package com.citygis.web.service.impl;

import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.citygis.web.service.SingleLoginService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author: zyl
 * @CreateTime: 2025-02-05
 * @Description: 单点登录
 * @Version: 1.0
 */
@Service
@Slf4j
public class SingleLoginServiceImpl implements SingleLoginService {

    @Value("${singleLogin.ssoRet}")
    private String ssoRet;

    @Value("${singleLogin.clientId}")
    private String clientId;

    @Value("${singleLogin.url}")
    private String url;

    @Value("${singleLogin.tokenUrl}")
    private String tokenUrl;

    @Value("${singleLogin.userInfo}")
    private String userInfo;

    @Override
    public void singleLogin(HttpServletRequest request, HttpServletResponse response) throws IOException {

        //拼接url，ssoRet为派拉请求登陆认证地址，redirect_uri为跳转应用地址
        String returnURL = ssoRet +
                "client_id=" + clientId + "&" +
                "response_type=code" +
                "&redirect_uri=" + URLEncoder.encode(url, StandardCharsets.UTF_8.toString()) +
                "&oauth_timestamp=" + System.currentTimeMillis();

        log.info("成功------>" + returnURL);

        response.sendRedirect(returnURL);
    }

    @Override
    public String getUser(String code) throws UnsupportedEncodingException {
        String accessToken = getAccessToken(code);
        String user = getUserAccountInfo(accessToken);
        return "";
    }


    /**
     * 获取token
     * @param code
     * @return
     * @throws UnsupportedEncodingException
     */
    public String getAccessToken(String code) throws UnsupportedEncodingException {
        Map<String, String> params = new HashMap<>();
        params.put("grant_type", "authorization_code");
        params.put("oauth_timestamp", String.valueOf(System.currentTimeMillis()));
        params.put("client_id", clientId);
        params.put("client_secret", ssoRet);
        params.put("code", code);
        params.put("redirect_uri", URLEncoder.encode(url, StandardCharsets.UTF_8.toString()));

        // 拼接请求参数
        String queryString = params.entrySet().stream()
                .map(entry -> entry.getKey() + "=" + entry.getValue())
                .collect(Collectors.joining("&"));

        String fullUrl = tokenUrl + "/esc-sso/oauth2.0/accessToken?" + queryString;

        // 发送请求并获取响应
        HttpResponse response = HttpUtil.createPost(fullUrl).execute();

        // 检查HTTP状态码
        if (response.getStatus() != 200) {
            throw new RuntimeException("获取token失败，状态码: " + response.getStatus() + "，响应: " + response.body());
        }

        // 解析JSON响应
        JSONObject jsonResponse = JSONUtil.parseObj(response.body());
        String accessToken = jsonResponse.getStr("access_token");

        if (accessToken == null || accessToken.isEmpty()) {
            throw new RuntimeException("响应中未找到access_token，完整响应: " + jsonResponse);
        }

        return accessToken;
    }

    /**
     * 获取用户
     * @param accessToken
     * @return
     */
    public String getUserAccountInfo(String accessToken) {
        Map<String, String> params = new HashMap<>();
        params.put("access_token", accessToken);

        // 使用Stream API构建查询参数
        String queryString = params.entrySet().stream()
                .map(entry -> entry.getKey() + "=" + entry.getValue())
                .collect(Collectors.joining("&"));

        String fullUrl = userInfo + "/esc-sso/oauth2.0/profile?" + queryString;

        // 发送HTTP请求
        HttpResponse response = HttpUtil.createGet(fullUrl).execute();

        // 校验HTTP状态码
        if (response.getStatus() != 200) {
            throw new RuntimeException("获取用户信息失败，状态码: " + response.getStatus()
                    + "，响应: " + response.body());
        }

        // 解析JSON响应
        JSONObject jsonResponse = JSONUtil.parseObj(response.body());

        // 获取嵌套的attributes对象
        JSONObject attributes = jsonResponse.getJSONObject("attributes");
        if (attributes == null) {
            throw new RuntimeException("响应中缺少attributes字段，完整响应: " + jsonResponse);
        }

        // 提取目标字段
        String accountOn = attributes.getStr("account_on");
        if (accountOn == null || accountOn.isEmpty()) {
            throw new RuntimeException("account_on字段不存在或为空，attributes内容: " + attributes);
        }

        return accountOn;
    }
}
