import { HttpStatus } from "@nestjs/common";
import {
  ErrorCode,
  type ErrorCodeType,
  WhmcsProviderError,
  type WhmcsProviderErrorCode,
} from "@customer-portal/domain/common";
import { BaseProviderError } from "./base-provider.error.js";

export class WhmcsApiError extends BaseProviderError {
  readonly provider = "whmcs" as const;
  readonly providerCode = WhmcsProviderError.API_ERROR;
  readonly domainErrorCode = ErrorCode.EXTERNAL_SERVICE_ERROR;
  readonly httpStatus = HttpStatus.BAD_GATEWAY;

  constructor(message: string, providerMessage: string, cause?: unknown) {
    super(message, providerMessage, cause);
  }
}

export class WhmcsNotFoundError extends BaseProviderError {
  readonly provider = "whmcs" as const;
  readonly providerCode: WhmcsProviderErrorCode;
  readonly domainErrorCode = ErrorCode.NOT_FOUND;
  readonly httpStatus = HttpStatus.NOT_FOUND;

  constructor(
    resource: "client" | "invoice" | "product",
    providerMessage: string,
    cause?: unknown
  ) {
    super(`WHMCS ${resource} not found`, providerMessage, cause);
    const codeMap = {
      client: WhmcsProviderError.CLIENT_NOT_FOUND,
      invoice: WhmcsProviderError.INVOICE_NOT_FOUND,
      product: WhmcsProviderError.PRODUCT_NOT_FOUND,
    } as const;
    this.providerCode = codeMap[resource];
  }
}

export class WhmcsAuthError extends BaseProviderError {
  readonly provider = "whmcs" as const;
  readonly providerCode = WhmcsProviderError.AUTH_FAILED;
  readonly domainErrorCode = ErrorCode.EXTERNAL_SERVICE_ERROR;
  readonly httpStatus = HttpStatus.SERVICE_UNAVAILABLE;

  constructor(providerMessage: string, cause?: unknown) {
    super("WHMCS authentication failed", providerMessage, cause);
  }
}

export class WhmcsInvalidCredentialsError extends BaseProviderError {
  readonly provider = "whmcs" as const;
  readonly providerCode = WhmcsProviderError.INVALID_CREDENTIALS;
  readonly domainErrorCode = ErrorCode.INVALID_CREDENTIALS;
  readonly httpStatus = HttpStatus.UNAUTHORIZED;

  constructor(providerMessage: string, cause?: unknown) {
    super("Invalid login credentials", providerMessage, cause);
  }
}

export class WhmcsValidationError extends BaseProviderError {
  readonly provider = "whmcs" as const;
  readonly providerCode = WhmcsProviderError.VALIDATION_ERROR;
  readonly domainErrorCode = ErrorCode.VALIDATION_FAILED;
  readonly httpStatus = HttpStatus.BAD_REQUEST;

  constructor(providerMessage: string, cause?: unknown) {
    super("WHMCS validation failed", providerMessage, cause);
  }
}

export class WhmcsTimeoutError extends BaseProviderError {
  readonly provider = "whmcs" as const;
  readonly providerCode = WhmcsProviderError.TIMEOUT;
  readonly domainErrorCode = ErrorCode.TIMEOUT;
  readonly httpStatus = HttpStatus.GATEWAY_TIMEOUT;

  constructor(providerMessage: string, cause?: unknown) {
    super("WHMCS request timed out", providerMessage, cause);
  }
}

export class WhmcsNetworkError extends BaseProviderError {
  readonly provider = "whmcs" as const;
  readonly providerCode = WhmcsProviderError.NETWORK_ERROR;
  readonly domainErrorCode = ErrorCode.NETWORK_ERROR;
  readonly httpStatus = HttpStatus.BAD_GATEWAY;

  constructor(providerMessage: string, cause?: unknown) {
    super("WHMCS network error", providerMessage, cause);
  }
}

export class WhmcsRateLimitError extends BaseProviderError {
  readonly provider = "whmcs" as const;
  readonly providerCode = WhmcsProviderError.RATE_LIMITED;
  readonly domainErrorCode = ErrorCode.RATE_LIMITED;
  readonly httpStatus = HttpStatus.TOO_MANY_REQUESTS;

  constructor(providerMessage: string, cause?: unknown) {
    super("WHMCS rate limit exceeded", providerMessage, cause);
  }
}

export class WhmcsHttpError extends BaseProviderError {
  readonly provider = "whmcs" as const;
  readonly providerCode = WhmcsProviderError.HTTP_ERROR;
  readonly domainErrorCode: ErrorCodeType;
  readonly httpStatus: HttpStatus;

  constructor(
    upstreamStatus: number,
    providerMessage: string,
    domainErrorCode: ErrorCodeType,
    httpStatus: HttpStatus,
    cause?: unknown
  ) {
    super(`WHMCS HTTP ${upstreamStatus} error`, providerMessage, cause);
    this.domainErrorCode = domainErrorCode;
    this.httpStatus = httpStatus;
  }
}
