export enum OrderStatus {
  CREATED = 'CREATED',
  PENDING_PAYMENT = 'PENDING_PAYMENT',
  PAID = 'PAID',
  PROCESSING = 'PROCESSING',
  COMPLETED = 'COMPLETED',
  CANCELLED = 'CANCELLED',
  REFUNDED = 'REFUNDED',
}

export enum ServiceType {
  ASSESSMENT = 'ASSESSMENT',
  CONSULTATION = 'CONSULTATION',
  DOCUMENT_REVIEW = 'DOCUMENT_REVIEW',
}

/**
 * Order Domain Entity
 */
export class OrderEntity {
  readonly id: string;
  readonly userId: string;
  conversationId: string | null;
  readonly serviceType: ServiceType;
  serviceCategory: string | null;
  readonly amount: number;
  readonly currency: string;
  status: OrderStatus;
  paymentMethod: string | null;
  paymentId: string | null;
  paidAt: Date | null;
  completedAt: Date | null;
  metadata: Record<string, unknown> | null;
  readonly createdAt: Date;
  updatedAt: Date;

  private constructor(props: {
    id: string;
    userId: string;
    conversationId: string | null;
    serviceType: ServiceType;
    serviceCategory: string | null;
    amount: number;
    currency: string;
    status: OrderStatus;
    paymentMethod: string | null;
    paymentId: string | null;
    paidAt: Date | null;
    completedAt: Date | null;
    metadata: Record<string, unknown> | null;
    createdAt: Date;
    updatedAt: Date;
  }) {
    Object.assign(this, props);
  }

  static create(props: {
    userId: string;
    serviceType: ServiceType;
    serviceCategory?: string;
    conversationId?: string;
    amount: number;
    currency?: string;
  }): OrderEntity {
    const now = new Date();
    return new OrderEntity({
      id: crypto.randomUUID(),
      userId: props.userId,
      conversationId: props.conversationId || null,
      serviceType: props.serviceType,
      serviceCategory: props.serviceCategory || null,
      amount: props.amount,
      currency: props.currency || 'CNY',
      status: OrderStatus.CREATED,
      paymentMethod: null,
      paymentId: null,
      paidAt: null,
      completedAt: null,
      metadata: null,
      createdAt: now,
      updatedAt: now,
    });
  }

  static fromPersistence(props: {
    id: string;
    userId: string;
    conversationId: string | null;
    serviceType: string;
    serviceCategory: string | null;
    amount: number;
    currency: string;
    status: string;
    paymentMethod: string | null;
    paymentId: string | null;
    paidAt: Date | null;
    completedAt: Date | null;
    metadata: Record<string, unknown> | null;
    createdAt: Date;
    updatedAt: Date;
  }): OrderEntity {
    return new OrderEntity({
      ...props,
      serviceType: props.serviceType as ServiceType,
      status: props.status as OrderStatus,
    });
  }

  updateStatus(status: OrderStatus): void {
    this.status = status;
    this.updatedAt = new Date();

    if (status === OrderStatus.PAID) {
      this.paidAt = new Date();
    } else if (status === OrderStatus.COMPLETED) {
      this.completedAt = new Date();
    }
  }

  markAsPaid(paymentId: string, paymentMethod: string): void {
    this.status = OrderStatus.PAID;
    this.paymentId = paymentId;
    this.paymentMethod = paymentMethod;
    this.paidAt = new Date();
    this.updatedAt = new Date();
  }

  cancel(): void {
    this.status = OrderStatus.CANCELLED;
    this.updatedAt = new Date();
  }

  canBePaid(): boolean {
    return this.status === OrderStatus.CREATED || this.status === OrderStatus.PENDING_PAYMENT;
  }

  canBeCancelled(): boolean {
    return this.status !== OrderStatus.PAID && this.status !== OrderStatus.COMPLETED;
  }
}
