package cn.iocoder.yudao.module.asset.job;

import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
import cn.iocoder.yudao.module.asset.dal.dataobject.contract.ContractDO;
import cn.iocoder.yudao.module.asset.dal.mysql.contract.ContractMapper;
import cn.iocoder.yudao.module.asset.enums.contract.ContractStatusEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import jakarta.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 合同状态自动流转定时任务
 *
 * 功能：
 * 1. 将待生效的合同自动转为进行中（当前日期 >= 生效日期）
 * 2. 将进行中的合同自动转为已到期（当前日期 > 结束日期）
 *
 * @author 芋道源码
 */
@Component
@Slf4j
public class ContractStatusJob {

    @Resource
    private ContractMapper contractMapper;

    @XxlJob("contractStatusJob")
    @TenantJob
    public void execute() {
        log.info("[contractStatusJob] 开始执行合同状态自动流转");

        try {
            // 1. 处理待生效 -> 进行中
            int activatedCount = activatePendingContracts();
            log.info("[contractStatusJob] 激活待生效合同数量: {}", activatedCount);

            // 2. 处理进行中 -> 已到期
            int expiredCount = expireActiveContracts();
            log.info("[contractStatusJob] 到期合同数量: {}", expiredCount);

            log.info("[contractStatusJob] 执行完成，激活: {}, 到期: {}", activatedCount, expiredCount);
        } catch (Exception e) {
            log.error("[contractStatusJob] 执行失败", e);
        }
    }

    /**
     * 激活待生效的合同
     */
    private int activatePendingContracts() {
        LocalDate today = LocalDate.now();

        // 查询待生效且生效日期 <= 今天的合同
        List<ContractDO> contracts = contractMapper.selectList(
                new LambdaQueryWrapper<ContractDO>()
                        .eq(ContractDO::getContractStatus, ContractStatusEnum.PENDING.getStatus())
                        .le(ContractDO::getStartDate, today)
        );

        int count = 0;
        for (ContractDO contract : contracts) {
            ContractDO updateObj = new ContractDO();
            updateObj.setId(contract.getId());
            updateObj.setContractStatus(ContractStatusEnum.IN_PROGRESS.getStatus());
            updateObj.setEffectiveTime(LocalDateTime.now());
            contractMapper.updateById(updateObj);
            count++;
            log.info("[contractStatusJob] 合同 {} 已激活", contract.getContractCode());
        }

        return count;
    }

    /**
     * 将进行中的合同标记为已到期
     */
    private int expireActiveContracts() {
        LocalDate today = LocalDate.now();

        // 查询进行中且结束日期 < 今天的合同
        List<ContractDO> contracts = contractMapper.selectList(
                new LambdaQueryWrapper<ContractDO>()
                        .eq(ContractDO::getContractStatus, ContractStatusEnum.IN_PROGRESS.getStatus())
                        .lt(ContractDO::getEndDate, today)
        );

        int count = 0;
        for (ContractDO contract : contracts) {
            ContractDO updateObj = new ContractDO();
            updateObj.setId(contract.getId());
            updateObj.setContractStatus(ContractStatusEnum.EXPIRED.getStatus());
            contractMapper.updateById(updateObj);
            count++;
            log.info("[contractStatusJob] 合同 {} 已到期", contract.getContractCode());
        }

        return count;
    }

}
