import { PRE_PLANTING_PORTIONS_PER_TREE } from '../value-objects/pre-planting-right-amounts';

export interface PrePlantingPositionData {
  id?: bigint;
  userId: bigint;
  accountSequence: string;
  totalPortions: number;
  availablePortions: number;
  mergedPortions: number;
  totalTreesMerged: number;
  provinceCode?: string | null;
  provinceName?: string | null;
  cityCode?: string | null;
  cityName?: string | null;
  firstPurchaseAt?: Date | null;
  createdAt?: Date;
}

export class PrePlantingPosition {
  private _id: bigint | null;
  private readonly _userId: bigint;
  private readonly _accountSequence: string;
  private _totalPortions: number;
  private _availablePortions: number;
  private _mergedPortions: number;
  private _totalTreesMerged: number;
  private _provinceCode: string | null;
  private _provinceName: string | null;
  private _cityCode: string | null;
  private _cityName: string | null;
  private _firstPurchaseAt: Date | null;
  private readonly _createdAt: Date;

  private constructor(userId: bigint, accountSequence: string, createdAt?: Date) {
    this._id = null;
    this._userId = userId;
    this._accountSequence = accountSequence;
    this._totalPortions = 0;
    this._availablePortions = 0;
    this._mergedPortions = 0;
    this._totalTreesMerged = 0;
    this._provinceCode = null;
    this._provinceName = null;
    this._cityCode = null;
    this._cityName = null;
    this._firstPurchaseAt = null;
    this._createdAt = createdAt || new Date();
  }

  static create(userId: bigint, accountSequence: string): PrePlantingPosition {
    return new PrePlantingPosition(userId, accountSequence);
  }

  static reconstitute(data: PrePlantingPositionData): PrePlantingPosition {
    const position = new PrePlantingPosition(data.userId, data.accountSequence, data.createdAt);
    position._id = data.id || null;
    position._totalPortions = data.totalPortions;
    position._availablePortions = data.availablePortions;
    position._mergedPortions = data.mergedPortions;
    position._totalTreesMerged = data.totalTreesMerged;
    position._provinceCode = data.provinceCode || null;
    position._provinceName = data.provinceName || null;
    position._cityCode = data.cityCode || null;
    position._cityName = data.cityName || null;
    position._firstPurchaseAt = data.firstPurchaseAt || null;
    return position;
  }

  /**
   * 增加购买份数
   */
  addPortions(count: number, provinceCode: string, cityCode: string, provinceName?: string, cityName?: string): void {
    this._totalPortions += count;
    this._availablePortions += count;

    // 首次购买设置省市和时间
    if (!this._firstPurchaseAt) {
      this._firstPurchaseAt = new Date();
      this._provinceCode = provinceCode;
      this._cityCode = cityCode;
      this._provinceName = provinceName || null;
      this._cityName = cityName || null;
    }
  }

  /**
   * 是否可以触发合并
   */
  canMerge(): boolean {
    return this._availablePortions >= PRE_PLANTING_PORTIONS_PER_TREE;
  }

  /**
   * 执行合并（消耗 PRE_PLANTING_PORTIONS_PER_TREE 份）
   */
  performMerge(): void {
    if (!this.canMerge()) {
      throw new Error(`可用份数不足 ${PRE_PLANTING_PORTIONS_PER_TREE}，当前: ${this._availablePortions}`);
    }
    this._availablePortions -= PRE_PLANTING_PORTIONS_PER_TREE;
    this._mergedPortions += PRE_PLANTING_PORTIONS_PER_TREE;
    this._totalTreesMerged += 1;
  }

  /**
   * 计算续购时还可以购买的最大份数（关闭开关时使用）
   */
  maxAdditionalPortionsToMerge(): number {
    const remainder = this._availablePortions % PRE_PLANTING_PORTIONS_PER_TREE;
    if (remainder === 0) return 0;
    return PRE_PLANTING_PORTIONS_PER_TREE - remainder;
  }

  setId(id: bigint): void {
    this._id = id;
  }

  get id(): bigint | null { return this._id; }
  get userId(): bigint { return this._userId; }
  get accountSequence(): string { return this._accountSequence; }
  get totalPortions(): number { return this._totalPortions; }
  get availablePortions(): number { return this._availablePortions; }
  get mergedPortions(): number { return this._mergedPortions; }
  get totalTreesMerged(): number { return this._totalTreesMerged; }
  get provinceCode(): string | null { return this._provinceCode; }
  get provinceName(): string | null { return this._provinceName; }
  get cityCode(): string | null { return this._cityCode; }
  get cityName(): string | null { return this._cityName; }
  get firstPurchaseAt(): Date | null { return this._firstPurchaseAt; }
  get createdAt(): Date { return this._createdAt; }

  toPersistence(): PrePlantingPositionData {
    return {
      id: this._id || undefined,
      userId: this._userId,
      accountSequence: this._accountSequence,
      totalPortions: this._totalPortions,
      availablePortions: this._availablePortions,
      mergedPortions: this._mergedPortions,
      totalTreesMerged: this._totalTreesMerged,
      provinceCode: this._provinceCode,
      provinceName: this._provinceName,
      cityCode: this._cityCode,
      cityName: this._cityName,
      firstPurchaseAt: this._firstPurchaseAt,
      createdAt: this._createdAt,
    };
  }
}
