package com.kingdee.eas.custom.perfweb.handler;

import com.kingdee.bos.BOSException;
import com.kingdee.bos.Context;
import com.kingdee.eas.common.EASBizException;
import com.kingdee.eas.custom.perfweb.utils.FeishuMessageUtil;
import com.kingdee.eas.custom.perfweb.utils.PerfEvaObjectUtil;
import com.kingdee.eas.custom.perfweb.utils.UrlParamUtil;
import com.kingdee.shr.perfweb.app.base.evalplan.IPerfPeriod;
import com.kingdee.shr.perfweb.app.base.evalplan.PerfPeriodFactory;
import com.kingdee.shr.perfweb.app.base.evalplan.PerfPeriodInfo;
import com.kingdee.shr.perfweb.planexecute.handler.perfGoalsWorkListHandler;
import com.kingdee.shr.base.syssetting.api.bean.BatchMessageTipsBody;
import com.kingdee.shr.base.syssetting.api.bean.BatchMessageTipsHeader;
import com.kingdee.shr.base.syssetting.context.SHRContext;
import com.kingdee.shr.base.syssetting.exception.SHRWebException;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.ui.ModelMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * 绩效目标考核-启动考核后发送飞书消息
 * <p>
 * 扩展点：重写 startEvaTaskAction，
 * 先调用 super 保留标品全部逻辑，再追加飞书消息推送
 *
 * @author 青梧
 * @date 2026-06-10
 */
public class perfGoalsWorkListHandlerEx extends perfGoalsWorkListHandler {

    private Logger logger = Logger.getLogger(perfGoalsWorkListHandlerEx.class);
    private Context ctx = SHRContext.getInstance().getContext();

    /**
     * 重写启动考核方法
     * <p>
     * 执行顺序：
     * 1. super.startEvaTaskAction()  ← 标品全部逻辑，完全保留，不修改
     * 2. 分析 tipsHeader，区分成功/失败
     * 3. 对成功的处理人发送飞书消息（同一处理人只发一次）
     */
    @Override
    public void startEvaTaskAction(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap, BatchMessageTipsHeader tipsHeader) throws SHRWebException {

        // 【关键】先调用父类，标品逻辑完全保留，不修改任何原有行为
        super.startEvaTaskAction(request, response, modelMap, tipsHeader);

        // 父类执行完后，tipsHeader 中已记录了成功/失败的明细
        // 现在追加飞书推送逻辑
        try {
            sendFeishuForSuccessPersons(request, tipsHeader);
        } catch (Exception e) {
            // 飞书推送失败不影响启动考核主流程
            logger.error("飞书推送异常（不影响启动考核）", e);
        }
    }

    /**
     * 从 tipsHeader 中解析成功人员，发送飞书消息
     * <p>
     * 标品行为说明：
     * - tipsHeader.getSuccessCount() 未填充，永远为 0，不可用
     * - tipsHeader.getResult() 只记录【失败】的明细
     * - isMuitTipsState() 恒为 false，无需判断，getResult() 中的全是失败记录
     * - 因此：成功ID = 前端勾选的全部billId - getResult()中的失败ID
     */
    private void sendFeishuForSuccessPersons(HttpServletRequest request, BatchMessageTipsHeader tipsHeader) throws BOSException, EASBizException {

        String periodId = request.getParameter("period");
        String workFlowId = request.getParameter("workflowId");
        logger.error("sendFeishuForSuccessPersons start, periodId=" + periodId + ", workFlowId=" + workFlowId);

        // ===== Step1: 从 request 中获取前端勾选的全部 evaObjId（billIds 参数）=====
        // billIds 格式: "evaObjId1$workFlowId1,evaObjId2$workFlowId2,..."
        String billIds = request.getParameter("billId");
        if (StringUtils.isBlank(billIds)) {
            logger.error("request 中未找到 billIds 参数，无法判断成功人员");
            return;
        }

        // 解析全部勾选ID，按前端顺序构建 evaObjSet（第一条用于飞书模板）
        String[] idPairs = billIds.split(",");
        logger.error("前端勾选总数：" + idPairs.length);

        Set<String> failureIds = new HashSet<>();
        List<BatchMessageTipsBody> results = tipsHeader.getResult();
        if (results != null) {
            for (BatchMessageTipsBody body : results) {
                String rawId = body.getId();
                int dollarIdx = rawId.indexOf("$");
                String evaObjId = (dollarIdx > 0) ? rawId.substring(0, dollarIdx) : rawId;
                failureIds.add(evaObjId);
                logger.error("启动考核失败：" + evaObjId + "，原因：" + body.getMuitTipsMessage());
            }
        }
        logger.error("失败ID数：" + failureIds.size());

        Set<String> evaObjSet = new LinkedHashSet<>();
        int successCount = 0;
        for (String pair : idPairs) {
            String trimmed = pair.trim();
            int dollarIdx = trimmed.indexOf("$");
            String evaObjId = (dollarIdx > 0) ? trimmed.substring(0, dollarIdx) : trimmed;
            if (!failureIds.contains(evaObjId)) {
                evaObjSet.add(evaObjId);
                successCount++;
            }
        }
        logger.error("解析结果：成功ID数=" + successCount + "，失败ID数=" + failureIds.size());

        if (evaObjSet.isEmpty()) {
            logger.error("没有成功启动的人员，跳过飞书推送");
            return;
        }

        // ===== Step5: 按「设置评分人」TargetNode 查一级节点处理人（不读节点实例，避免旧处理人）=====
        Map<String, String> currentHandlerMap = new HashMap<>();
        Map<String, Set<String>> evaObjHandlerMap = new HashMap<>();
        Map<String, String> workFlowNameMap = new HashMap<>();

        IPerfPeriod iPerfPeriod = PerfPeriodFactory.getLocalInstance(ctx);
        PerfPeriodInfo perfPeriodInfo = iPerfPeriod.getPerfPeriodInfo("where id = '" + periodId + "'");
        if (!evaObjSet.isEmpty()) {
            PerfEvaObjectUtil.getBatchTargetNodeHandlersForEvaObj(ctx, evaObjSet, currentHandlerMap, evaObjHandlerMap, workFlowNameMap, "1");
        }
        if (evaObjHandlerMap.isEmpty()) {
            logger.error("TargetNode 未查到任何评分人，跳过飞书推送");
            return;
        }
        // ===== Step6: 发送飞书消息（按处理人去重，同一处理人只发一次）=====
        String workFlowName = workFlowNameMap.isEmpty() ? "" : workFlowNameMap.values().iterator().next();
        String messageUrl = UrlParamUtil.buildPerfPortalFeishuMessageUrl();
        FeishuMessageUtil.sendInitialFeishuTodos(ctx, evaObjHandlerMap, evaObjSet, perfPeriodInfo, messageUrl, workFlowName, messageUrl);
    }
}
