package com.mortals.xhx.module.attendance.dingmsg.api;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.dingtalkworkflow_1_0.models.GetProcessInstanceResponseBody;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiGettokenRequest;
import com.dingtalk.api.response.OapiGettokenResponse;
import com.mortals.framework.annotation.UnAuth;
import com.mortals.framework.common.Rest;
import com.mortals.framework.exception.AppException;
import com.mortals.xhx.common.pdu.ApiRespPdu;
import com.mortals.xhx.module.attendance.dingmsg.DingCallbackCrypto;
import com.mortals.xhx.module.attendance.dingmsg.dingmsgreq.DingResponsMeassageReq;
import com.mortals.xhx.module.attendance.dingmsg.dingmsgreq.EncryptReq;
import com.mortals.xhx.module.attendance.model.AttendanceLeaveRecordEntity;
import com.mortals.xhx.module.attendance.model.AttendanceLeaveRecordQuery;
import com.mortals.xhx.module.attendance.service.AttendanceLeaveRecordService;
import com.mortals.xhx.module.dingding.personal.service.IDingPersonService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.logging.Log;
import org.apache.poi.ss.formula.functions.T;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

import static cn.hutool.core.date.DatePattern.*;

/**
 *
 * 接收钉钉的审批消息推送
 *
 * @author ZYW
 * @date 2023-07-18 9:52
 */
@RestController
@Slf4j
public class DingMessageController {

    @Autowired
    private IDingPersonService dingPersonService;
    @Autowired
    private AttendanceLeaveRecordService attendanceLeaveRecordService;


    /**
     * appKey
     */
    @Value("${dingtalk.AppKey:''}")
    protected String appKey;
    /**
     * aesKey
     */
    @Value("${dingtalk.AesKey:''}")
    protected String aesKey;

    /**
     * 订阅消息token
     */
    @Value("${dingtalk.token:''}")
    protected String token;

