package com.chinaweal.aiccs.org.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.chinaweal.aiccs.common.util.StringUtils;
import com.chinaweal.aiccs.config.UnifiedAuthConfig;
import com.chinaweal.aiccs.org.entity.dto.UnifiedAuthDTO;
import com.chinaweal.aiccs.org.service.IUnifiedAuthService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.UUID;

/**
 * 统一认证平台OAuth2服务实现
 *
 * @author lroyia
 * @since 2025/03/02
 */
@Slf4j
@Service
public class UnifiedAuthServiceImpl implements IUnifiedAuthService {

    @Autowired
    private UnifiedAuthConfig unifiedAuthConfig;

    @Autowired
    private RestTemplate restTemplate;

    @Override
    public String buildLoginUrl(String state) {
        if (StringUtils.isBlank(state)) {
            state = UUID.randomUUID().toString().replace("-", "");
        }

        StringBuilder url = new StringBuilder(unifiedAuthConfig.getAuthorizeUrl());
        url.append("?response_type=code");
        url.append("&client_id=").append(unifiedAuthConfig.getClientId());
        try {
            url.append("&redirect_uri=").append(URLEncoder.encode(unifiedAuthConfig.getRedirectUri(), "utf-8"));
        } catch (UnsupportedEncodingException e) {
            log.error("{}的UrlEncode失败", unifiedAuthConfig.getRedirectUri(), e);
        }
        url.append("&state=").append(state);

        log.info("构建统一认证平台登录URL: {}", url.toString());
        return url.toString();
    }

    @Override
    public UnifiedAuthDTO.TokenResponse getAccessToken(String code) {
        try {
            // 构建请求参数
            MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
            params.add("grant_type", "authorization_code");
            params.add("client_id", unifiedAuthConfig.getClientId());
            params.add("client_secret", unifiedAuthConfig.getClientSecret());
            params.add("code", code);
            params.add("redirect_uri", unifiedAuthConfig.getRedirectUri());

            // 设置请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

            HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(params, headers);

            // 发送POST请求
            ResponseEntity<String> responseEntity = restTemplate.postForEntity(
                    unifiedAuthConfig.getTokenUrl(),
                    requestEntity,
                    String.class
            );

            String responseBody = responseEntity.getBody();
            log.info("获取访问令牌响应: {}", responseBody);

            // 解析响应
            UnifiedAuthDTO.TokenResponse response = JSON.parseObject(responseBody, UnifiedAuthDTO.TokenResponse.class);

            if (StringUtils.isNotBlank(response.getError())) {
                log.error("获取访问令牌失败: {} - {}", response.getError(), response.getError_description());
            }

            return response;
        } catch (Exception e) {
            log.error("获取访问令牌异常", e);
            UnifiedAuthDTO.TokenResponse errorResponse = new UnifiedAuthDTO.TokenResponse();
            errorResponse.setError("server_error");
            errorResponse.setError_description("服务器内部错误: " + e.getMessage());
            return errorResponse;
        }
    }

    @Override
    public UnifiedAuthDTO.UserInfoResponse getUserInfo(String accessToken) {
        try {
            // 构建请求URL
            String url = String.format("%s?access_token=%s&client_id=%s",
                    unifiedAuthConfig.getUserinfoUrl(),
                    accessToken,
                    unifiedAuthConfig.getClientId());

            // 发送GET请求
            ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class);

            String responseBody = responseEntity.getBody();
            log.info("IMS获取用户信息响应: {}", responseBody);

            // 解析响应
            UnifiedAuthDTO.UserInfoResponse response = JSON.parseObject(responseBody, UnifiedAuthDTO.UserInfoResponse.class);

            // 统一处理返回数据
            if (StringUtils.isNotBlank(response.getError())) {
                log.error("获取用户信息失败: {} - {}", response.getError(), response.getError_description());
            } else if (StringUtils.isNotBlank(response.getCode()) && !"0".equals(response.getCode())) {
                log.error("获取用户信息失败: {} - {}", response.getCode(), response.getMessage());
                response.setError(response.getCode());
                response.setError_description(response.getMessage());
            }

            return response;
        } catch (Exception e) {
            log.error("获取用户信息异常", e);
            UnifiedAuthDTO.UserInfoResponse errorResponse = new UnifiedAuthDTO.UserInfoResponse();
            errorResponse.setError("server_error");
            errorResponse.setError_description("服务器内部错误: " + e.getMessage());
            return errorResponse;
        }
    }

    @Override
    public UnifiedAuthDTO.LogoutResponse logout(String accessToken) {
        try {
            // 构建请求参数
            MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
            params.add("access_token", accessToken);
            params.add("client_id", unifiedAuthConfig.getClientId());

            // 设置请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

            HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(params, headers);

            // 发送POST请求
            ResponseEntity<String> responseEntity = restTemplate.postForEntity(
                    unifiedAuthConfig.getLogoutUrl(),
                    requestEntity,
                    String.class
            );

            String responseBody = responseEntity.getBody();
            log.info("单点登出响应: {}", responseBody);

            // 解析响应
            UnifiedAuthDTO.LogoutResponse response = JSON.parseObject(responseBody, UnifiedAuthDTO.LogoutResponse.class);

            return response;
        } catch (Exception e) {
            log.error("单点登出异常", e);
            UnifiedAuthDTO.LogoutResponse errorResponse = new UnifiedAuthDTO.LogoutResponse();
            errorResponse.setCode("error");
            errorResponse.setMessage("服务器内部错误: " + e.getMessage());
            return errorResponse;
        }
    }

    @Override
    public boolean checkToken(String accessToken) {
        try {
            // 构建请求参数
            MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
            params.add("access_token", accessToken);
            params.add("client_id", unifiedAuthConfig.getClientId());

            // 设置请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);

            HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(params, headers);

            // 发送POST请求
            ResponseEntity<String> responseEntity = restTemplate.postForEntity(
                    unifiedAuthConfig.getCheckTokenUrl(),
                    requestEntity,
                    String.class
            );

            String responseBody = responseEntity.getBody();
            log.info("验证令牌响应: {}", responseBody);

            if (StringUtils.isBlank(responseBody)) {
                return false;
            }

            // 解析响应JSON
            JSONObject jsonObject = JSON.parseObject(responseBody);
            String code = jsonObject.getString("code");
            return "0".equals(code);

        } catch (Exception e) {
            log.error("验证令牌异常", e);
            return false;
        }
    }
}