package com.srs.flowable.listener.disciplinary; // 您可以根据需要调整包路径

import com.srs.comprehensive.domain.CphMsg;
import com.srs.comprehensive.service.ICphMsgService;
import lombok.extern.slf4j.Slf4j;
import org.flowable.task.service.delegate.DelegateTask;
import org.flowable.task.service.delegate.TaskListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import javax.annotation.PostConstruct;
import java.util.List;

/**
 * 【任务监听器】在任务完成后，删除内部消息。 知无涯
 * <p>
 * 该监听器被设计为在UserTask的'complete'事件上触发。
 * 它通过解析消息内容中的隐藏HTML标识来找到与当前已完成任务关联的消息，
 * 并将其删除。
 * </p>
 */
@Component("messageProcessorListener") // 定义一个清晰的Bean名称
@Slf4j
public class MessageProcessorListener implements TaskListener {

    @Autowired
    private ICphMsgService cphMsgService;

    /**
     * 依赖检查方法，确保关键服务已注入。
     */
    @PostConstruct
    public void checkDependencies() {
        Assert.notNull(cphMsgService, "ICphMsgService dependency not injected for MessageProcessorListener!");
    }

    @Override
    public void notify(DelegateTask delegateTask) {
        // 步骤 1: 获取当前任务的办理人ID
        String assigneeIdStr = delegateTask.getAssignee();
        if (assigneeIdStr == null || assigneeIdStr.isEmpty()) {
            log.warn("任务 [ID: {}] 没有办理人，无法处理消息。", delegateTask.getId());
            return;
        }
        Long receiverId;
        try {
            receiverId = Long.parseLong(assigneeIdStr);
        } catch (NumberFormatException e) {
            log.error("任务办理人ID '{}' 无法转换为Long类型。", assigneeIdStr);
            return;
        }

        // 步骤 2: 获取用于查找消息的唯一标识
        String processInstanceId = delegateTask.getProcessInstanceId();
        // taskDefinitionKey 对应流程图中节点的ID，即我之前在 GenericMessageListener 中存入的 activityId
        String activityId = delegateTask.getTaskDefinitionKey();

        log.info("任务 [ID: {}, Name: {}] (办理人: {}) 已完成。开始查找并处理关联的内部消息...",
                delegateTask.getId(), delegateTask.getName(), receiverId);
        log.debug("用于查找的关联标识 -> ProcInst ID: [{}], Activity ID: [{}]", processInstanceId, activityId);

        try {
            // 步骤 3: 构造用于模糊查询的、唯一的标识字符串
            // 这个字符串必须与 GenericMessageListener 中生成该标识的逻辑完全一致
            String searchIdentifier = String.format("data-proc-inst-id='%s' data-activity-id='%s'",
                    processInstanceId,
                    activityId);

            // 步骤 4: 创建查询参数并调用服务
            CphMsg queryParam = new CphMsg();
            queryParam.setReceiver(receiverId);
            queryParam.setContent(searchIdentifier); // 将标识作为模糊查询的内容

            // 注意：这一步要求 CphMsgMapper.xml 中的 selectCphMsgListForFlowable 方法支持对 content 字段的 LIKE 查询
            List<CphMsg> messagesToProcess = cphMsgService.selectCphMsgListForFlowable(queryParam);

            if (messagesToProcess.isEmpty()) {
                log.info("未找到需要为用户 [{}] 处理的、与当前任务关联的消息。", receiverId);
                return;
            }

            // 步骤 5: 遍历所有找到的消息，并进行处理（删除）
            for (CphMsg msg : messagesToProcess) {
                try {
                    cphMsgService.deleteCphMsgById(msg.getId());
                    log.info("已成功删除与任务关联的消息 [ID: {}]。", msg.getId());
                } catch (Exception e) {
                    // 捕获单个消息删除失败的异常，确保不影响其他消息的处理
                    log.error("删除消息 [ID: {}] 时发生异常: {}", msg.getId(), e.getMessage(), e);
                }
            }

        } catch (Exception e) {
            // 捕获整个处理过程中的异常，确保不影响主流程的流转
            log.error("处理用户 [{}] 的内部消息时发生严重异常: {}", receiverId, e.getMessage(), e);
        }
    }
}