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

import com.kingdee.bos.Context;
import com.kingdee.eas.basedata.person.IPerson;
import com.kingdee.eas.basedata.person.PersonCollection;
import com.kingdee.eas.basedata.person.PersonFactory;
import com.kingdee.eas.custom.integration.base.config.AppConfig;
import com.kingdee.eas.custom.integration.base.service.PlatformOAuthStrategy;
import com.kingdee.eas.custom.integration.base.util.SHRApiUtils;
import com.kingdee.eas.custom.integration.feishu.exception.FeishuErrorCodes;
import com.kingdee.eas.custom.integration.feishu.exception.FeishuIntegrationException;
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.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 飞书 OAuth 策略实现
 */
@Component
public class FeishuOAuthStrategy implements PlatformOAuthStrategy {

    private static final Logger log = LoggerFactory.getLogger(FeishuOAuthStrategy.class);
    // 飞书 OAuth 认证 URL
    private static final String AUTH_URL = "https://accounts.feishu.cn/open-apis/authen/v1/authorize";
    // 飞书 OAuth 获取 token URL
    private static final String TOKEN_URL = "https://open.feishu.cn/open-apis/authen/v1/access_token";
    // 获取用户信息
    public static final String GET_USERINFO_URL = "https://open.feishu.cn/open-apis/authen/v1/user_info";

    private final RestTemplate restTemplate;

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

    /**
     * 平台标识
     */
    @Override
    public String platform() {
        return "feishu";
    }

    /**
     * 构建授权 URL
     */
    @Override
    public String buildAuthUrl(AppConfig config, String state) {
        return UriComponentsBuilder.fromHttpUrl(AUTH_URL)
                .queryParam("app_id", config.getAppId())
                .queryParam("redirect_uri", config.getCallbackUrl())
                .queryParam("state", state)
                .build()
                .toUriString();
    }

    /**
     * 根据授权码获取用户 ID
     */
    @Override
    @SuppressWarnings("unchecked")
    public String getUserId(AppConfig config, String code) {
        //获取token
        Map<String, String> body = new HashMap<>();
        body.put("app_id", config.getAppId());
        body.put("app_secret", config.getAppSecret());
        body.put("grant_type", "authorization_code");
        body.put("code", 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 失败");
        }
        log.info("飞书获取 accessToken 响应: {}", tokenResp.getBody());
        Map<String, Object> respBody = tokenResp.getBody();
        if (Integer.valueOf(0).equals(respBody.get("code"))) {
            Map<String, Object> data = (Map<String, Object>) respBody.get("data");
            String accessToken = (String) data.get("access_token");
            //请求用户信息
            return getUserInfo(config, accessToken);
        }

        throw new RuntimeException("飞书换取 accessToken 业务失败, msg=" + respBody.get("msg"));
    }


    /**
     * 使用访问令牌获取用户信息
     *
     * @param accessToken 访问令牌
     * @return 用户信息响应
     * @throws IOException IO异常
     */
    public String getUserInfo(AppConfig config, String accessToken) {
        log.info("获取飞书用户信息");
        try {
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.set("Authorization", "Bearer " + accessToken);
            HttpEntity<String> entity = new HttpEntity<String>(headers);

            ResponseEntity<Map> respBody = restTemplate.exchange(
                    GET_USERINFO_URL,
                    HttpMethod.GET,
                    entity,
                    Map.class
            );

            if (!respBody.getStatusCode().is2xxSuccessful() || respBody.getBody() == null) {
                throw new RuntimeException("飞书获取用户信息失败");
            }
            log.info("飞书获取用户信息响应: {}", respBody.getBody());

            Map<String, Object> userInfo = (Map<String, Object>) respBody.getBody().get("data");
            if (!userInfo.containsKey("user_id")) {
                throw new FeishuIntegrationException(FeishuErrorCodes.APP_PERMISSION_ABSENCE, "当前飞书应用没有获取飞书用户ID权限，应用id[" + config.getAppId() + "]，请联系管理员分配");
            }
            //工号
            //Object employeeNo = userInfo.get("employee_no");
            //用户id
            Object user_id = userInfo.get("user_id");
            if (user_id == null || StringUtils.isBlank(user_id.toString())) {
                throw new FeishuIntegrationException(FeishuErrorCodes.EMPLOYEE_NUMBER_EMPTY, "飞书用户[" + userInfo.get("name") + "]的用户ID为空，，请联系管理员");
            }
            //用飞书用户ID查询sHR员工信息
            Context ctx = SHRApiUtils.getContext();
            IPerson iPerson = PersonFactory.getLocalInstance(ctx);
            PersonCollection personCol = iPerson.getPersonCollection("select number where idmusercode='" + user_id + "'");
            if (personCol.isEmpty()) {
                throw new FeishuIntegrationException(FeishuErrorCodes.GET_USERINFO_FAILED, "sHR系统不存在属性IDM_USER_CODE为 " + user_id + " 的员工");
            } else if (personCol.size() > 1) {
                throw new FeishuIntegrationException(FeishuErrorCodes.GET_USERINFO_FAILED, "sHR系统存在多个属性IDM_USER_CODE为 " + user_id + " 的员工");
            }
            return personCol.get(0).getNumber();
        } catch (Exception e) {
            log.error("获取用户信息异常: {}", e.getMessage(), e);
            throw new FeishuIntegrationException(FeishuErrorCodes.GET_USERINFO_FAILED, "获取用户信息失败: " + e.getMessage(), e);
        }
    }

}
