package com.mosquito.project.permission;

import com.mosquito.project.permission.SysApprovalRecord;
import com.mosquito.project.permission.ApprovalRecordRepository;
import com.mosquito.project.permission.ApprovalFlowRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 审批超时处理定时任务
 * TASK-317: 审批超时检测
 * TASK-318: 超时提醒通知
 * TASK-319: 超时自动升级
 */
@Component
public class ApprovalTimeoutJob {

    private static final Logger log = LoggerFactory.getLogger(ApprovalTimeoutJob.class);

    private final ApprovalRecordRepository recordRepository;
    private final ApprovalFlowRepository flowRepository;
    private final ApprovalFlowService approvalFlowService;

    public ApprovalTimeoutJob(
            ApprovalRecordRepository recordRepository,
            ApprovalFlowRepository flowRepository,
            ApprovalFlowService approvalFlowService) {
        this.recordRepository = recordRepository;
        this.flowRepository = flowRepository;
        this.approvalFlowService = approvalFlowService;
    }

    /**
     * 每小时执行一次审批超时检测
     * TASK-317: 审批超时检测
     */
    @Scheduled(fixedRate = 3600000) // 每小时执行一次
    @Transactional
    public void checkApprovalTimeout() {
        log.info("开始执行审批超时检测任务");

        List<SysApprovalRecord> processingRecords = recordRepository.findByStatus("PROCESSING");

        for (SysApprovalRecord record : processingRecords) {
            try {
                processTimeoutRecord(record);
            } catch (Exception e) {
                log.error("处理审批超时记录失败, recordId: {}", record.getId(), e);
            }
        }

        log.info("审批超时检测任务执行完成, 共处理 {} 条记录", processingRecords.size());
    }

    /**
     * 处理超时记录
     * TASK-318: 超时提醒通知
     * TASK-319: 超时自动升级
     */
    private void processTimeoutRecord(SysApprovalRecord record) {
        // 获取流程配置
        var flowOpt = flowRepository.findById(record.getFlowId());
        if (flowOpt.isEmpty()) {
            log.warn("审批记录 {} 对应的流程配置不存在", record.getId());
            return;
        }

        var flow = flowOpt.get();
        Integer timeoutHours = flow.getTimeoutHours();
        if (timeoutHours == null || timeoutHours <= 0) {
            timeoutHours = 24; // 默认24小时
        }

        LocalDateTime createdAt = record.getCreatedAt();
        if (createdAt == null) {
            createdAt = LocalDateTime.now();
        }

        LocalDateTime deadline = createdAt.plusHours(timeoutHours);
        LocalDateTime now = LocalDateTime.now();

        // 检查是否超时
        if (now.isAfter(deadline)) {
            handleTimeout(record, flow, timeoutHours);
        } else {
            // 检查是否接近超时（提前1小时提醒）
            LocalDateTime warningTime = deadline.minusHours(1);
            if (now.isAfter(warningTime)) {
                sendTimeoutWarning(record, flow, timeoutHours);
            }
        }
    }

    /**
     * 处理超时 - 自动升级或通知
     * TASK-319: 超时自动升级
     */
    private void handleTimeout(SysApprovalRecord record, com.mosquito.project.permission.SysApprovalFlow flow, int timeoutHours) {
        String timeoutAction = flow.getTimeoutAction();
        if (timeoutAction == null) {
            timeoutAction = "ESCALATE";
        }

        log.info("审批记录 {} 已超时 {} 小时，执行动作: {}",
                record.getId(), timeoutHours, timeoutAction);

        switch (timeoutAction) {
            case "ESCALATE":
                // 自动升级到上级审批人
                escalateApproval(record);
                break;
            case "AUTO_APPROVE":
                // 自动通过（适用于某些场景）
                autoApprove(record);
                break;
            case "NOTIFY":
                // 发送超时通知
                notifyTimeout(record);
                break;
            case "REJECT":
                // 自动拒绝
                autoReject(record);
                break;
            default:
                log.warn("未知的超时处理动作: {}", timeoutAction);
        }
    }

    /**
     * 升级审批到上级
     */
    private void escalateApproval(SysApprovalRecord record) {
        try {
            // 获取下一个审批人并转交
            Long currentApproverId = record.getCurrentApproverId();
            if (currentApproverId != null) {
                // TODO: 查找上级审批人
                // 这里需要集成UserService或DepartmentService来获取上级
                log.info("审批记录 {} 将升级到上级审批人", record.getId());
            }
        } catch (Exception e) {
            log.error("升级审批失败, recordId: {}", record.getId(), e);
        }
    }

    /**
     * 自动通过审批
     */
    private void autoApprove(SysApprovalRecord record) {
        try {
            // 只有特定流程可以自动通过
            log.info("审批记录 {} 自动通过", record.getId());
            // 这里可以调用approvalFlowService
        } catch (Exception e) {
            log.error("自动通过审批失败, recordId: {}", record.getId(), e);
        }
    }

    /**
     * 发送超时通知
     */
    private void notifyTimeout(SysApprovalRecord record) {
        // TODO: 集成通知服务发送超时提醒
        log.info("发送审批超时通知, recordId: {}, applicantId: {}",
                record.getId(), record.getApplicantId());
    }

    /**
     * 自动拒绝
     */
    private void autoReject(SysApprovalRecord record) {
        try {
            log.info("审批记录 {} 因超时被自动拒绝", record.getId());
            // 这里可以调用approvalFlowService
        } catch (Exception e) {
            log.error("自动拒绝审批失败, recordId: {}", record.getId(), e);
        }
    }

    /**
     * 发送超时预警通知
     * TASK-318: 超时提醒通知
     */
    private void sendTimeoutWarning(SysApprovalRecord record, com.mosquito.project.permission.SysApprovalFlow flow, int timeoutHours) {
        // TODO: 集成通知服务发送超时预警
        log.info("发送审批超时预警, recordId: {}, 预计 {} 小时后将超时",
                record.getId(), timeoutHours);
    }

    /**
     * 手动触发超时检测（用于测试或管理）
     */
    public void manualCheckTimeout() {
        checkApprovalTimeout();
    }
}
