import { Injectable } from "@nestjs/common";
import { ORDER_FULFILLMENT_ERROR_CODE } from "@customer-portal/domain/orders";
import type { OrderFulfillmentErrorCode } from "@customer-portal/domain/orders";

/**
 * Centralized error code determination and error handling for order fulfillment
 * Eliminates duplicate error code logic across services
 *
 * Note: Error codes are now defined in @customer-portal/domain/orders as business constants
 */
@Injectable()
export class OrderFulfillmentErrorService {
  /**
   * Determine error code from error object or message
   */
  determineErrorCode(error: unknown): OrderFulfillmentErrorCode {
    const errorMessage = this.getErrorMessage(error);

    if (errorMessage.includes("Payment method missing")) {
      return ORDER_FULFILLMENT_ERROR_CODE.PAYMENT_METHOD_MISSING;
    }
    if (errorMessage.includes("not found")) {
      return ORDER_FULFILLMENT_ERROR_CODE.ORDER_NOT_FOUND;
    }
    if (errorMessage.includes("WHMCS")) {
      return ORDER_FULFILLMENT_ERROR_CODE.WHMCS_ERROR;
    }
    if (errorMessage.includes("mapping")) {
      return ORDER_FULFILLMENT_ERROR_CODE.MAPPING_ERROR;
    }
    if (errorMessage.includes("validation") || errorMessage.includes("Invalid")) {
      return ORDER_FULFILLMENT_ERROR_CODE.VALIDATION_ERROR;
    }
    if (errorMessage.includes("Salesforce") || errorMessage.includes("SF")) {
      return ORDER_FULFILLMENT_ERROR_CODE.SALESFORCE_ERROR;
    }

    return ORDER_FULFILLMENT_ERROR_CODE.PROVISIONING_ERROR;
  }

  /**
   * Get user-friendly error message for external consumption
   * Ensures no sensitive information is exposed
   */
  getUserFriendlyMessage(error: unknown, errorCode: OrderFulfillmentErrorCode): string {
    switch (errorCode) {
      case ORDER_FULFILLMENT_ERROR_CODE.PAYMENT_METHOD_MISSING:
        return "Payment method missing - please add a payment method before fulfillment";
      case ORDER_FULFILLMENT_ERROR_CODE.ORDER_NOT_FOUND:
        return "Order not found or cannot be fulfilled";
      case ORDER_FULFILLMENT_ERROR_CODE.WHMCS_ERROR:
        return "Billing system error - please try again later";
      case ORDER_FULFILLMENT_ERROR_CODE.MAPPING_ERROR:
        return "Order configuration error - please contact support";
      case ORDER_FULFILLMENT_ERROR_CODE.VALIDATION_ERROR:
        return "Invalid order data - please verify order details";
      case ORDER_FULFILLMENT_ERROR_CODE.SALESFORCE_ERROR:
        return "CRM system error - please try again later";
      default:
        return "Order fulfillment failed - please contact support";
    }
  }

  /**
   * Extract error message from various error types
   */
  private getErrorMessage(error: unknown): string {
    if (error instanceof Error) {
      return error.message;
    }
    if (typeof error === "string") {
      return error;
    }
    return String(error);
  }

  /**
   * Create standardized error response
   */
  createErrorResponse(error: unknown) {
    const errorCode = this.determineErrorCode(error);
    const userMessage = this.getUserFriendlyMessage(error, errorCode);

    return {
      success: false,
      status: "Failed" as const,
      message: userMessage,
      errorCode: errorCode,
    };
  }

  /**
   * Extract a short error code for diagnostics (e.g., 429, 503, ETIMEOUT)
   */
  getShortCode(error: unknown): string | undefined {
    const msg = this.getErrorMessage(error);
    const m = msg.match(/HTTP\s+(\d{3})/i);
    if (m) return m[1];
    if (/timeout/i.test(msg)) return "ETIMEOUT";
    if (/network/i.test(msg)) return "ENETWORK";
    return undefined;
  }
}
