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

import com.kingdee.bos.Context;
import com.kingdee.bos.metadata.entity.*;
import com.kingdee.bos.metadata.query.util.CompareType;
import com.kingdee.eas.custom.perfweb.utils.FeishuMessageUtil;
import com.kingdee.eas.custom.perfweb.utils.UrlParamUtil;
import com.kingdee.eas.custom.perfweb.service.CenterPerfStatService;
import com.kingdee.shr.base.syssetting.context.SHRContext;
import com.kingdee.shr.base.syssetting.exception.SHRWebException;
import com.kingdee.shr.base.syssetting.web.json.JSONUtils;
import com.kingdee.shr.perfweb.app.base.evalplan.*;
import com.kingdee.shr.perfweb.planexecute.handler.EvaResultSummaryManagerListHandler;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ui.ModelMap;

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

/**
 * 类名称: EvaResultSummaryManagerListHandlerEx
 * 功能描述: 考核结果汇总列表发送飞书消息
 * 创建日期: 2026-06-15 10:54
 * 作    者: 青梧
 * 版    本: 1.0
 */
public class EvaResultSummaryManagerListHandlerEx extends EvaResultSummaryManagerListHandler {

    private static final Logger logger = LoggerFactory.getLogger(EvaResultSummaryManagerListHandlerEx.class);

    /** 标品考核结果汇总 billState：3 = 已审批（审批通过） */
    private static final String BILL_STATE_AUDITED = "3";

    /**
     * 发送飞书消息按钮 Action 入口
     * <p>
     * 按前端勾选的每条考核结果，向对应<strong>被考核人本人</strong>各发一条飞书通知（勾选几条发几条）。
     * 发送前须校验：对应考核周期下全部「考核结果说明」均已审批通过（autoStatus = SPTG）。
     * 单条考核结果须已审批（billState = 3，与列表「绩效状态」一致）。消息正文见 {@link FeishuMessageUtil#buildEvaResultSummaryFeishuMessage}。
     */
    public void sendFeishuToLeadersAction(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap) throws SHRWebException {
        Context ctx = SHRContext.getInstance().getContext();
        Map<String, Object> res = new HashMap<>();
        String billId = this.getBillId(request);

        if (StringUtils.isBlank(billId)) {
            res.put("result", "500");
            res.put("msg", "请先勾选需要发送消息的考核结果");
            JSONUtils.writeJson(response, res);
            return;
        }
        try {
            // 保留前端勾选顺序，每条 billId 对应一条发送
            List<String> selectedBillIds = parseSelectedBillIds(billId);
            if (selectedBillIds.isEmpty()) {
                res.put("result", "500");
                res.put("msg", "勾选的考核结果ID无效");
                JSONUtils.writeJson(response, res);
                return;
            }

            Map<String, EvaResultSummaryInfo> summaryById = loadSummaryByIds(ctx, selectedBillIds);
            if (summaryById.isEmpty()) {
                res.put("result", "500");
                res.put("msg", "未查询到勾选的考核结果数据");
                JSONUtils.writeJson(response, res);
                return;
            }

            Set<String> periodIds = collectPeriodIds(summaryById);
            for (String periodId : periodIds) {
                String blockMsg = CenterPerfStatService.validateAllDescriptionApprovedForNotify(ctx, periodId);
                if (blockMsg != null) {
                    res.put("result", "500");
                    res.put("msg", blockMsg);
                    JSONUtils.writeJson(response, res);
                    return;
                }
            }

            String pcurl = UrlParamUtil.buildPerfPortalFeishuMessageUrl();
            String appurl = pcurl;
            int successCount = 0;
            int skippedNotApproved = 0;
            int skippedNoPerson = 0;
            int skippedNotFound = 0;
            int failCount = 0;

            for (int i = 0; i < selectedBillIds.size(); i++) {
                String selectedId = selectedBillIds.get(i);
                EvaResultSummaryInfo summaryInfo = summaryById.get(selectedId);
                if (summaryInfo == null) {
                    skippedNotFound++;
                    continue;
                }
                if (!isApproved(summaryInfo)) {
                    skippedNotApproved++;
                    continue;
                }

                PerfEvaObjectInfo evaObj = summaryInfo.getEvaObj();
                PerfPeriodInfo period = summaryInfo.getPeriod();
                if (evaObj == null || evaObj.getPerson() == null
                        || StringUtils.isBlank(evaObj.getPerson().getNumber()) || period == null) {
                    skippedNoPerson++;
                    continue;
                }

                String receiverId = evaObj.getPerson().getNumber();
                String periodName = period.getName();
                String messageContent = FeishuMessageUtil.buildEvaResultSummaryFeishuMessage(periodName);
                String workFlowName = "绩效结果公示通知";
                String uuid = "esn_" + selectedId + "_" + receiverId+"_"+System.currentTimeMillis();;
                FeishuMessageUtil.ApprovalBotResult sendResult = FeishuMessageUtil.sendRemindMessage(
                        receiverId, workFlowName, messageContent, pcurl, appurl, uuid);
                if (sendResult.isSuccess()) {
                    successCount++;
                } else {
                    failCount++;
                    logger.error("考核结果汇总-飞书消息发送失败，billId={}，receiverId={}，msg={}",
                            selectedId, receiverId, sendResult.getMsg());
                }
            }

            if (successCount == 0) {
                res.put("result", "500");
                if (skippedNotApproved > 0) {
                    res.put("msg", "勾选的考核结果均未审批通过，无法发送（共 " + skippedNotApproved + " 条）");
                } else if (skippedNoPerson > 0) {
                    res.put("msg", "勾选的考核结果中未找到有效的被考核人工号");
                } else if (failCount > 0) {
                    res.put("msg", "飞书消息推送失败，请检查员工工号及飞书接口配置");
                } else {
                    res.put("msg", "未找到可推送的考核结果");
                }
                JSONUtils.writeJson(response, res);
                return;
            }

            StringBuilder msg = new StringBuilder("飞书消息推送成功，共发送 ").append(successCount).append(" 条");
            if (skippedNotApproved > 0) {
                msg.append("；").append(skippedNotApproved).append(" 条未审批已跳过");
            }
            if (skippedNoPerson > 0) {
                msg.append("；").append(skippedNoPerson).append(" 条无有效工号已跳过");
            }
            if (skippedNotFound > 0) {
                msg.append("；").append(skippedNotFound).append(" 条未查询到数据已跳过");
            }
            if (failCount > 0) {
                msg.append("；").append(failCount).append(" 条发送失败");
            }
            res.put("result", "200");
            res.put("msg", msg.toString());
            logger.info("考核结果汇总-飞书消息推送完成，成功={}，未审批跳过={}，无工号跳过={}，失败={}",
                    successCount, skippedNotApproved, skippedNoPerson, failCount);

        } catch (Exception e) {
            logger.error("考核结果汇总-飞书消息推送异常", e);
            res.put("result", "500");
            res.put("msg", "飞书消息推送失败：" + e.getMessage());
        }

        JSONUtils.writeJson(response, res);
    }

