import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
import { Cron, CronExpression } from '@nestjs/schedule';
import { BurnService } from '../services/burn.service';
import { PriceService } from '../services/price.service';
import { RedisService } from '../../infrastructure/redis/redis.service';
import { TradingConfigRepository } from '../../infrastructure/persistence/repositories/trading-config.repository';

@Injectable()
export class BurnScheduler implements OnModuleInit {
  private readonly logger = new Logger(BurnScheduler.name);

  constructor(
    private readonly burnService: BurnService,
    private readonly priceService: PriceService,
    private readonly redis: RedisService,
    private readonly tradingConfigRepository: TradingConfigRepository,
  ) {}

  async onModuleInit() {
    this.logger.log('Burn scheduler initialized');

    // 初始化销毁系统
    try {
      await this.burnService.initialize();
      this.logger.log('Burn system initialized');
    } catch (error) {
      this.logger.error('Failed to initialize burn system', error);
    }
  }

  /**
   * 每分钟执行销毁并创建价格快照
   * 每分钟销毁量 = 100亿 ÷ (365×4×1440) = 4756.468797564687 进黑洞
   *
   * 注意：销毁和快照必须在同一个任务中顺序执行，
   * 确保快照总是捕获销毁后的最新价格，避免K线出现价格不变的情况
   *
   * 只有当交易系统激活时才执行销毁和快照
   */
  @Cron(CronExpression.EVERY_MINUTE)
  async executeMinuteBurnAndSnapshot(): Promise<void> {
    try {
      // 检查交易系统是否激活
      const config = await this.tradingConfigRepository.getConfig();
      if (!config || !config.isActive) {
        // 交易系统未激活，跳过销毁和快照
        return;
      }

      // 1. 先执行销毁
      const burnAmount = await this.burnService.executeMinuteBurn();
      if (!burnAmount.isZero()) {
        this.logger.debug(`Minute burn completed: ${burnAmount.toFixed(8)}`);
      }

      // 2. 销毁完成后立即创建价格快照
      await this.priceService.createSnapshot();
    } catch (error) {
      this.logger.error('Failed to execute minute burn and snapshot', error);
    }
  }

  /**
   * 每天清理旧的价格快照（保留30天）
   */
  @Cron('0 3 * * *') // 每天凌晨3点
  async cleanupOldSnapshots(): Promise<void> {
    const lockValue = await this.redis.acquireLock('snapshot:cleanup:lock', 300);
    if (!lockValue) {
      return;
    }

    try {
      // 通过 PriceService 调用 repository 清理
      this.logger.log('Starting cleanup of old price snapshots');
      // 这里可以添加清理逻辑
    } catch (error) {
      this.logger.error('Failed to cleanup old snapshots', error);
    } finally {
      await this.redis.releaseLock('snapshot:cleanup:lock', lockValue);
    }
  }

  /**
   * 每小时记录销毁状态日志（只在交易系统激活时记录）
   */
  @Cron('0 * * * *') // 每小时整点
  async logBurnStatus(): Promise<void> {
    try {
      // 检查交易系统是否激活
      const config = await this.tradingConfigRepository.getConfig();
      if (!config || !config.isActive) {
        return;
      }

      const status = await this.burnService.getBurnStatus();
      this.logger.log(
        `Burn status: burned=${status.totalBurned}, ` +
          `remaining=${status.remainingBurn}, ` +
          `progress=${status.burnProgress}%, ` +
          `minuteRate=${status.minuteBurnRate}`,
      );
    } catch (error) {
      this.logger.error('Failed to log burn status', error);
    }
  }
}
