import { DomainError } from '@/shared/exceptions/domain.exception';

/**
 * 账户序列号值对象
 * 格式: D + 年(2位) + 月(2位) + 日(2位) + 5位序号
 * 示例: D2512110008 -> 2025年12月11日的第8个注册用户
 */
export class AccountSequence {
  private static readonly PATTERN = /^D\d{11}$/;

  constructor(public readonly value: string) {
    if (!AccountSequence.PATTERN.test(value)) {
      throw new DomainError(
        `账户序列号格式无效: ${value}，应为 D + 年月日(6位) + 序号(5位)`,
      );
    }
  }

  static create(value: string): AccountSequence {
    return new AccountSequence(value);
  }

  /**
   * 根据日期和当日序号生成新的账户序列号
   * @param date 日期
   * @param dailySequence 当日序号 (0-99999)
   */
  static generate(date: Date, dailySequence: number): AccountSequence {
    if (dailySequence < 0 || dailySequence > 99999) {
      throw new DomainError(`当日序号超出范围: ${dailySequence}，应为 0-99999`);
    }
    const year = String(date.getFullYear()).slice(-2);
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const day = String(date.getDate()).padStart(2, '0');
    const seq = String(dailySequence).padStart(5, '0');
    return new AccountSequence(`D${year}${month}${day}${seq}`);
  }

  /**
   * 从序列号中提取日期字符串 (YYMMDD)
   */
  get dateString(): string {
    return this.value.slice(1, 7);
  }

  /**
   * 从序列号中提取当日序号
   */
  get dailySequence(): number {
    return parseInt(this.value.slice(7), 10);
  }

  equals(other: AccountSequence): boolean {
    return this.value === other.value;
  }

  toString(): string {
    return this.value;
  }
}
