package com.kingdee.eas.custom.integration.dingtalk.service.impl;

import com.kingdee.eas.custom.integration.base.config.AppConfig;
import com.kingdee.eas.custom.integration.base.exception.CommonErrorCodes;
import com.kingdee.eas.custom.integration.base.exception.IntegrationException;
import com.kingdee.eas.custom.integration.base.service.PlatformOAuthStrategy;
import com.kingdee.eas.custom.integration.base.util.SHRApiUtils;
import com.kingdee.eas.util.app.DbUtil;
import com.kingdee.jdbc.rowset.IRowSet;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.util.HashMap;
import java.util.Map;

/**
 * 钉钉 OAuth 策略实现
 */
@Component
public class DingtalkOAuthStrategy implements PlatformOAuthStrategy {

    private static final Logger log = LoggerFactory.getLogger(DingtalkOAuthStrategy.class);

    private static final String AUTH_URL = "https://login.dingtalk.com/oauth2/auth";
    private static final String TOKEN_URL = "https://api.dingtalk.com/v1.0/oauth2/userAccessToken";
    private static final String USER_INFO_URL = "https://api.dingtalk.com/v1.0/contact/users/me";

    private final RestTemplate restTemplate;

    public DingtalkOAuthStrategy(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    /**
     * 获取平台名称
     *
     * @return
     */
    @Override
    public String platform() {
        return "dingtalk";
    }

    /**
     * 构建授权 URL
     *
     * @param config
     * @param state
     * @return
     */
    @Override
    public String buildAuthUrl(AppConfig config, String state) {
        return UriComponentsBuilder.fromHttpUrl(AUTH_URL)
                .queryParam("response_type", "code")
                .queryParam("client_id", config.getAppId())
                .queryParam("redirect_uri", config.getCallbackUrl())
                .queryParam("scope", "openid")
                .queryParam("state", state)
                .queryParam("prompt", "consent")
                .build()
                .toUriString();
    }

    /**
     * 根据授权码获取用户ID
     *
     * @param config
     * @param code
     * @return
     */
    @Override
    @SuppressWarnings("unchecked")
    public String getUserId(AppConfig config, String code) {
        Map<String, String> body = new HashMap<>();
        body.put("clientId", config.getAppId());
        body.put("clientSecret", config.getAppSecret());
        body.put("code", code);
        body.put("grantType", "authorization_code");

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        ResponseEntity<Map> tokenResp = restTemplate.postForEntity(
                TOKEN_URL, new HttpEntity<>(body, headers), Map.class);

        if (!tokenResp.getStatusCode().is2xxSuccessful() || tokenResp.getBody() == null) {
            throw new RuntimeException("钉钉换取 accessToken 失败");
        }

        String accessToken = (String) tokenResp.getBody().get("accessToken");

        HttpHeaders authHeader = new HttpHeaders();
        authHeader.set("x-acs-dingtalk-access-token", accessToken);

        ResponseEntity<Map> userResp = restTemplate.exchange(
                USER_INFO_URL,
                HttpMethod.GET,
                new HttpEntity<>(authHeader),
                Map.class);

        Map respBody = userResp.getBody();
        if (!userResp.getStatusCode().is2xxSuccessful() || respBody == null) {
            throw new RuntimeException("钉钉获取用户信息失败");
        }

        String mobile = (String) respBody.get("mobile");
        if (!respBody.containsKey("mobile")) {
            throw new IntegrationException(CommonErrorCodes.SYSTEM_ERROR, "钉钉应用【" + config.getAppId() + "】没有获取【个人手机号信息】权限，请联系管理员处理");
        }
        String dingName = (String) respBody.get("nick");
        if (StringUtils.isBlank(mobile)) {
            throw new IntegrationException(CommonErrorCodes.SYSTEM_ERROR, "钉钉账号[" + dingName + "]没有维护手机号码");
        }
        String queryUserId = "select fusernumber from T_PM_EASDTUSERMAP where fcell =?";
        String userNumber = null;
        try {
            IRowSet iRowSet = DbUtil.executeQuery(SHRApiUtils.getContext(), queryUserId, new Object[]{mobile});
            while (iRowSet.next()) {
                userNumber = iRowSet.getString("fusernumber");
            }
        } catch (Exception e) {
            throw new IntegrationException(CommonErrorCodes.SYSTEM_ERROR, "sHR系统匹配到钉钉用户手机号[" + mobile + "]失败", e);
        }
        if (StringUtils.isBlank(userNumber)) {
            throw new IntegrationException(CommonErrorCodes.SYSTEM_ERROR, "sHR系统未匹配到钉钉用户手机号: " + mobile);
        }
        return userNumber;
    }
}
