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

export class SalesforceApiError extends BaseProviderError {
  readonly provider = "salesforce" as const;
  readonly providerCode = SalesforceProviderError.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 SalesforceSessionExpiredError extends BaseProviderError {
  readonly provider = "salesforce" as const;
  readonly providerCode = SalesforceProviderError.SESSION_EXPIRED;
  readonly domainErrorCode = ErrorCode.EXTERNAL_SERVICE_ERROR;
  readonly httpStatus = HttpStatus.SERVICE_UNAVAILABLE;

  constructor(providerMessage: string, cause?: unknown) {
    super("Salesforce session expired", providerMessage, cause);
  }
}

export class SalesforceQueryError extends BaseProviderError {
  readonly provider = "salesforce" as const;
  readonly providerCode = SalesforceProviderError.QUERY_ERROR;
  readonly domainErrorCode = ErrorCode.EXTERNAL_SERVICE_ERROR;
  readonly httpStatus = HttpStatus.BAD_GATEWAY;

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

export class SalesforceTimeoutError extends BaseProviderError {
  readonly provider = "salesforce" as const;
  readonly providerCode = SalesforceProviderError.TIMEOUT;
  readonly domainErrorCode = ErrorCode.TIMEOUT;
  readonly httpStatus = HttpStatus.GATEWAY_TIMEOUT;

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

export class SalesforceNetworkError extends BaseProviderError {
  readonly provider = "salesforce" as const;
  readonly providerCode = SalesforceProviderError.NETWORK_ERROR;
  readonly domainErrorCode = ErrorCode.NETWORK_ERROR;
  readonly httpStatus = HttpStatus.BAD_GATEWAY;

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

export class SalesforceRateLimitError extends BaseProviderError {
  readonly provider = "salesforce" as const;
  readonly providerCode = SalesforceProviderError.RATE_LIMITED;
  readonly domainErrorCode = ErrorCode.RATE_LIMITED;
  readonly httpStatus = HttpStatus.TOO_MANY_REQUESTS;

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

export class SalesforceValidationError extends BaseProviderError {
  readonly provider = "salesforce" as const;
  readonly providerCode = SalesforceProviderError.VALIDATION_ERROR;
  readonly domainErrorCode = ErrorCode.VALIDATION_FAILED;
  readonly httpStatus = HttpStatus.BAD_REQUEST;

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

export class SalesforceDuplicateError extends BaseProviderError {
  readonly provider = "salesforce" as const;
  readonly providerCode = SalesforceProviderError.DUPLICATE_RECORD;
  readonly domainErrorCode = ErrorCode.ACCOUNT_EXISTS;
  readonly httpStatus = HttpStatus.CONFLICT;

  constructor(providerMessage: string, cause?: unknown) {
    super("Salesforce duplicate record", providerMessage, cause);
  }
}

export class SalesforceAccessError extends BaseProviderError {
  readonly provider = "salesforce" as const;
  readonly providerCode = SalesforceProviderError.ACCESS_DENIED;
  readonly domainErrorCode = ErrorCode.EXTERNAL_SERVICE_ERROR;
  readonly httpStatus = HttpStatus.FORBIDDEN;

  constructor(providerMessage: string, cause?: unknown) {
    super("Salesforce insufficient access", providerMessage, cause);
  }
}

export class SalesforceStorageLimitError extends BaseProviderError {
  readonly provider = "salesforce" as const;
  readonly providerCode = SalesforceProviderError.STORAGE_LIMIT;
  readonly domainErrorCode = ErrorCode.SERVICE_UNAVAILABLE;
  readonly httpStatus = HttpStatus.SERVICE_UNAVAILABLE;

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