    private List<String> parseSelectedBillIds(String billId) {
        List<String> selectedBillIds = new ArrayList<>();
        Set<String> seen = new HashSet<>();
        for (String id : billId.split(",")) {
            if (StringUtils.isBlank(id)) {
                continue;
            }
            String trimmed = id.trim();
            if (seen.add(trimmed)) {
                selectedBillIds.add(trimmed);
            }
        }
        return selectedBillIds;
    }

    private Map<String, EvaResultSummaryInfo> loadSummaryByIds(Context ctx, List<String> selectedBillIds) throws Exception {
        IEvaResultSummary iEvaResultSummary = EvaResultSummaryFactory.getLocalInstance(ctx);
        FilterInfo filter = new FilterInfo();
        filter.getFilterItems().add(new FilterItemInfo("id", new HashSet<>(selectedBillIds), CompareType.INCLUDE));

        SelectorItemCollection sic = new SelectorItemCollection();
        sic.add(new SelectorItemInfo("*"));
        sic.add(new SelectorItemInfo("evaObj.*"));
        sic.add(new SelectorItemInfo("evaObj.person.*"));
        sic.add(new SelectorItemInfo("evaObj.workFlow.*"));
        sic.add(new SelectorItemInfo("period.*"));

        EntityViewInfo evi = new EntityViewInfo();
        evi.setFilter(filter);
        evi.setSelector(sic);

        EvaResultSummaryCollection coll = iEvaResultSummary.getEvaResultSummaryCollection(evi);
        Map<String, EvaResultSummaryInfo> summaryById = new HashMap<>();
        if (coll == null || coll.isEmpty()) {
            return summaryById;
        }
        for (int i = 0; i < coll.size(); i++) {
            EvaResultSummaryInfo info = coll.get(i);
            if (info != null && info.getId() != null) {
                summaryById.put(info.getId().toString(), info);
            }
        }
        return summaryById;
    }

    private Set<String> collectPeriodIds(Map<String, EvaResultSummaryInfo> summaryById) {
        Set<String> periodIds = new LinkedHashSet<>();
        for (EvaResultSummaryInfo info : summaryById.values()) {
            if (info == null || info.getPeriod() == null || info.getPeriod().getId() == null) {
                continue;
            }
            periodIds.add(info.getPeriod().getId().toString());
        }
        return periodIds;
    }

    private boolean isApproved(EvaResultSummaryInfo info) {
        if (info == null) {
            return false;
        }
        return BILL_STATE_AUDITED.equals(StringUtils.trimToEmpty(info.getString("billState")));
    }
}
