import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
import { Cron } from '@nestjs/schedule';
import { ConfigService } from '@nestjs/config';
import { C2cOrderRepository } from '../../infrastructure/persistence/repositories/c2c-order.repository';
import { C2cBotService } from '../services/c2c-bot.service';
import { RedisService } from '../../infrastructure/redis/redis.service';

/**
 * C2C Bot 定时任务
 * 定期扫描待处理的卖单并自动购买
 */
@Injectable()
export class C2cBotScheduler implements OnModuleInit {
  private readonly logger = new Logger(C2cBotScheduler.name);
  private readonly LOCK_KEY = 'c2c:bot:scheduler:lock';
  static readonly ENABLED_KEY = 'c2c:bot:enabled';

  constructor(
    private readonly c2cOrderRepository: C2cOrderRepository,
    private readonly c2cBotService: C2cBotService,
    private readonly redis: RedisService,
    private readonly configService: ConfigService,
  ) {}

  async onModuleInit() {
    // 如果 Redis 中没有设置，用环境变量初始化
    const existing = await this.redis.get(C2cBotScheduler.ENABLED_KEY);
    if (existing === null) {
      const envEnabled = this.configService.get<string>('C2C_BOT_ENABLED', 'false');
      await this.redis.set(C2cBotScheduler.ENABLED_KEY, envEnabled === 'true' ? 'true' : 'false');
    }

    const enabled = await this.isEnabled();
    this.logger.log(`C2C Bot Scheduler initialized, enabled: ${enabled}`);

    if (enabled) {
      const isAvailable = await this.c2cBotService.isAvailable();
      if (isAvailable) {
        const balance = await this.c2cBotService.getHotWalletBalance();
        this.logger.log(`Hot wallet balance: ${balance} dUSDT`);
      } else {
        this.logger.warn('Mining blockchain service not available, Bot will not process orders');
      }
    }
  }

  /**
   * 检查 Bot 是否启用（读 Redis，回退到环境变量）
   */
  async isEnabled(): Promise<boolean> {
    const value = await this.redis.get(C2cBotScheduler.ENABLED_KEY);
    if (value === null) {
      return this.configService.get<string>('C2C_BOT_ENABLED', 'false') === 'true';
    }
    return value === 'true';
  }

  /**
   * 每10秒扫描待处理的卖单
   */
  @Cron('*/10 * * * * *')
  async processPendingSellOrders(): Promise<void> {
    if (!(await this.isEnabled())) {
      return;
    }

    const lockValue = await this.redis.acquireLock(this.LOCK_KEY, 30); // 30秒锁（留足链上转账时间）
    if (!lockValue) {
      return; // 其他实例正在处理
    }

    try {
      // 每个周期只处理1个订单，确保顺序执行
      const orders = await this.c2cOrderRepository.findPendingSellOrdersForBot(1);

      if (orders.length === 0) {
        return;
      }

      const order = orders[0];
      this.logger.log(`[SCHEDULER] Processing order ${order.orderNo} (amount: ${order.totalAmount})`);

      try {
        const success = await this.c2cBotService.purchaseOrder(order);
        this.logger.log(`[SCHEDULER] Order ${order.orderNo}: ${success ? 'success' : 'failed'}`);
      } catch (error: any) {
        this.logger.error(`[SCHEDULER] Error processing order ${order.orderNo}: ${error.message}`);
      }
    } catch (error: any) {
      this.logger.error(`[SCHEDULER] Error in processPendingSellOrders: ${error.message}`);
    } finally {
      await this.redis.releaseLock(this.LOCK_KEY, lockValue);
    }
  }

  /**
   * 每分钟检查热钱包余额
   */
  @Cron('0 * * * * *')
  async checkHotWalletBalance(): Promise<void> {
    if (!(await this.isEnabled())) {
      return;
    }

    try {
      const balance = await this.c2cBotService.getHotWalletBalance();
      if (balance) {
        // 如果余额低于阈值，记录警告
        const threshold = this.configService.get<number>('C2C_BOT_BALANCE_THRESHOLD', 1000);
        const balanceNum = parseFloat(balance);

        if (balanceNum < threshold) {
          this.logger.warn(`[SCHEDULER] Hot wallet balance (${balance}) is below threshold (${threshold})`);
        }
      }
    } catch (error: any) {
      this.logger.error(`[SCHEDULER] Error checking hot wallet balance: ${error.message}`);
    }
  }
}
