package com.qmth.teachcloud.cas.mq.gdpu.api;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.qmth.boot.api.annotation.Aac;
import com.qmth.teachcloud.cas.mq.gdpu.bean.AESEncryptUtils;
import com.qmth.teachcloud.cas.mq.gdpu.bean.ProcessInfoDTO;
import com.qmth.teachcloud.cas.mq.gdpu.bean.RemarkInfoDTO;
import com.qmth.teachcloud.cas.mq.gdpu.bean.TodoInfoDTO;
import com.qmth.teachcloud.cas.mq.gdpu.cache.FlowMqCacheUtil;
import com.qmth.teachcloud.exchange.common.bean.dto.flow.DoneTaskDto;
import com.qmth.teachcloud.exchange.common.bean.dto.flow.StandardFlowWorkMsg;
import com.qmth.teachcloud.exchange.common.bean.dto.flow.ToDoTaskDto;
import com.qmth.teachcloud.exchange.common.bean.dto.syssetting.SimpleObject;
import com.qmth.teachcloud.exchange.common.contant.SystemConstant;
import com.qmth.teachcloud.exchange.common.entity.BasicSchool;
import com.qmth.teachcloud.exchange.common.enums.ExceptionResultEnum;
import com.qmth.teachcloud.exchange.common.service.CommonCacheService;
import com.qmth.teachcloud.exchange.common.util.ResultUtil;
import io.swagger.annotations.*;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;

@Api(tags = "广东药科大学服务中台controller")
@RestController
//@RequestMapping(SystemConstant.PREFIX_URL_GDPU_GET_BACK_LOG)
@Aac(auth = false)
@Validated
public class GdpuMqController {
    private final static Logger log = LoggerFactory.getLogger(GdpuMqController.class);

    @Resource
    CommonCacheService commonCacheService;

