package com.jeelowcode.module.biz.service.impl;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.jeelowcode.framework.plus.core.toolkit.StringUtils;
import com.jeelowcode.framework.utils.tool.spring.SpringUtils;
import com.jeelowcode.module.biz.service.IPortalTodoService;
import com.jeelowcode.module.biz.service.IRiskService;
import com.jeelowcode.module.biz.service.ITodoRequestService;
import com.jeelowcode.service.bpm.config.framework.portal.core.PortalRequest;
import com.jeelowcode.service.bpm.config.framework.portal.core.dto.DeleteRequestInfoDTO;
import com.jeelowcode.service.bpm.config.framework.portal.core.dto.ReceiveRequestInfoDTO;
import com.jeelowcode.service.system.api.IApiAdminUserApi;
import com.jeelowcode.service.system.dto.AdminUserRespDTO;
import com.jeelowcode.service.system.entity.DictDataDO;
import com.jeelowcode.service.system.service.IDictDataService;
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

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

import static com.jeelowcode.tool.framework.common.util.collection.CollectionUtils.getFirst;

/**
 * 待办系统接口实现类
 *
 * @author yangchenjj
 */
@Slf4j
@Service
public class PortalTodoServiceImpl implements IPortalTodoService {

    private static final String SPACE = " ";
    private static final String WORK_NODE_NAME = "整改风险隐患";
    private static final String WORK_FLOW_NAME = "风险隐患信息";
    // TODO 待办跳转链接,这个以后需要优化，通过配置去取这个链接，不能写死在这里
    private static final String RISK_PC_URL = "/fx/table/view/1963446160885366786";
    private static final String WORK_STATUS_TODO = "0";
    private static final String WORK_STATUS_DONE = "2";
    private static final String WORK_STATUS_COMPLETE = "4";
    private static final String VIEW_TYPE_UNREAD = "0";
    private static final String VIEW_TYPE_READ = "1";
    private static final String Bill_Table_Name = "lc_risk_hazard_manage";

    @Resource
    private IRiskService riskService;
    @Resource
    private IApiAdminUserApi apiAdminUserApi;

    @Resource
    private IDictDataService dictDataService;

    @Resource
    private ITodoRequestService todoRequestService;

