import { Injectable } from '@nestjs/common';
import { PrismaService } from '../../../infrastructure/persistence/prisma/prisma.service';
import { PrePlantingPrismaService } from '../../infrastructure/prisma/pre-planting-prisma.service';

/**
 * 预种卖出限制服务
 *
 * [2026-03-04] 新增：限制仅有预种份数（未合并成棵）的用户卖出积分股，
 * 直到用户完成"首次预种合并"（将份数合并成整棵树）为止。
 *
 * === 判断逻辑 ===
 * isRestricted = has_pre_planting_marker AND !has_real_tree AND !admin_override
 *
 * - has_pre_planting_marker：synced_adoptions.distribution_summary = 'PRE_PLANTING_MARKER'
 * - has_real_tree：
 *   正常认种：original_adoption_id < 10_000_000_000 AND status = 'MINING_ENABLED' AND tree_count > 0
 *   合并树：  original_adoption_id >= 20_000_000_000 AND tree_count > 0
 * - admin_override：pre_planting_sell_restriction_overrides 表中存在该账户记录
 *
 * === 注意 ===
 * - 本服务使用两个 Prisma 实例：
 *   PrismaService（主 schema）：查询 synced_adoptions 判断预种和真实树状态
 *   PrePlantingPrismaService（预种 schema）：查询/写入 override 表
 */
@Injectable()
export class SellRestrictionService {
  // 10B 偏移：pre-planting 份额的 originalAdoptionId
  private static readonly PRE_PLANTING_OFFSET = 10_000_000_000n;
  // 20B 偏移：合并树的 originalAdoptionId
  private static readonly MERGE_OFFSET = 20_000_000_000n;
  // 预种标记字符串
  private static readonly PRE_PLANTING_MARKER = 'PRE_PLANTING_MARKER';

  constructor(
    private readonly prisma: PrismaService,
    private readonly prePlantingPrisma: PrePlantingPrismaService,
  ) {}

  /**
   * 判断账户是否受预种卖出限制
   *
   * @returns true = 限制卖出；false = 允许卖出
   */
  async isRestricted(accountSequence: string): Promise<boolean> {
    // 1. 管理员手动解除？
    const override = await this.prePlantingPrisma.prePlantingSellRestrictionOverride.findUnique({
      where: { accountSequence },
    });
    if (override) return false;

    // 2. 有预种标记？（预种份额写入 synced_adoptions 时设置此标记）
    const marker = await this.prisma.syncedAdoption.findFirst({
      where: {
        accountSequence,
        distributionSummary: SellRestrictionService.PRE_PLANTING_MARKER,
      },
      select: { id: true },
    });
    if (!marker) return false; // 没有预种，不限制

    // 3. 有真实树？（正常认种 或 合并树）
    const realTree = await this.prisma.syncedAdoption.findFirst({
      where: {
        accountSequence,
        treeCount: { gt: 0 },
        OR: [
          // 正常认种（originalAdoptionId < 10B），状态为挖矿启用
          {
            originalAdoptionId: { lt: SellRestrictionService.PRE_PLANTING_OFFSET },
            status: 'MINING_ENABLED',
          },
          // 合并树（originalAdoptionId >= 20B，来自 pre-planting-merge-synced.handler）
          {
            originalAdoptionId: { gte: SellRestrictionService.MERGE_OFFSET },
          },
        ],
      },
      select: { id: true },
    });

    return !realTree; // 无真实树 = 受限
  }

  /**
   * 管理员手动解除卖出限制
   *
   * 使用 upsert 保证幂等性：重复解除只更新记录，不报错。
   */
  async createOverride(accountSequence: string, unlockedBy: string, reason?: string): Promise<void> {
    await this.prePlantingPrisma.prePlantingSellRestrictionOverride.upsert({
      where: { accountSequence },
      create: { accountSequence, unlockedBy, reason },
      update: { unlockedBy, reason },
    });
  }
}
