package com.yeejoin.amos.boot.module.jg.biz.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yeejoin.amos.boot.biz.common.bo.ReginParams;
import com.yeejoin.amos.boot.biz.common.utils.RedisKey;
import com.yeejoin.amos.boot.biz.common.utils.RedisUtils;
import com.yeejoin.amos.boot.module.jg.api.entity.JgEnableDisable;
import com.yeejoin.amos.boot.module.jg.api.entity.JgEnableDisableEq;
import com.yeejoin.amos.boot.module.jg.api.entity.JgMaintenanceContract;
import com.yeejoin.amos.boot.module.jg.api.entity.JgUseRegistration;
import com.yeejoin.amos.boot.module.jg.api.enums.WorkFlowStatusEnum;
import com.yeejoin.amos.boot.module.jg.api.mapper.JgEnableDisableMapper;
import com.yeejoin.amos.boot.module.jg.api.service.IJgEnableDisableService;
import com.yeejoin.amos.boot.module.jg.api.dto.JgEnableDisableDto;
import com.yeejoin.amos.boot.module.jg.biz.feign.TzsServiceFeignClient;
import com.yeejoin.amos.boot.module.jg.flc.api.fegin.WorkFlowFeignService;
import com.yeejoin.amos.boot.module.ymt.api.enums.ApplicationFormTypeEnum;
import com.yeejoin.amos.boot.module.ymt.api.enums.FlowStatusEnum;
import com.yeejoin.amos.component.feign.model.FeignClientResult;
import com.yeejoin.amos.feign.workflow.Workflow;
import com.yeejoin.amos.feign.workflow.model.ActWorkflowStartDTO;
import com.yeejoin.amos.feign.workflow.model.AjaxResult;
import com.yeejoin.amos.feign.workflow.model.TaskResultDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.typroject.tyboot.core.foundation.context.RequestContext;
import org.typroject.tyboot.core.rdbms.service.BaseService;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.typroject.tyboot.core.restful.utils.ResponseModel;

import java.util.*;

/**
 * 服务实现类
 *
 * @author system_generator
 * @date 2023-12-25
 */
@Service
public class JgEnableDisableServiceImpl extends BaseService<JgEnableDisableDto, JgEnableDisable, JgEnableDisableMapper> implements IJgEnableDisableService {

    @Autowired
    WorkFlowFeignService workFlowFeginService;

    @Autowired
    RedisUtils redisUtils;

    @Autowired
    JgEnableDisableEqServiceImpl jgEnableDisableEqService;

    @Autowired
    TzsServiceFeignClient tzsServiceFeignClient;


    private final String WORK_FLOW_KEY = "deactivateEnable";


    public void saveOrUpdate(JSONObject map) {
        ReginParams reginParams = JSONObject.parseObject(redisUtils.get(RedisKey.buildReginKey(RequestContext.getExeUserId(), RequestContext.getToken())).toString(), ReginParams.class);
        JgEnableDisable jgEnableDisable = new JgEnableDisable();
        BeanUtil.copyProperties(map, jgEnableDisable);
        jgEnableDisable.setApplyDate(new Date());
        String submit = String.valueOf(map.get("submit"));
        String pageType = String.valueOf(map.get("pageType"));
        if (map.containsKey("receiveOrgCode")) {
            // 接收机构
            String[] splitMaintenanceUnitCode = String.valueOf(map.getString("receiveOrgCode")).split("_");
            jgEnableDisable.setReceiveOrgCode(splitMaintenanceUnitCode[0]);
            jgEnableDisable.setReceiveOrgName(splitMaintenanceUnitCode[1]);
        }
        jgEnableDisable.setUseUnitCreditCode(reginParams.getCompany().getCompanyCode());
        jgEnableDisable.setUseUnitName(reginParams.getCompany().getCompanyName());
        // 仅保存
        if ("add".equals(pageType)) {
            // 获取申请编号
            ResponseModel<List<String>> listResponseModel = tzsServiceFeignClient.applicationFormCode(ApplicationFormTypeEnum.TYQY.getCode(), 1);
            if (!ObjectUtils.isEmpty(listResponseModel)) {
                jgEnableDisable.setApplyNo(listResponseModel.getResult().get(0));
            }
            jgEnableDisable.setAuditStatus(WorkFlowStatusEnum.ENABLE_SUBMIT.getPass());
            this.save(jgEnableDisable);
        } else {
            // 编辑
            jgEnableDisable.setSequenceNbr(Long.valueOf(String.valueOf(map.get("sequenceNbr"))));
            this.baseMapper.updateById(jgEnableDisable);
            LambdaQueryWrapper<JgEnableDisableEq> lambda = new QueryWrapper<JgEnableDisableEq>().lambda();
            lambda.eq(JgEnableDisableEq::getEnableDisableApplyId, String.valueOf(map.get("sequenceNbr")));
            jgEnableDisableEqService.getBaseMapper().delete(lambda);
        }
        // 关联设备表
        JgEnableDisableEq jgEnableDisableEq = new JgEnableDisableEq();
        jgEnableDisableEq.setEquId(String.valueOf(map.get("record")));
        jgEnableDisableEq.setEnableDisableApplyId(jgEnableDisable.getSequenceNbr().toString());
        jgEnableDisableEqService.save(jgEnableDisableEq);
        // 提交启动流程
        if ("1".equals(submit)) {
            String instanceId = "";
            if (map.containsKey("instanceId")) {
                instanceId = map.get("instanceId").toString();
            } else {
                instanceId = startByVariable();
            }
            if (!ObjectUtils.isEmpty(instanceId)) {
                // 更新数据状态
                updateExecuteIds(instanceId, jgEnableDisable.getSequenceNbr(), "0");
                // 执行流程
                flowExecute(jgEnableDisable.getSequenceNbr(), instanceId, "0", "");
            }
        }
    }