    /**
     * 接收钉钉消息
     *
     * @return
     */
    @PostMapping("/dingtalk/getOaMeassge")
    @UnAuth
    public Map<String, String> getOaMessage(@RequestParam(value = "msg_signature", required = false) String msg_signature,
                                            @RequestParam(value = "timestamp", required = false) String timeStamp,
                                            @RequestParam(value = "nonce", required = false) String nonce,
                                            @RequestBody(required = false) JSONObject json)  {
//        log.info("钉钉推送参数：" + msg_signature+"---"+timeStamp+"---"+nonce+"---"+json.toJSONString() );
        try {
            //  从http请求中获取加解密参数
            DingCallbackCrypto callbackCrypto = new DingCallbackCrypto(token, aesKey, appKey);
            String encryptMsg = json.getString("encrypt");
            String decryptMsg = callbackCrypto.getDecryptMsg(msg_signature, timeStamp, nonce, encryptMsg);

            // 反序列化回调事件json数据
            JSONObject eventJson = JSON.parseObject(decryptMsg);
            String eventType = eventJson.getString("EventType");
            String processInstanceId = eventJson.getString("processInstanceId");

            // 根据EventType分类处理
            if("bpms_instance_change".equals(eventType)){  //请假等需要审批的消息
                // 处理审批实例始末（审批任务开始、结束）
                // 存入数据库
//                log.info("发生了：" + eventType + "事件" );
                if(processInstanceId != null){
                    Rest<GetProcessInstanceResponseBody.GetProcessInstanceResponseBodyResult> rest = dingPersonService.getOaRecordsById(processInstanceId);
                    if(rest.getCode() == Rest.SUCCESS){
                        GetProcessInstanceResponseBody.GetProcessInstanceResponseBodyResult result = rest.getData();
                        log.info("审批详情："+JSONObject.toJSONString(result) );
                        AttendanceLeaveRecordEntity leaveRecordEntity = new AttendanceLeaveRecordEntity();
                        leaveRecordEntity.initAttrValue();
                        leaveRecordEntity.setRemark(processInstanceId);   //将钉钉的事物id作为备注填入数据库
                        leaveRecordEntity.setLeavePersonId(Long.parseLong(result.getOriginatorUserId()));
                        leaveRecordEntity.setLeavePerson(result.getTitle().substring(0,result.getTitle().indexOf("提交")));
                        leaveRecordEntity.setDeptId(Long.parseLong(result.getOriginatorDeptId()));
                        leaveRecordEntity.setDeptName(result.getOriginatorDeptName());



                        if(result.getTasks().size() >0 ){
                            Date startTime = dateFormat(result.getTasks().get(0).getCreateTime());
                            Date endTime = dateFormat(result.getTasks().get(0).getFinishTime());
                            leaveRecordEntity.setStartTime(startTime);
                            leaveRecordEntity.setEndTime(endTime);
                            leaveRecordEntity.setDuration((int) ((endTime.getTime() - startTime.getTime())/1000));
                        }

                        if(result.getFormComponentValues().size() > 0 ){
                            JSONArray jsonArray = JSONArray.parseArray(result.getFormComponentValues().get(0).getValue());
                            if(jsonArray.size() > 0){
                                Date startTime1 = dateFormat(jsonArray.get(0).toString());
                                leaveRecordEntity.setStartTime(startTime1);
                            }
                            if(jsonArray.size() > 1){
                                Date endTime1 = dateFormat(jsonArray.get(1).toString());
                                leaveRecordEntity.setEndTime(endTime1);
                            }
                            if(jsonArray.size() > 2){
                                leaveRecordEntity.setDuration((int) (Float.parseFloat(jsonArray.get(2).toString())*60*60));
                            }
                            if(jsonArray.size() > 4){
                                switch (jsonArray.get(4).toString()){
                                    case "调休":
                                        leaveRecordEntity.setLeaveType(2);
                                        break;
                                    case "病假":
                                        leaveRecordEntity.setLeaveType(3);
                                        break;
                                    case "年假":
                                        leaveRecordEntity.setLeaveType(4);
                                        break;
                                    case "产假":
                                        leaveRecordEntity.setLeaveType(5);
                                        break;
                                    case "陪产假":
                                        leaveRecordEntity.setLeaveType(6);
                                        break;
                                    case "婚假":
                                        leaveRecordEntity.setLeaveType(7);
                                        break;
                                    case "例假":
                                        leaveRecordEntity.setLeaveType(8);
                                        break;
                                    case "哺乳假":
                                        leaveRecordEntity.setLeaveType(9);
                                        break;
                                    case "丧假":
                                        leaveRecordEntity.setLeaveType(10);
                                        break;
                                    case "回单位":
                                        leaveRecordEntity.setLeaveType(11);
                                        break;
                                    case "因公请假":
                                        leaveRecordEntity.setLeaveType(12);
                                        break;
                                    case "外出勘验":
                                        leaveRecordEntity.setLeaveType(13);
                                        break;
                                    case "值班补班":
                                        leaveRecordEntity.setLeaveType(14);
                                        break;
                                    case "体检":
                                        leaveRecordEntity.setLeaveType(15);
                                        break;
                                    case "隔离":
                                        leaveRecordEntity.setLeaveType(16);
                                        break;
                                    case "因公外出":
                                        leaveRecordEntity.setLeaveType(17);
                                        break;
                                    case "公休":
                                        leaveRecordEntity.setLeaveType(18);
                                        break;
                                    case "育儿假":
                                        leaveRecordEntity.setLeaveType(19);
                                        break;
                                    case "调回单位":
                                        leaveRecordEntity.setLeaveType(20);
                                        break;
                                    case "探亲假":
                                        leaveRecordEntity.setLeaveType(21);
                                        break;
                                    default:
                                        leaveRecordEntity.setLeaveType(1);  //默认事假
                                        break;

                                }

                            }

                        }

                        if(result.getStatus().equals("NEW") || result.getStatus().equals("RUNNING")){
                            leaveRecordEntity.setProcessStatus(1);
                        }else if(result.getStatus().equals("COMPLETED") || result.getStatus().equals("CANCELED") || result.getStatus().equals("TERMINATED")){
                            leaveRecordEntity.setProcessStatus(2);
                        }

                        if(result.getResult().equals("AGREE")){
                            leaveRecordEntity.setAuditResult(1);
                        }else {
                            leaveRecordEntity.setAuditResult(2);
                        }

                        leaveRecordEntity.setAuditDesc(result.getOperationRecords().get(0).getRemark());

                        AttendanceLeaveRecordEntity recordEntity = attendanceLeaveRecordService.selectOne(new AttendanceLeaveRecordQuery().remark(processInstanceId));
                        if(ObjectUtils.isEmpty(recordEntity)){

                            leaveRecordEntity.setCreateTime(new Date());
                            leaveRecordEntity.setCreateUserId(1L);
                            attendanceLeaveRecordService.save(leaveRecordEntity);
                        }else{
                             leaveRecordEntity.setId(recordEntity.getId());

                             leaveRecordEntity.setUpdateUserId(1L);
                             leaveRecordEntity.setUpdateTime(new Date());

                             attendanceLeaveRecordService.update(leaveRecordEntity);
                        }


                    }

                }
            }
            else {
                // 添加其他已注册的
                log.info("发生了：" + eventType + "事件");
            }

            // 5. 返回success的加密数据
            Map<String, String> successMap = callbackCrypto.getEncryptedMap("success");
            return successMap;

        } catch (DingCallbackCrypto.DingTalkEncryptException e) {
            e.printStackTrace();
        }
        return null;

    }

    private Date dateFormat(String dateString){
        SimpleDateFormat dateFormat_ = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'");

        Date t;
        try {
            t = dateFormat_ .parse(dateString);
            return t;
        } catch (ParseException e) {
            return new Date(System.currentTimeMillis());
        }
    }

}
