import { Injectable, Logger } from '@nestjs/common';
import { Cron } from '@nestjs/schedule';
import { RedisService } from '@/infrastructure/redis/redis.service';
import { PrePlantingContributionService } from '../services/pre-planting-contribution.service';

/**
 * 预种算力分配补偿调度器
 *
 * [2026-02-28] 新增：处理 CDC 后置回调失败后未分配的预种订单
 *
 * === 职责 ===
 * 每 5 分钟扫描一次 pre_planting_synced_orders 表中 status=PAID 且
 * contributionDistributed=false 的订单，重新触发算力计算。
 *
 * === 设计原则 ===
 * - CDC 后置回调失败（如 DB 迁移未就绪、网络抖动）时，订单已写入追踪表但未分配算力
 * - 本调度器作为补偿机制，确保最终一致性
 * - calculateForPrePlantingOrder 内部已做幂等检查（existsBySourceAdoptionId），重复调用安全
 */
@Injectable()
export class PrePlantingContributionScheduler {
  private readonly logger = new Logger(PrePlantingContributionScheduler.name);
  private readonly LOCK_KEY = 'pre-planting:contribution:distribute:lock';

  constructor(
    private readonly contributionService: PrePlantingContributionService,
    private readonly redis: RedisService,
  ) {}

  /**
   * 每 5 分钟处理一批未分配的预种订单
   */
  @Cron('0 */5 * * * *')
  async processUndistributedOrders(): Promise<void> {
    const lockValue = await this.redis.acquireLock(`${this.LOCK_KEY}`, 240);
    if (!lockValue) return;

    try {
      const count = await this.contributionService.processUndistributedOrders(50);
      if (count > 0) {
        this.logger.log(`[PRE-PLANTING-CONTRIBUTION] Distributed ${count} undistributed orders`);
      }
    } catch (error) {
      this.logger.error('[PRE-PLANTING-CONTRIBUTION] Failed to process undistributed orders', error);
    } finally {
      await this.redis.releaseLock(`${this.LOCK_KEY}`, lockValue);
    }
  }
}
