package com.fjhx.dingding.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dingtalk.oapi.lib.aes.DingTalkEncryptor;
import com.fjhx.dingding.constant.Constant;
import com.fjhx.dingding.entity.dto.GetUserTokenDto;
import com.fjhx.dingding.service.DingService;
import com.ruoyi.common.annotation.NonInterception;
import com.ruoyi.common.annotation.TenantIgnore;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@Slf4j
@RestController
@RequestMapping("/open")
public class DingController {

    @Autowired
    private DingService dingService;

    /**
     * 创建应用，验证回调URL创建有效事件（第一次保存回调URL之前）
     */
    private static final String EVENT_CHECK_CREATE_SUITE_URL = "check_create_suite_url";

    /**
     * 创建应用，验证回调URL变更有效事件（第一次保存回调URL之后）
     */
    private static final String EVENT_CHECK_UPDATE_SUITE_URL = "check_update_suite_url";

    /**
     * 推送事件
     */
    private static final String SYNC_HTTP_PUSH_HIGH = "SYNC_HTTP_PUSH_HIGH";

    /**
     * https://open.dingtalk.com/document/isvapp/configure-synchttp-push
     * https://open.dingtalk.com/document/isvapp/authorization-event-1
     */
    @TenantIgnore
    @NonInterception
    @PostMapping(value = "/dingCallback")
    public Object dingCallback(
            @RequestParam(value = "signature") String signature,
            @RequestParam(value = "timestamp") Long timestamp,
            @RequestParam(value = "nonce") String nonce,
            @RequestBody(required = false) JSONObject body) {

        String params = "signature:" + signature + " timestamp:" + timestamp + " nonce:" + nonce + " body:" + body;

        try {
            DingTalkEncryptor dingTalkEncryptor = new DingTalkEncryptor(
                    Constant.TOKEN, Constant.ENCODING_AES_KEY, Constant.SUITE_KEY);

            // 从post请求的body中获取回调信息的加密数据进行解密处理
            String encrypt = body.getString("encrypt");
            String plainText = dingTalkEncryptor.getDecryptMsg(signature, timestamp.toString(), nonce, encrypt);
            JSONObject callBackContent = JSON.parseObject(plainText);

            // 根据回调事件类型做不同的业务处理
            String eventType = callBackContent.getString("EventType");
            switch (eventType) {

                case EVENT_CHECK_CREATE_SUITE_URL:
                    log.info("验证新创建的回调URL有效性: " + plainText);
                    break;

                case EVENT_CHECK_UPDATE_SUITE_URL:
                    log.info("验证更新回调URL有效性: " + plainText);
                    break;

                case SYNC_HTTP_PUSH_HIGH:
                    log.info("推送回调：" + plainText);
                    dingService.pushHigh(callBackContent);
                    break;
                default:
                    // 其他类型事件处理
                    log.info("其他回调：" + plainText);
                    // dingService.saveCallback(callBackContent);
            }

            // 返回success的加密信息表示回调处理成功
            return dingTalkEncryptor.getEncryptedMap("success", timestamp, nonce);
        } catch (Exception e) {
            // 失败的情况，应用的开发者应该通过告警感知，并干预修复
            log.error("钉钉回调异常" + params, e);
            return "fail";
        }

    }

    @TenantIgnore
    @PostMapping(value = "/dingApi/getUserToken")
    public String getUserToken(@RequestBody GetUserTokenDto dto) {
        return dingService.getUserToken(dto);
    }

}