/**
 * Plan Change Error Types and Utilities
 * Maps Stripe errors to bilingual user messages (English/Arabic)
 * @module lib/errors/plan-change-errors
 */

export enum PlanChangeErrorCode {
  // Validation Errors
  SAME_PLAN = "SAME_PLAN",
  INVALID_TIER = "INVALID_TIER",
  NO_ACTIVE_SUBSCRIPTION = "NO_ACTIVE_SUBSCRIPTION",
  AMOUNT_MISMATCH = "AMOUNT_MISMATCH",
  UNAUTHORIZED = "UNAUTHORIZED",

  // Stripe Payment Errors
  CARD_DECLINED = "CARD_DECLINED",
  INSUFFICIENT_FUNDS = "INSUFFICIENT_FUNDS",
  EXPIRED_CARD = "EXPIRED_CARD",
  INCORRECT_CVC = "INCORRECT_CVC",
  PROCESSING_ERROR = "PROCESSING_ERROR",

  // System Errors
  STRIPE_API_ERROR = "STRIPE_API_ERROR",
  DATABASE_ERROR = "DATABASE_ERROR",
  SUBSCRIPTION_NOT_FOUND = "SUBSCRIPTION_NOT_FOUND",
}

export interface PlanChangeError {
  code: PlanChangeErrorCode;
  message: string;
  userMessage: string;
  userMessageAr: string;
  retryable: boolean;
}

const ERROR_DEFINITIONS: Record<
  PlanChangeErrorCode,
  Omit<PlanChangeError, "code">
> = {
  // Validation Errors
  [PlanChangeErrorCode.SAME_PLAN]: {
    message: "Attempting to change to current plan",
    userMessage: "You are already on this plan.",
    userMessageAr: "أنت بالفعل على هذه الخطة.",
    retryable: false,
  },
  [PlanChangeErrorCode.INVALID_TIER]: {
    message: "Invalid tier specified",
    userMessage: "The selected plan is not available.",
    userMessageAr: "الخطة المحددة غير متاحة.",
    retryable: false,
  },
  [PlanChangeErrorCode.NO_ACTIVE_SUBSCRIPTION]: {
    message: "No active subscription found",
    userMessage: "No active subscription found. Please subscribe first.",
    userMessageAr: "لم يتم العثور على اشتراك نشط. يرجى الاشتراك أولاً.",
    retryable: false,
  },
  [PlanChangeErrorCode.AMOUNT_MISMATCH]: {
    message: "Confirmed amount does not match expected",
    userMessage: "The price has changed. Please refresh and try again.",
    userMessageAr: "تغير السعر. يرجى تحديث الصفحة والمحاولة مرة أخرى.",
    retryable: true,
  },
  [PlanChangeErrorCode.UNAUTHORIZED]: {
    message: "User not authorized",
    userMessage: "Please log in to change your plan.",
    userMessageAr: "يرجى تسجيل الدخول لتغيير خطتك.",
    retryable: false,
  },

  // Stripe Payment Errors
  [PlanChangeErrorCode.CARD_DECLINED]: {
    message: "Card was declined",
    userMessage:
      "Your card was declined. Please try a different payment method.",
    userMessageAr: "تم رفض بطاقتك. يرجى تجربة طريقة دفع مختلفة.",
    retryable: true,
  },
  [PlanChangeErrorCode.INSUFFICIENT_FUNDS]: {
    message: "Insufficient funds on card",
    userMessage: "Your card has insufficient funds. Please try another card.",
    userMessageAr: "رصيد بطاقتك غير كافٍ. يرجى تجربة بطاقة أخرى.",
    retryable: true,
  },
  [PlanChangeErrorCode.EXPIRED_CARD]: {
    message: "Card has expired",
    userMessage: "Your card has expired. Please update your payment method.",
    userMessageAr: "انتهت صلاحية بطاقتك. يرجى تحديث طريقة الدفع.",
    retryable: true,
  },
  [PlanChangeErrorCode.INCORRECT_CVC]: {
    message: "Incorrect CVC code",
    userMessage: "The security code is incorrect. Please check and try again.",
    userMessageAr: "رمز الأمان غير صحيح. يرجى التحقق والمحاولة مرة أخرى.",
    retryable: true,
  },
  [PlanChangeErrorCode.PROCESSING_ERROR]: {
    message: "Payment processing error",
    userMessage:
      "Unable to process payment. Please try again in a few minutes.",
    userMessageAr: "تعذر معالجة الدفع. يرجى المحاولة مرة أخرى بعد بضع دقائق.",
    retryable: true,
  },

  // System Errors
  [PlanChangeErrorCode.STRIPE_API_ERROR]: {
    message: "Stripe API error",
    userMessage:
      "Payment service temporarily unavailable. Please try again later.",
    userMessageAr: "خدمة الدفع غير متاحة مؤقتاً. يرجى المحاولة لاحقاً.",
    retryable: true,
  },
  [PlanChangeErrorCode.DATABASE_ERROR]: {
    message: "Database error",
    userMessage: "An unexpected error occurred. Please try again.",
    userMessageAr: "حدث خطأ غير متوقع. يرجى المحاولة مرة أخرى.",
    retryable: true,
  },
  [PlanChangeErrorCode.SUBSCRIPTION_NOT_FOUND]: {
    message: "Subscription not found",
    userMessage: "Subscription not found. Please contact support.",
    userMessageAr: "لم يتم العثور على الاشتراك. يرجى التواصل مع الدعم.",
    retryable: false,
  },
};

/**
 * Get error details by code
 */
export function getErrorByCode(code: PlanChangeErrorCode): PlanChangeError {
  return {
    code,
    ...ERROR_DEFINITIONS[code],
  };
}

/**
 * Parse Stripe error to plan change error
 * Maps Stripe error codes to user-friendly bilingual messages
 */
export function parseStripeError(error: unknown): PlanChangeError {
  // Handle Stripe error object
  if (error && typeof error === "object" && "type" in error) {
    const stripeError = error as {
      type?: string;
      code?: string;
      message?: string;
    };

    // Stripe card errors
    if (stripeError.type === "StripeCardError") {
      switch (stripeError.code) {
        case "card_declined":
          return getErrorByCode(PlanChangeErrorCode.CARD_DECLINED);
        case "insufficient_funds":
          return getErrorByCode(PlanChangeErrorCode.INSUFFICIENT_FUNDS);
        case "expired_card":
          return getErrorByCode(PlanChangeErrorCode.EXPIRED_CARD);
        case "incorrect_cvc":
          return getErrorByCode(PlanChangeErrorCode.INCORRECT_CVC);
        case "processing_error":
          return getErrorByCode(PlanChangeErrorCode.PROCESSING_ERROR);
      }
    }

    // Stripe invalid request errors
    if (stripeError.type === "StripeInvalidRequestError") {
      if (stripeError.message?.includes("subscription")) {
        return getErrorByCode(PlanChangeErrorCode.SUBSCRIPTION_NOT_FOUND);
      }
    }
  }

  // Default to generic Stripe error
  return getErrorByCode(PlanChangeErrorCode.STRIPE_API_ERROR);
}

/**
 * Create error response object for API endpoints
 */
export function createErrorResponse(error: PlanChangeError) {
  return {
    success: false,
    error: error.userMessage,
    errorAr: error.userMessageAr,
    code: error.code,
    retryable: error.retryable,
  };
}