    public Page<Map<String, Object>> pageList(Page<Map<String, Object>> page, JgEnableDisableDto dto) {
        ReginParams reginParams = JSONObject.parseObject(redisUtils.get(RedisKey.buildReginKey(RequestContext.getExeUserId(), RequestContext.getToken())).toString(), ReginParams.class);
        dto.setUseUnitCreditCode(reginParams.getCompany().getCompanyCode());
        return this.baseMapper.pageList(page, dto);
    }


    public String startByVariable() {
        String instanceId = "";
        //启动流程
        try {
            ActWorkflowStartDTO dto = new ActWorkflowStartDTO();
            dto.setProcessDefinitionKey(WORK_FLOW_KEY);
            dto.setBusinessKey("submit");
            AjaxResult ajaxResult = Workflow.taskClient.startByVariable(dto);
            instanceId = ((Map<?, ?>) ajaxResult.get("data")).get("id").toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return instanceId;
    }

    public void flowExecute(Long id, String instanceId, String operate, String comment) {
        try {
            JgEnableDisable jgEnableDisable = this.baseMapper.selectById(id);
            JSONObject task = workFlowFeginService.getTaskNoAuth(instanceId);
            JSONObject taskMessage = JSON.parseObject(JSON.toJSONString(task.get("data")));
            String taskId = taskMessage.getString("id");
            //组装信息
            TaskResultDTO dto = new TaskResultDTO();
            dto.setResultCode("approvalStatus");
            dto.setTaskId(taskId);
            dto.setComment(comment);
            HashMap<String, Object> map = new HashMap<>();
            map.put("approvalStatus", operate);
            if (WorkFlowStatusEnum.ENABLE_SUBMIT.getReject().equals(jgEnableDisable.getAuditStatus()) || WorkFlowStatusEnum.ENABLE_SUBMIT.getRollBack().equals(jgEnableDisable.getAuditStatus())) {
                map.put("approvalStatus", "提交");
            }
            dto.setVariable(map);
            //执行流程
            Workflow.taskClient.completeByTask(taskId, dto);
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 更新下一步执行人
        updateExecuteIds(instanceId, id, operate);

    }

    public void withdraw(String instanceId) {
        ReginParams reginParams = JSONObject.parseObject(redisUtils.get(RedisKey.buildReginKey(RequestContext.getExeUserId(), RequestContext.getToken())).toString(), ReginParams.class);
        String taskCode = "";
        JgEnableDisable jgEnableDisable = new JgEnableDisable();
        LambdaQueryWrapper<JgEnableDisable> lambda = new QueryWrapper<JgEnableDisable>().lambda();
        lambda.eq(JgEnableDisable::getInstanceId, instanceId);
        ArrayList<String> roleList = new ArrayList<>();
        try {
            workFlowFeginService.rollBack(instanceId);
            JSONObject taskNoAuth = workFlowFeginService.getTaskNoAuth(instanceId);
            JSONObject nextTask = JSON.parseObject(JSON.toJSONString(taskNoAuth.get("data")));

            if (!ObjectUtils.isEmpty(taskNoAuth.get("data"))) {
                String nextTaskId = nextTask.getString("id");
                FeignClientResult<JSONObject> nodeInfo = workFlowFeginService.getNodeInfo(nextTaskId);
                JSONObject result = nodeInfo.getResult();
                Map<String, Object> taskInfo = (Map<String, Object>) result.get("taskInfo");
                taskCode = String.valueOf(taskInfo.get("taskDefinitionKey"));
                AjaxResult taskGroupName = Workflow.taskClient.getTaskGroupName(nextTaskId);
                JSONArray data = JSON.parseArray(JSON.toJSONString(taskGroupName.get("data")));
                for (Object datum : data) {
                    if (((Map<?, ?>) datum).containsKey("groupId")) {
                        roleList.add(((Map<?, ?>) datum).get("groupId").toString());
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (!ObjectUtils.isEmpty(taskCode)) {

            jgEnableDisable.setAuditStatus(WorkFlowStatusEnum.getMessage(taskCode).getRollBack());
        }
        String join = String.join(",", roleList);
        jgEnableDisable.setPromoter(reginParams.getUserModel().getUserId());
        jgEnableDisable.setNextExecutorIds(join);
        this.update(jgEnableDisable, lambda);
    }


    public void updateExecuteIds(String instanceId, Long sequenceNbr, String operate) {
        ReginParams reginParams = JSONObject.parseObject(redisUtils.get(RedisKey.buildReginKey(RequestContext.getExeUserId(), RequestContext.getToken())).toString(), ReginParams.class);
        String role = "";
        String taskCode = FlowStatusEnum.TO_BE_FINISHED.getName();
        ArrayList<String> roleList = new ArrayList<>();
        JgEnableDisable jgEnableDisable = this.getBaseMapper().selectById(sequenceNbr);
        try {
            // 查询下节点任务

            JSONObject taskNoAuth = workFlowFeginService.getTaskNoAuth(instanceId);
            if (!ObjectUtils.isEmpty(taskNoAuth.get("data"))) {
                JSONObject nextTask = JSON.parseObject(JSON.toJSONString(taskNoAuth.get("data")));
                String nextTaskId = nextTask.getString("id");
                FeignClientResult<JSONObject> nodeInfo = workFlowFeginService.getNodeInfo(nextTaskId);
                JSONObject result = nodeInfo.getResult();
                Map<String, Object> taskInfo = (Map<String, Object>) result.get("taskInfo");
                taskCode = String.valueOf(taskInfo.get("taskDefinitionKey"));
                AjaxResult taskGroupName = Workflow.taskClient.getTaskGroupName(nextTaskId);
                JSONArray data = JSON.parseArray(JSON.toJSONString(taskGroupName.get("data")));
                for (Object datum : data) {
                    if (((Map) datum).containsKey("groupId")) {
                        roleList.add(((Map) datum).get("groupId").toString());
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (!FlowStatusEnum.TO_BE_FINISHED.getName().equals(taskCode)) {
            role = String.join(",", roleList);
            jgEnableDisable.setNextExecutorIds(role);
            jgEnableDisable.setPromoter(reginParams.getUserModel().getUserId());
            jgEnableDisable.setInstanceId(instanceId);
            jgEnableDisable.setApplyDate(new Date());
            if (!ObjectUtils.isEmpty(jgEnableDisable.getExecuteSequence())) {
                jgEnableDisable.setExecuteSequence(jgEnableDisable.getExecuteSequence() + "," + role);
            } else {
                jgEnableDisable.setExecuteSequence(role);
            }
            if ("0".equals(operate)) {
                // 通过操作
                jgEnableDisable.setAuditStatus(WorkFlowStatusEnum.getMessage(taskCode).getPass());
            } else {
                // 驳回操作
                jgEnableDisable.setAuditStatus(WorkFlowStatusEnum.getMessage(taskCode).getReject());
                jgEnableDisable.setPromoter(null);
            }

        } else {
            jgEnableDisable.setAuditStatus(taskCode);
            jgEnableDisable.setAuditPassDate(new Date());
        }
        this.getBaseMapper().updateById(jgEnableDisable);
    }

    public void deleteMessage(Long sequenceNbr) {
        this.baseMapper.deleteById(sequenceNbr);
        LambdaQueryWrapper<JgEnableDisableEq> lambda = new QueryWrapper<JgEnableDisableEq>().lambda();
        lambda.eq(JgEnableDisableEq::getEnableDisableApplyId, sequenceNbr);
        jgEnableDisableEqService.getBaseMapper().delete(lambda);
    }

    public Map<String, Object> getDetail(Long sequenceNbr) {
        return this.baseMapper.getDetail(sequenceNbr);

    }

}