package com.example.backend.service;

import com.aliyun.dingtalkoauth2_1_0.models.*;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiMediaUploadRequest;
import com.dingtalk.api.request.OapiMessageCorpconversationAsyncsendV2Request;
import com.dingtalk.api.request.OapiV2UserGetuserinfoRequest;
import com.dingtalk.api.response.OapiMediaUploadResponse;
import com.dingtalk.api.response.OapiMessageCorpconversationAsyncsendV2Response;
import com.dingtalk.api.response.OapiV2UserGetuserinfoResponse;
import com.taobao.api.ApiException;
import com.taobao.api.FileItem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.example.backend.dto.DingtalkUserInfo;
import com.example.backend.exception.BizException;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.ArrayList;
import java.util.List;

/**
 *
 */
@Service
public class DingtalkService {
    private static final Logger log = LoggerFactory.getLogger(DingtalkService.class);
    @Value("${dingtalk.clientId}")
    private String clientId;
    @Value("${dingtalk.clientSecret}")
    private String clientSecret;
    @Value("${dingtalk.filepath}")
    private String filepath;
    @Value("${dingtalk.agentId}")
    private long agentId;
    @Autowired
    private AccessTokenManager accessTokenManager;

    private com.aliyun.teaopenapi.models.Config getDingTalkConfig() {
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
        config.protocol = "https";
        config.regionId = "central";
        return config;
    }

    /**
     * 获取access_token
     * @return
     */
    private String getAccessToken() {
        if (clientId == null || clientSecret == null) {
            throw new BizException("钉钉配置缺失：clientId 或 clientSecret 为空");
        }
        return accessTokenManager.getAccessToken(clientId, clientSecret, (appKey, appSecret) -> {
            try {
                com.aliyun.dingtalkoauth2_1_0.Client client = new com.aliyun.dingtalkoauth2_1_0.Client(getDingTalkConfig());
                com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest getAccessTokenRequest = new com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest()
                        .setAppKey(appKey)
                        .setAppSecret(appSecret);
                GetAccessTokenResponse resp = client.getAccessToken(getAccessTokenRequest);
                if (resp != null && resp.body != null && resp.body.accessToken != null) {
                    return resp.body.accessToken;
                } else {
                    throw new BizException("获取钉钉访问令牌失败：响应为空");
                }
            } catch (Exception err) {
                log.error("获取钉钉访问令牌失败", err);
                throw new BizException("获取钉钉访问令牌失败: " + err.getMessage());
            }
        });
    }

    /**
     * 根据授权码和组织ID获取用户信息，并返回给前端
     * @param code
     * @param corpId
     * @return
     */
    public DingtalkUserInfo getUserInfo(String code, String corpId) {
        try {
            log.info("开始获取钉钉用户信息，code={}, corpId={}", code, corpId);
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/getuserinfo");
            OapiV2UserGetuserinfoRequest req = new OapiV2UserGetuserinfoRequest();
            req.setCode(code);
            String accessToken = getAccessToken();
            OapiV2UserGetuserinfoResponse rsp = client.execute(req, accessToken);
            if (!rsp.isSuccess()) {
                log.error("获取钉钉用户信息失败，errcode={}, errmsg={}", rsp.getErrcode(), rsp.getErrmsg());
                throw new BizException(rsp.getErrmsg());
            }
            var result = rsp.getResult();
            DingtalkUserInfo userInfo = new DingtalkUserInfo();
            userInfo.setName(result.getName());
            userInfo.setUserid(result.getUserid());
            userInfo.setUnionid(result.getUnionid());
            userInfo.setSys(result.getSys());
            userInfo.setSysLevel(result.getSysLevel() != null ? result.getSysLevel().intValue() : 0);
            log.info("获取钉钉用户信息成功，userid={}, name={}", userInfo.getUserid(), userInfo.getName());
            return userInfo;
        } catch (ApiException e) {
            log.error("获取钉钉用户信息异常", e);
            throw new BizException("获取用户信息失败: " + e.getMessage());
        }
    }

    /**
     * 通过传递的文件数据，上传附件
     * @return
     */
    public boolean commitFile(String userId) {
        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/media/upload");
            OapiMediaUploadRequest req = new OapiMediaUploadRequest();
            req.setType("image");
            // 要上传的媒体文件
            FileItem item = new FileItem(filepath);
            req.setMedia(item);
            OapiMediaUploadResponse rsp = client.execute(req, getAccessToken());
            String accessToken = getAccessToken();
            // 工作通知发送方式
            sendMes(accessToken,rsp.getMediaId(),userId);
            // 通过互动卡片方式发送
        /*    actionSenMes(accessToken,userId);*/
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
       return true;
    }

    /**
     * 图片方式发送
     * @param accessToken
     * @return
     */
    public void sendMes(String accessToken,String mediaId,String userId) {
        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2");
            OapiMessageCorpconversationAsyncsendV2Request request = new OapiMessageCorpconversationAsyncsendV2Request();
            request.setAgentId(agentId);
            request.setUseridList(userId);
            request.setToAllUser(false);

            // 图片
            OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
            msg.setMsgtype("image");
            OapiMessageCorpconversationAsyncsendV2Request.Image image = new OapiMessageCorpconversationAsyncsendV2Request.Image();
            image.setMediaId(mediaId);
            msg.setImage(image);
            request.setMsg(msg);
            OapiMessageCorpconversationAsyncsendV2Response rsp = client.execute(request, accessToken);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 互动卡片方式发送，如果需要可再上方进行替换
     * @return
     */
    public boolean actionSenMes(String accessToken,String userId){
        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2");
            OapiMessageCorpconversationAsyncsendV2Request request = new OapiMessageCorpconversationAsyncsendV2Request();
            request.setAgentId(agentId);
            request.setUseridList(userId);
            request.setToAllUser(false);
            OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
            msg.setMsgtype("action_card");
            OapiMessageCorpconversationAsyncsendV2Request.ActionCard actionCard = new OapiMessageCorpconversationAsyncsendV2Request.ActionCard();

            List<OapiMessageCorpconversationAsyncsendV2Request.BtnJsonList> btnJsonList =  new ArrayList<OapiMessageCorpconversationAsyncsendV2Request.BtnJsonList>();
            OapiMessageCorpconversationAsyncsendV2Request.BtnJsonList btnJson = new OapiMessageCorpconversationAsyncsendV2Request.BtnJsonList();
            btnJson.setTitle("消息通知");
            btnJson.setActionUrl("https://img0.baidu.com/it/u=2684172837,4233049252&fm=253&app=138&f=JPEG?w=608&h=608");
            btnJsonList.add(btnJson);
            actionCard.setBtnJsonList(btnJsonList);
            actionCard.setBtnOrientation("1");
            actionCard.setTitle("媒体文件上传通知");
            actionCard.setMarkdown("### 有新文件上传~");

            actionCard.setSingleUrl("https://www.dingtalk.com");
            actionCard.setSingleTitle("文件上传");
            msg.setActionCard(actionCard);
            request.setMsg(msg);
            OapiMessageCorpconversationAsyncsendV2Response rsp = client.execute(request, accessToken);
            System.out.println(rsp.getBody());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return true;
    }
} 