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

import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
import cn.iocoder.yudao.module.energy.dal.dataobject.account.EnergyAccountDO;
import cn.iocoder.yudao.module.energy.dal.mysql.account.EnergyAccountMapper;
import cn.iocoder.yudao.module.energy.enums.AccountStatusEnum;
import com.xxl.job.core.handler.annotation.XxlJob;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.List;

/**
 * 账户余额预警定时任务
 *
 * 功能：
 * 1. 检查正常账户，余额低于预警阈值则更新为预警状态
 * 2. 检查正常账户，余额小于0则更新为欠费状态
 * 3. 检查预警/欠费账户，余额恢复正常则更新为正常状态
 */
@Component
@Slf4j
public class AccountWarningJob {

    @Resource
    private EnergyAccountMapper accountMapper;

    @XxlJob("accountWarningJob")
    @TenantJob
    public void execute() {
        log.info("[accountWarningJob] 开始执行账户余额预警检查");

        try {
            int warningCount = 0;
            int overdueCount = 0;
            int normalCount = 0;

            // 1. 检查正常账户，余额低于阈值则更新为预警/欠费
            List<EnergyAccountDO> normalAccounts = accountMapper.selectList(new LambdaQueryWrapperX<EnergyAccountDO>()
                    .eq(EnergyAccountDO::getAccountStatus, AccountStatusEnum.NORMAL.getStatus())
                    .isNotNull(EnergyAccountDO::getReminderThreshold));
            for (EnergyAccountDO account : normalAccounts) {
                if (account.getBalance().compareTo(BigDecimal.ZERO) < 0) {
                    updateStatus(account.getId(), AccountStatusEnum.OVERDUE.getStatus());
                    overdueCount++;
                    log.info("[accountWarningJob] 账户 {} 余额为负，更新为欠费状态", account.getId());
                } else if (account.getBalance().compareTo(account.getReminderThreshold()) < 0) {
                    updateStatus(account.getId(), AccountStatusEnum.WARNING.getStatus());
                    warningCount++;
                    log.info("[accountWarningJob] 账户 {} 余额低于预警阈值，更新为预警状态", account.getId());
                }
            }

            // 2. 检查预警/欠费账户，余额恢复则更新为正常
            List<EnergyAccountDO> abnormalAccounts = accountMapper.selectList(new LambdaQueryWrapperX<EnergyAccountDO>()
                    .in(EnergyAccountDO::getAccountStatus,
                            AccountStatusEnum.WARNING.getStatus(),
                            AccountStatusEnum.OVERDUE.getStatus())
                    .isNotNull(EnergyAccountDO::getReminderThreshold));
            for (EnergyAccountDO account : abnormalAccounts) {
                if (account.getBalance().compareTo(account.getReminderThreshold()) >= 0
                        && account.getBalance().compareTo(BigDecimal.ZERO) >= 0) {
                    updateStatus(account.getId(), AccountStatusEnum.NORMAL.getStatus());
                    normalCount++;
                    log.info("[accountWarningJob] 账户 {} 余额已恢复，更新为正常状态", account.getId());
                }
            }

            log.info("[accountWarningJob] 执行完成: 新增预警={}, 新增欠费={}, 恢复正常={}", warningCount, overdueCount, normalCount);
        } catch (Exception e) {
            log.error("[accountWarningJob] 执行失败", e);
        }
    }

    private void updateStatus(Long accountId, Integer status) {
        EnergyAccountDO update = new EnergyAccountDO();
        update.setId(accountId);
        update.setAccountStatus(status);
        accountMapper.updateById(update);
    }

}
