import { DomainValidationError, ValueObject } from "@repo/rdx-ddd";
import { Result } from "@repo/rdx-utils";

interface ICustomerStatusProps {
  value: string;
}

export enum CUSTOMER_STATUS {
  ACTIVE = "active",
  INACTIVE = "inactive",
}
export class CustomerStatus extends ValueObject<ICustomerStatusProps> {
  private static readonly ALLOWED_STATUSES = ["active", "inactive"];
  private static readonly FIELD = "status";
  private static readonly ERROR_CODE = "INVALID_STATUS";

  private static readonly TRANSITIONS: Record<string, string[]> = {
    active: [CUSTOMER_STATUS.INACTIVE],
    inactive: [CUSTOMER_STATUS.ACTIVE],
  };

  static create(value: string): Result<CustomerStatus, Error> {
    if (!CustomerStatus.ALLOWED_STATUSES.includes(value)) {
      const detail = `Status value not valid: ${value}`;
      return Result.fail(
        new DomainValidationError(CustomerStatus.ERROR_CODE, CustomerStatus.FIELD, detail)
      );
    }

    return Result.ok(
      value === "active" ? CustomerStatus.createActive() : CustomerStatus.createInactive()
    );
  }

  public static createActive(): CustomerStatus {
    return new CustomerStatus({ value: CUSTOMER_STATUS.ACTIVE });
  }

  public static createInactive(): CustomerStatus {
    return new CustomerStatus({ value: CUSTOMER_STATUS.INACTIVE });
  }

  isActive(): boolean {
    return this.props.value === CUSTOMER_STATUS.ACTIVE;
  }

  getProps(): string {
    return this.props.value;
  }

  toPrimitive() {
    return this.getProps();
  }

  toString() {
    return String(this.props.value);
  }

  canTransitionTo(nextStatus: string): boolean {
    return CustomerStatus.TRANSITIONS[this.props.value].includes(nextStatus);
  }

  transitionTo(nextStatus: string): Result<CustomerStatus, Error> {
    if (!this.canTransitionTo(nextStatus)) {
      return Result.fail(
        new Error(`Transition not allowed from ${this.props.value} to ${nextStatus}`)
      );
    }
    return CustomerStatus.create(nextStatus);
  }
}