    @RequestMapping(value = SystemConstant.PREFIX_URL_GDPU_GET_BACK_LOG, method = RequestMethod.POST)
    @ApiOperation(value = "获取流程事项信息")
    @ApiResponses({@ApiResponse(code = 200, message = "常规信息", response = ResultUtil.class)})
    public JSONObject getbacklog(@ApiParam(value = "appid", required = true) @RequestHeader String appid,
                                 @ApiParam(value = "签名串", required = true) @RequestHeader String secret,
                                 @ApiParam(value = "流程id", required = true) @RequestHeader String orunId) {
        log.info("getbacklog appid:{},secret:{},orunId:{}", appid, secret, orunId);
        if (Objects.isNull(appid) || Objects.equals(appid.trim(), "")) {
            throw ExceptionResultEnum.PARAMS_ERROR.exception("appid为空");
        }
        if (Objects.isNull(secret) || Objects.equals(secret.trim(), "")) {
            throw ExceptionResultEnum.PARAMS_ERROR.exception("secret为空");
        }
        if (Objects.isNull(orunId) || Objects.equals(orunId.trim(), "")) {
            throw ExceptionResultEnum.PARAMS_ERROR.exception("流水号为空");
        }
        Long flowId = Long.parseLong(orunId);
        Long schoolId = Long.parseLong((String) FlowMqCacheUtil.getSchoolId(flowId));
        Map<String, SimpleObject> mapSetting = commonCacheService.getSysSetting(schoolId);

        BasicSchool basicSchool = commonCacheService.schoolCache(schoolId);
        Objects.requireNonNull(basicSchool, "学校信息不存在");

        String appId = null, appSecret = null, sysAppId = null;
        if (!CollectionUtils.isEmpty(mapSetting)) {
            SimpleObject simpleObjectAppId = mapSetting.get(SystemConstant.GDPU_APP_ID_PARAM);
            Objects.requireNonNull(simpleObjectAppId, "未配置学校appId");

            SimpleObject simpleObjectAppSecret = mapSetting.get(SystemConstant.GDPU_APP_SECRET_PARAM);
            Objects.requireNonNull(simpleObjectAppSecret, "未配置学校secret");

            SimpleObject simpleObjectSysAppId = mapSetting.get(SystemConstant.GDPU_SYS_APP_ID_PARAM);
            Objects.requireNonNull(simpleObjectSysAppId, "未配置学校sysAppid");

            appId = simpleObjectAppId.getValue();
            appSecret = simpleObjectAppSecret.getValue();
            sysAppId = simpleObjectSysAppId.getValue();
        }
        //校验secret
        String dateStr = new SimpleDateFormat(SystemConstant.DEFAULT_DATE).format(new Date());
        String encryptedvalue = DigestUtils.md5Hex(appId + appSecret + dateStr).toUpperCase();
        JSONObject result = new JSONObject();

        JSONObject content = new JSONObject();
        if (!encryptedvalue.equals(secret)) {
            content.put("code", "501");
            content.put("message", "加密串校验失败!");
            result.put("content", content);
            return result;
        }
        JSONObject data = new JSONObject();
        ToDoTaskDto toDoTaskDto = FlowMqCacheUtil.getToDoTask(flowId);
        JSONArray processInfo = new JSONArray(); //主流程信息
        ProcessInfoDTO processInfoDTO = null;
        if (orunId != null) {
            processInfoDTO = new ProcessInfoDTO();
            processInfoDTO.setSysAppId(sysAppId);
            processInfoDTO.setOrunId(sysAppId + flowId);
            setProcessInfoDTO(processInfoDTO, toDoTaskDto, basicSchool.getCode());
//            processInfo.add(processInfoDTO);
        }
//        data.put("processInfo", processInfo);

        JSONArray todoInfo = new JSONArray(); //待办信息
        if (Objects.nonNull(toDoTaskDto) && Objects.nonNull(toDoTaskDto.getHandleMessageDto())) {
            List<StandardFlowWorkMsg> todoTaskList = toDoTaskDto.getHandleMessageDto().getTodoTaskList();
            if (!CollectionUtils.isEmpty(todoTaskList)) {
                for (StandardFlowWorkMsg s : todoTaskList) {
                    TodoInfoDTO todoInfoDTO = new TodoInfoDTO();
                    setTodoInfoDTO(todoInfoDTO, s, basicSchool.getCode());
                    if (Objects.nonNull(processInfoDTO)) {
                        processInfoDTO.setUserId(todoInfoDTO.getUserId());
                        processInfoDTO.setUserName(todoInfoDTO.getUserName());
                        processInfoDTO.setUrl(todoInfoDTO.getUrl());
                        processInfoDTO.setMobileUrl(todoInfoDTO.getMobileUrl());
                    }
                    todoInfo.add(todoInfoDTO);
                }
                data.put("todoInfo", todoInfo);
            }
        }

        if (orunId != null && Objects.nonNull(processInfoDTO)) {
            processInfo.add(processInfoDTO);
        }
        data.put("processInfo", processInfo);
//        JSONArray toreadInfo = new JSONArray(); //待阅信息
//        if (orunId != null) {
//            ToReadInfoDTO toReadInfoDTO = new ToReadInfoDTO();
//            // TODO 根据业务系统和场景，传入待阅参数，如无数据，则无需传参。
//            setToReadInfoDTO(toReadInfoDTO);
//            toreadInfo.add(toReadInfoDTO);
//        }
        DoneTaskDto doneTaskDto = FlowMqCacheUtil.getDoneTask(flowId);
        if (Objects.nonNull(doneTaskDto)) {
            JSONArray remarkInfo = new JSONArray(); //已办信息
            RemarkInfoDTO remarkInfoDTO = new RemarkInfoDTO();
            setRemarkInfoDTO(remarkInfoDTO, doneTaskDto, basicSchool.getCode());
            remarkInfo.add(remarkInfoDTO);
            data.put("remarkInfo", remarkInfo);
        }

//        data.put("processInfo", processInfo);
//        data.put("todoInfo", todoInfo);
//        data.put("toreadInfo", toreadInfo);
//        data.put("remarkInfo", remarkInfo);
        content.put("statusCode", 200);
        content.put("success", true);
        content.put("message", "操作成功!");
        content.put("data", data);
        log.info("content:{}", content.toJSONString());
        //请求参数body内容加密
        try {
            result.put("content", AESEncryptUtils.aesEncrypt(content.toJSONString(), appSecret.substring(0, 16)));
        } catch (Exception e) {
            System.out.println("AES加密失败");
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        return result;
    }

    private void setProcessInfoDTO(ProcessInfoDTO processInfoDTO, ToDoTaskDto toDoTaskDto, String schoolCode) {
//        processInfoDTO.setSysAppId("LYOA");
//        processInfoDTO.setOrunId("LYOA79ec0af89702d641d839d5bbb5e9073b0e4b");
        if (Objects.nonNull(toDoTaskDto)) {
            List<String> userIdList = new LinkedList<>(), userNameList = new LinkedList<>(), taskIdList = new LinkedList<>();
            String taskName = null, requestUserId = null, requestUserName = null;
            if (Objects.nonNull(toDoTaskDto.getHandleMessageDto())) {
                List<StandardFlowWorkMsg> standardFlowWorkMsgList = toDoTaskDto.getHandleMessageDto().getTodoTaskList();
                if (!CollectionUtils.isEmpty(standardFlowWorkMsgList)) {
                    for (StandardFlowWorkMsg s : standardFlowWorkMsgList) {
                        userIdList.add(s.getLoginName());
                        userNameList.add(s.getUserName());
                        if (Objects.isNull(requestUserId)) {
                            requestUserId = s.getCreateLoginName();
                        }
                        if (Objects.isNull(requestUserName)) {
                            requestUserName = s.getCreateRealName();
                        }
                        taskIdList.add(String.valueOf(s.getTaskId()));
                        taskName = s.getTaskName();
                    }
                }
            }

            processInfoDTO.setSubject(toDoTaskDto.getFlowData().getName());
            processInfoDTO.setCurrentNodeId(StringUtils.join(taskIdList, ","));
            processInfoDTO.setCurrentNodeName(taskName);
//        processInfoDTO.setStatus(standardFlowWorkMsgList.get(0).getStatus().name());
            processInfoDTO.setStatus("Current");
            processInfoDTO.setUserId(requestUserId); //申请人ID
            processInfoDTO.setUserName(requestUserName); //申请人名称
            processInfoDTO.setAuthor(StringUtils.join(userIdList, ",")); //当前审批人的账户ID（多个使用逗号分隔（示例：2007112, admin））
            processInfoDTO.setAuthorCn(StringUtils.join(userNameList, ",")); //当前审批人的账户名称（多个使用逗号分隔（示例：2007112, admin））
            processInfoDTO.setUrl(SystemConstant.GDPU_CAS_MQ_URL + "?schoolCode=" + schoolCode + "&employeeNo=" + requestUserId);
            processInfoDTO.setMobileUrl(SystemConstant.GDPU_CAS_MQ_URL + "?schoolCode=" + schoolCode + "&employeeNo=" + requestUserId);
            processInfoDTO.setDocAddTime(new Date());// "2022-07-25 02:36:00"
            processInfoDTO.setDocEndTime(new Date());
            processInfoDTO.setDesc(toDoTaskDto.getFlowData().getName());
        }
    }

    private void setTodoInfoDTO(TodoInfoDTO todoInfoDTO, StandardFlowWorkMsg standardFlowWorkMsg, String schoolCode) {
        todoInfoDTO.setUserId(standardFlowWorkMsg.getLoginName());
        todoInfoDTO.setUserName(standardFlowWorkMsg.getUserName());
        todoInfoDTO.setStartTime(DateUtil.format(new Date(standardFlowWorkMsg.getCreateTime()), SystemConstant.DEFAULT_DATE_PATTERN));
        todoInfoDTO.setOrunId(String.valueOf(standardFlowWorkMsg.getExecutionId()));
        todoInfoDTO.setNodeId(String.valueOf(standardFlowWorkMsg.getTaskId()));
        todoInfoDTO.setNodeName(standardFlowWorkMsg.getTaskName());
        todoInfoDTO.setUrl(SystemConstant.GDPU_CAS_MQ_URL + "?schoolCode=" + schoolCode + "&employeeNo=" + standardFlowWorkMsg.getLoginName());
        todoInfoDTO.setMobileUrl(SystemConstant.GDPU_CAS_MQ_URL + "?schoolCode=" + schoolCode + "&employeeNo=" + standardFlowWorkMsg.getLoginName());
        todoInfoDTO.setStatus("Current"); //当出现或签、抢占流程时，需要将其他未办理用户设置为Pause状态。
    }

    //以审批通过为例，给出办理记录DTO的数据填充demo
    private void setRemarkInfoDTO(RemarkInfoDTO remarkInfoDTO, DoneTaskDto doneTaskDto, String schoolCode) {
        remarkInfoDTO.setNodeId(String.valueOf(doneTaskDto.getTaskId()));
        remarkInfoDTO.setNodeName(doneTaskDto.getHistoricName());
        remarkInfoDTO.setStartTime(DateUtil.format(new Date(doneTaskDto.getCreateTime()), SystemConstant.DEFAULT_DATE_PATTERN));
        remarkInfoDTO.setEndTime(DateUtil.format(new Date(doneTaskDto.getCreateTime()), SystemConstant.DEFAULT_DATE_PATTERN));
        remarkInfoDTO.setActionName(doneTaskDto.getApproveOperation().name());
        remarkInfoDTO.setUserId(doneTaskDto.getApproveUserName());
        remarkInfoDTO.setUserName(doneTaskDto.getRealName());
        remarkInfoDTO.setOrunId(String.valueOf(doneTaskDto.getId()));
        remarkInfoDTO.setRemark(doneTaskDto.getApproveRemark());
        remarkInfoDTO.setUrl(SystemConstant.GDPU_CAS_MQ_URL + "?schoolCode=" + schoolCode + "&employeeNo=" + doneTaskDto.getApproveUserName());
        remarkInfoDTO.setMobileUrl(SystemConstant.GDPU_CAS_MQ_URL + "?schoolCode=" + schoolCode + "&employeeNo=" + doneTaskDto.getApproveUserName());
    }

//    private void setToReadInfoDTO(ToReadInfoDTO toReadInfoDTO) {
//        JSONArray toReadUsers = new JSONArray();
////根据场景 -- 插入待阅用户记录
//        JSONObject toReadUser1 = new JSONObject();
//        toReadUser1.put("toReadUserId", "admin");
//        toReadUser1.put("toReadUserName", "超级管理员");
//        toReadUser1.put("Status", "Current");
//        toReadUser1.put("remark", null);
//        toReadUser1.put("startTime", "2022-12-09 17:34:46");
//        toReadUsers.add(toReadUser1);
////根据场景 -- 更新已阅用户记录
//        JSONObject toReadUser2 = new JSONObject();
//        toReadUser2.put("toReadUserId", "admin");
//        toReadUser2.put("toReadUserName", "超级管理员");
//        toReadUser2.put("Status", "End");
//        toReadUser2.put("remark", "已读");
//        toReadUser2.put("startTime", "2022-12-09 17:34:46");
//        toReadUser2.put("readTime", "2022-12-10 17:34:46");
//        toReadUsers.add(toReadUser2);
//        toReadInfoDTO.setToReadUser(toReadUsers);
////        toReadInfoDTO.setOrunId("a18a585c07b1c04cb00b66e0b76ca9125456");
//        toReadInfoDTO.setNodeId("T10005");
//        toReadInfoDTO.setUrl("https://portal.lysky.com:6205/bpmui/#/formRender/run?docUnid=79ec0af89702d641d839d5bbb5e9073b0e4b");
//        toReadInfoDTO.setMobileUrl("https://portal.lysky.com:6205/bpmui/#/formRender/run?docUnid=79ec0af89702d641d839d5bbb5e9073b0e4b");
//        toReadInfoDTO.setNodeName("部门审批");
//    }
}