package com.fs.audit.chain.handler;

import com.alibaba.fastjson2.JSON;
import com.fs.audit.chain.AbstractAuditHandler;
import com.fs.audit.chain.AuditContext;
import com.fs.audit.chain.AuditResult;
import com.fs.audit.domain.Audit;
import com.fs.audit.domain.AuditFlow;
import com.fs.audit.dto.TemplateStepDTO;
import com.fs.audit.enums.AuditStatus;
import com.fs.audit.event.AuditCompletedEvent;
import com.fs.audit.event.AuditStepChangedEvent;
import com.fs.audit.mapper.AuditFlowMapper;
import com.fs.audit.mapper.AuditMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/**
 * 流程推进处理器
 * 根据审核结果推进或结束流程
 */
@Slf4j
@Component
@Order(4)
@RequiredArgsConstructor
public class FlowAdvanceHandler extends AbstractAuditHandler {

    private final AuditMapper auditMapper;
    private final AuditFlowMapper auditFlowMapper;
    private final ApplicationEventPublisher eventPublisher;

    @Override
    protected AuditResult doHandle(AuditContext context) {
        log.info("执行流程推进处理器");

        Audit audit = context.getAudit();

        if (context.isApproved()) {
            // 通过：判断是否为最后一步
            if (context.isLastStep()) {
                // 流程通过
                audit.setStatus(AuditStatus.APPROVED.getCode());
                auditMapper.updateById(audit);

                log.info("审核流程{}已完成，状态: 通过", audit.getId());

                // 发布流程完成事件
                eventPublisher.publishEvent(new AuditCompletedEvent(this, audit, true));

                return AuditResult.end("审核流程已通过");
            } else {
                // 推进到下一步
                advanceToNextStep(context);
                return AuditResult.end("已推进到下一审核步骤");
            }
        } else {
            // 驳回：流程结束
            audit.setStatus(AuditStatus.REJECTED.getCode());
            auditMapper.updateById(audit);

            log.info("审核流程{}已完成，状态: 驳回", audit.getId());

            // 发布流程完成事件
            eventPublisher.publishEvent(new AuditCompletedEvent(this, audit, false));

            return AuditResult.end("审核流程已驳回");
        }
    }

    /**
     * 推进到下一步骤
     */
    private void advanceToNextStep(AuditContext context) {
        Audit audit = context.getAudit();
        TemplateStepDTO nextStepConfig = context.getNextStepConfig();

        // 创建下一步流程记录
        AuditFlow nextFlow = new AuditFlow();
        nextFlow.setAuditId(audit.getId());
        nextFlow.setStepNumber(nextStepConfig.getStep());
        nextFlow.setStepDescription(nextStepConfig.getDescription());
        nextFlow.setAuditUserIds(JSON.toJSONString(nextStepConfig.getAuditUserIds()));
        nextFlow.setStatus(AuditStatus.PENDING.getCode());
        nextFlow.setCreateTime(LocalDateTime.now());
        nextFlow.setUpdateTime(LocalDateTime.now());
        auditFlowMapper.insert(nextFlow);

        // 更新审核实例
        audit.setCurrentStep(nextStepConfig.getStep());
        audit.setAuditUserIds(JSON.toJSONString(nextStepConfig.getAuditUserIds()));
        audit.setUpdateTime(LocalDateTime.now());
        auditMapper.updateById(audit);

        log.info("流程已推进到步骤{}: {}", nextStepConfig.getStep(), nextStepConfig.getDescription());

        // 发布步骤变更事件
        eventPublisher.publishEvent(new AuditStepChangedEvent(this, audit, nextFlow));
    }

    @Override
    public int getOrder() {
        return 4;
    }
}

