import { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { RedisService } from '../../infrastructure/redis/redis.service';

/**
 * 预种卖出限制检查服务（trading-service 侧）
 *
 * [2026-03-04] 新增：在卖单创建前调用 contribution-service 检查该账户是否受预种卖出限制。
 *
 * === 设计原则 ===
 * - Fail-open：contribution-service 不可用时允许卖出，保障业务连续性
 * - Redis 缓存：TTL 60 秒，减少对 contribution-service 的 HTTP 调用频率
 * - 无状态：不修改任何本地表，只做只读检查
 *
 * === 缓存 key 格式 ===
 * `sell_restriction:{accountSequence}` → '1'（受限）或 '0'（不受限）
 */
@Injectable()
export class TradingSellRestrictionService {
  private readonly logger = new Logger(TradingSellRestrictionService.name);
  private readonly contributionServiceUrl: string;
  private static readonly CACHE_TTL = 60; // 秒
  private static readonly CACHE_KEY_PREFIX = 'sell_restriction:';

  constructor(
    private readonly configService: ConfigService,
    private readonly redis: RedisService,
  ) {
    this.contributionServiceUrl = this.configService.get<string>(
      'CONTRIBUTION_SERVICE_URL',
      'http://localhost:3020',
    );
  }

  /**
   * 检查账户是否受预种卖出限制
   *
   * @returns true = 受限（禁止卖出）；false = 不受限（允许卖出）
   */
  async isRestricted(accountSequence: string): Promise<boolean> {
    const cacheKey = `${TradingSellRestrictionService.CACHE_KEY_PREFIX}${accountSequence}`;

    try {
      // 1. 先查 Redis 缓存
      const cached = await this.redis.get(cacheKey);
      if (cached !== null) {
        return cached === '1';
      }

      // 2. 调用 contribution-service
      const url = `${this.contributionServiceUrl}/api/v2/pre-planting/sell-restriction/${accountSequence}`;
      const response = await fetch(url, {
        method: 'GET',
        headers: { 'Content-Type': 'application/json' },
        signal: AbortSignal.timeout(3000), // 3 秒超时
      });

      if (!response.ok) {
        this.logger.warn(`contribution-service returned ${response.status} for ${accountSequence}, fail-open`);
        return false; // fail-open
      }

      const data = (await response.json()) as { data?: { isRestricted: boolean }; isRestricted?: boolean };
      // 兼容 TransformInterceptor 包装格式 { data: { isRestricted } } 和直接格式 { isRestricted }
      const isRestricted = data?.data?.isRestricted ?? data?.isRestricted ?? false;

      // 3. 写入 Redis 缓存
      await this.redis.set(cacheKey, isRestricted ? '1' : '0', TradingSellRestrictionService.CACHE_TTL);

      return isRestricted;
    } catch (error) {
      // Fail-open：任何异常（网络、超时等）都允许卖出
      this.logger.warn(`sell-restriction check failed for ${accountSequence}, fail-open: ${error}`);
      return false;
    }
  }

  /**
   * 主动清除某账户的卖出限制缓存
   * （合并完成后可调用此方法，使限制状态立即失效）
   */
  async invalidateCache(accountSequence: string): Promise<void> {
    const cacheKey = `${TradingSellRestrictionService.CACHE_KEY_PREFIX}${accountSequence}`;
    await this.redis.set(cacheKey, '0', 1); // TTL=1秒，相当于立即失效
  }
}
