/**
 * BookingNumber Value Object
 *
 * Represents a unique booking reference number
 * Format: WCM-YYYY-XXXXXX (e.g., WCM-2025-ABC123)
 * - WCM: WebCargo Maritime prefix
 * - YYYY: Current year
 * - XXXXXX: 6 alphanumeric characters
 */

import { InvalidBookingNumberException } from '../exceptions/invalid-booking-number.exception';

export class BookingNumber {
  private readonly _value: string;

  private constructor(value: string) {
    this._value = value;
  }

  get value(): string {
    return this._value;
  }

  /**
   * Generate a new booking number
   */
  static generate(): BookingNumber {
    const year = new Date().getFullYear();
    const random = BookingNumber.generateRandomString(6);
    const value = `WCM-${year}-${random}`;
    return new BookingNumber(value);
  }

  /**
   * Create BookingNumber from string
   */
  static fromString(value: string): BookingNumber {
    if (!BookingNumber.isValid(value)) {
      throw new InvalidBookingNumberException(value);
    }
    return new BookingNumber(value);
  }

  /**
   * Validate booking number format
   */
  static isValid(value: string): boolean {
    const pattern = /^WCM-\d{4}-[A-Z0-9]{6}$/;
    return pattern.test(value);
  }

  /**
   * Generate random alphanumeric string
   */
  private static generateRandomString(length: number): string {
    const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'; // Exclude ambiguous chars: 0,O,1,I
    let result = '';
    for (let i = 0; i < length; i++) {
      result += chars.charAt(Math.floor(Math.random() * chars.length));
    }
    return result;
  }

  /**
   * Equality check
   */
  equals(other: BookingNumber): boolean {
    return this._value === other._value;
  }

  /**
   * String representation
   */
  toString(): string {
    return this._value;
  }
}