    @Override
    public boolean pushDoneRiskHazardWorkflow(Long id, String todoType) {
        // 0.1.查找风险隐患数据，如果查不到则放弃推送
        Map<String, Object> risk = riskService.getRiskById(id);
        if (MapUtil.isEmpty(risk)) return false;
        // 0.2.从容器中获取 PortalRequest 对象，如果没有配置则放弃通知
        PortalRequest portalRequest = SpringUtils.getBean(PortalRequest.class);
        if (!Objects.requireNonNull(portalRequest).available()) return false;

        // 0.3.判断是否存在 场景下发送的消息，已经发送过消息的不重复发送
        boolean isExist = todoRequestService.isExistTodoRequest(id, todoType);
        if(isExist)
        {
            return true;
        }

        // 1.构建请求参数,准备推送待办信息
        String creator = "";
        String receiver = "";
        String isRemark = "";
        String viewType = "";
        String checkArea = "";
        // 1.1.拼接标题

        DictDataDO dictData = dictDataService.getDictData("check_area_dic", risk.getOrDefault("check_area", "").toString());
        if (dictData != null) {
            checkArea = dictData.getLabel();
        }

        String requestName = DateUtil.formatDate((Date) risk.getOrDefault("check_date", new Date())) + SPACE +
                risk.getOrDefault("parkname", "") + SPACE +
                checkArea + SPACE +
                risk.getOrDefault("check_content", "") + SPACE +
                risk.getOrDefault("check_problem", "") + SPACE +
                risk.getOrDefault("check_people", "");
        // 1.2.根据代办类型取消息发送者 TODO 需要升级存储检查人的username
        if (todoType.equals("CHARGE_TODO") || todoType.equals("CHARGE_DONE")) {
            if (todoType.equals("CHARGE_TODO")) {
                isRemark = WORK_STATUS_TODO;
                viewType = VIEW_TYPE_UNREAD;
            } else {
                isRemark = WORK_STATUS_DONE;
                viewType = VIEW_TYPE_READ;
            }

            // 消息发送者为 检查人
            Long createUserId = Objects.isNull(risk.get("check_people_id")) ? null : Long.valueOf(risk.get("check_people_id").toString());
            AdminUserRespDTO createUser = Optional.ofNullable(createUserId)
                    .map(userId -> apiAdminUserApi.getUser(userId))
                    .orElse(new AdminUserRespDTO());
            if (StringUtils.isEmpty(createUser.getUsername())) {
                return false;
            } else {
                creator = createUser.getUsername();
            }

            // 消息接受者为 整改责任人
            Long receiveId = Objects.isNull(risk.get("corrective_charge_people_id")) ? null : Long.valueOf(risk.get("corrective_charge_people_id").toString());
            AdminUserRespDTO receiveUser = Optional.ofNullable(receiveId)
                    .map(userId -> apiAdminUserApi.getUser(userId))
                    .orElse(new AdminUserRespDTO());
            if (StringUtils.isEmpty(receiveUser.getUsername())) {
                return false;
            } else {
                receiver = receiveUser.getUsername();
            }
        } else if (todoType.equals("CONFIRM_TODO") || todoType.equals("CONFIRM_DONE")) {
            if (todoType.equals("CONFIRM_TODO")) {
                isRemark = WORK_STATUS_TODO;
                viewType = VIEW_TYPE_UNREAD;
            } else {
                isRemark = WORK_STATUS_DONE;
                viewType = VIEW_TYPE_READ;
            }

            // 消息发送者为 整改责任人
            Long createUserId = Objects.isNull(risk.get("corrective_charge_people_id")) ? null : Long.valueOf(risk.get("corrective_charge_people_id").toString());
            AdminUserRespDTO createUser = Optional.ofNullable(createUserId)
                    .map(userId -> apiAdminUserApi.getUser(userId))
                    .orElse(new AdminUserRespDTO());
            if (StringUtils.isEmpty(createUser.getUsername())) {
                return false;
            } else {
                creator = createUser.getUsername();
            }

            // 消息接受者为 整改确认人
            Long receiveId = Objects.isNull(risk.get("corrective_confirm_people_id")) ? null : Long.valueOf(risk.get("corrective_confirm_people_id").toString());
            AdminUserRespDTO receiveUser = Optional.ofNullable(receiveId)
                    .map(userId -> apiAdminUserApi.getUser(userId))
                    .orElse(new AdminUserRespDTO());
            if (StringUtils.isEmpty(receiveUser.getUsername())) {
                return false;
            } else {
                receiver = receiveUser.getUsername();
            }
        }
        // 1.2.组织请求数据
        ReceiveRequestInfoDTO todoRequestDTO = new ReceiveRequestInfoDTO()
                .setFlowId(Base64.encode(String.valueOf(id)))
                .setRequestName(requestName)
                .setWorkflowName(WORK_FLOW_NAME)
                .setNodeName(WORK_NODE_NAME)
                .setPcUrl(RISK_PC_URL)
                .setIsRemark(isRemark)
                .setViewType(viewType)
                .setCreator(creator)
                .setCreateDateTime(new Date())
                .setReceiver(receiver)
                .setReceiveDateTime(new Date())
                .setReceiveTs(String.valueOf(System.currentTimeMillis()));
        ReceiveRequestInfoDTO completeRequestDTO = BeanUtils.toBean(todoRequestDTO, ReceiveRequestInfoDTO.class);
        completeRequestDTO.setIsRemark(WORK_STATUS_COMPLETE);

        // 1.3.构建发送消息详情
        HashMap<String, Object> newRecord = new HashMap<>();
        newRecord.put("bill_id", id);
        newRecord.put("bill_table_name", Bill_Table_Name);
        newRecord.put("bill_action", todoType);
        newRecord.put("todo_request", JSONUtil.toJsonStr(todoRequestDTO));

        // 2.推送待办信息，使用try-catch避免影响上层调用方法的事务回滚
        try {

            portalRequest.receiveRequestInfo(todoRequestDTO);
            newRecord.put("is_success", 1);
            todoRequestService.addTodoRequest(newRecord);
            if (todoType.equals("CONFIRM_DONE")) {
                portalRequest.receiveRequestInfo(completeRequestDTO);
            }
        } catch (Exception e) {
            log.error("推送待办信息失败", e);
            newRecord.put("is_success", 0);
            todoRequestService.addTodoRequest(newRecord);
            return false;
        }
        return true;
    }

    @Override
    public boolean pushCancelRiskHazardWorkflow(Long id) {
        // 0.1.查找风险隐患数据，如果查不到则放弃推送
        Map<String, Object> risk = riskService.getRiskById(id);
        if (MapUtil.isEmpty(risk)) return false;
        // 0.2.从容器中获取 PortalRequest 对象，如果没有配置则放弃通知
        PortalRequest portalRequest = SpringUtils.getBean(PortalRequest.class);
        if (!Objects.requireNonNull(portalRequest).available()) return false;

        // 1.构建请求参数,准备推送待办信息
        DeleteRequestInfoDTO deleteRequestInfoDTO = new DeleteRequestInfoDTO()
                .setFlowId(Base64.encode(String.valueOf(id)));
        // 2.推送待办信息，使用try-catch避免影响上层调用方法的事务回滚
        try {
            portalRequest.deleteRequestInfo(deleteRequestInfoDTO);
        } catch (Exception e) {
            log.error("删除待办信息失败", e);
            return false;
        }
        return true;
    }

}
