'use strict';

var chunkXA3ZNR75_js = require('./chunk-XA3ZNR75.js');

// src/utils/price.ts
var CURRENCY_SYMBOLS = {
  USD: "$",
  EUR: "\u20AC",
  GBP: "\xA3",
  JPY: "\xA5",
  CNY: "\xA5",
  CHF: "CHF",
  CAD: "C$",
  AUD: "A$",
  NZD: "NZ$",
  HKD: "HK$",
  SGD: "S$",
  INR: "\u20B9",
  BRL: "R$",
  MXN: "MX$",
  KRW: "\u20A9",
  RUB: "\u20BD",
  TRY: "\u20BA",
  THB: "\u0E3F",
  PLN: "z\u0142",
  SEK: "kr",
  NOK: "kr",
  DKK: "kr",
  CZK: "K\u010D",
  HUF: "Ft",
  ILS: "\u20AA",
  AED: "\u062F.\u0625",
  SAR: "\uFDFC",
  MYR: "RM",
  PHP: "\u20B1",
  IDR: "Rp",
  VND: "\u20AB",
  TWD: "NT$",
  GHS: "GH\u20B5",
  NGN: "\u20A6",
  KES: "KSh",
  ZAR: "R",
  XOF: "CFA",
  XAF: "FCFA",
  EGP: "E\xA3",
  MAD: "MAD",
  TZS: "TSh",
  UGX: "USh",
  RWF: "FRw",
  ETB: "Br",
  ZMW: "ZK",
  BWP: "P",
  MUR: "\u20A8",
  SCR: "\u20A8",
  NAD: "N$",
  SZL: "E",
  LSL: "L",
  MWK: "MK",
  AOA: "Kz",
  CDF: "FC",
  GMD: "D",
  GNF: "FG",
  LRD: "L$",
  SLL: "Le",
  MZN: "MT",
  SDG: "SDG",
  SSP: "SSP",
  SOS: "Sh.So.",
  DJF: "Fdj",
  ERN: "Nfk",
  CVE: "$",
  STN: "Db",
  KMF: "CF",
  BIF: "FBu"
};
function getCurrencySymbol(currencyCode2) {
  return CURRENCY_SYMBOLS[currencyCode2.toUpperCase()] || currencyCode2;
}
function formatNumberCompact(value, decimals = 1) {
  const absValue = Math.abs(value);
  const sign = value < 0 ? "-" : "";
  if (absValue >= 1e9) {
    return `${sign}${(absValue / 1e9).toFixed(decimals)}B`;
  }
  if (absValue >= 1e6) {
    return `${sign}${(absValue / 1e6).toFixed(decimals)}M`;
  }
  if (absValue >= 1e3) {
    return `${sign}${(absValue / 1e3).toFixed(decimals)}K`;
  }
  return `${sign}${absValue.toFixed(decimals)}`;
}
function formatPrice(amount, currency = "GHS", locale = "en-US") {
  const numAmount = typeof amount === "string" ? parseFloat(amount) : amount;
  if (isNaN(numAmount)) {
    return `${getCurrencySymbol(currency)}0.00`;
  }
  const symbol = getCurrencySymbol(currency);
  try {
    const formatted = new Intl.NumberFormat(locale, {
      minimumFractionDigits: 2,
      maximumFractionDigits: 2
    }).format(numAmount);
    return `${symbol}${formatted}`;
  } catch {
    return `${symbol}${numAmount.toFixed(2)}`;
  }
}
function formatPriceAdjustment(amount, currency = "GHS", locale = "en-US") {
  const formatted = formatPrice(Math.abs(amount), currency, locale);
  if (amount > 0) {
    return `+${formatted}`;
  } else if (amount < 0) {
    return `-${formatted}`;
  }
  return formatted;
}
function formatPriceCompact(amount, currency = "GHS", decimals = 1) {
  const numAmount = typeof amount === "string" ? parseFloat(amount) : amount;
  if (isNaN(numAmount)) {
    return `${getCurrencySymbol(currency)}0`;
  }
  const symbol = getCurrencySymbol(currency);
  if (Math.abs(numAmount) < 1e3) {
    return `${symbol}${numAmount.toFixed(2)}`;
  }
  return `${symbol}${formatNumberCompact(numAmount, decimals)}`;
}
function formatMoney(amount, currency = "GHS") {
  const symbol = getCurrencySymbol(currency);
  const numAmount = typeof amount === "string" ? parseFloat(amount) : amount;
  if (isNaN(numAmount)) {
    return `${symbol}0.00`;
  }
  return `${symbol}${numAmount.toFixed(2)}`;
}
function parsePrice(value) {
  if (value === void 0 || value === null) {
    return 0;
  }
  if (typeof value === "number") {
    return isNaN(value) ? 0 : value;
  }
  const cleaned = value.replace(/[^\d.-]/g, "");
  const parsed = parseFloat(cleaned);
  return isNaN(parsed) ? 0 : parsed;
}
function hasTaxInfo(priceInfo) {
  return priceInfo.tax_info !== void 0 && priceInfo.tax_info !== null;
}
function getTaxAmount(priceInfo) {
  return parsePrice(priceInfo.tax_info?.tax_amount);
}
function isTaxInclusive(priceInfo) {
  return priceInfo.tax_info?.is_inclusive === true;
}
function formatPriceWithTax(priceInfo, currency = "GHS") {
  const finalPrice = formatPrice(priceInfo.final_price, currency);
  if (!hasTaxInfo(priceInfo)) {
    return finalPrice;
  }
  if (isTaxInclusive(priceInfo)) {
    return `${finalPrice} (incl. tax)`;
  }
  return `${finalPrice} + ${formatPrice(getTaxAmount(priceInfo), currency)} tax`;
}
function getDisplayPrice(product) {
  if (product.price_info) {
    return parsePrice(product.price_info.final_price);
  }
  if (product.final_price !== void 0 && product.final_price !== null) {
    return parsePrice(product.final_price);
  }
  if (product.default_price !== void 0 && product.default_price !== null) {
    return parsePrice(product.default_price);
  }
  return 0;
}
function getBasePrice(product) {
  if (product.price_info) {
    return parsePrice(product.price_info.base_price);
  }
  if (product.base_price !== void 0 && product.base_price !== null) {
    return parsePrice(product.base_price);
  }
  if (product.default_price !== void 0 && product.default_price !== null) {
    return parsePrice(product.default_price);
  }
  return 0;
}
function isOnSale(product) {
  const basePrice = getBasePrice(product);
  const finalPrice = getDisplayPrice(product);
  return basePrice > finalPrice && basePrice > 0;
}
function getDiscountPercentage(product) {
  const basePrice = getBasePrice(product);
  const finalPrice = getDisplayPrice(product);
  if (basePrice > finalPrice && basePrice > 0) {
    return Math.round((basePrice - finalPrice) / basePrice * 100);
  }
  return 0;
}
function getMarkupPercentage(product) {
  const basePrice = getBasePrice(product);
  const finalPrice = getDisplayPrice(product);
  if (finalPrice > basePrice && basePrice > 0) {
    return Math.round((finalPrice - basePrice) / basePrice * 100);
  }
  return 0;
}
function getProductCurrency(product) {
  if (product.price_info?.currency) {
    return product.price_info.currency;
  }
  if (product.currency) {
    return product.currency;
  }
  return "GHS";
}
function formatProductPrice(product, locale = "en-US") {
  const price = getDisplayPrice(product);
  const currency = getProductCurrency(product);
  return formatPrice(price, currency, locale);
}
function getUnitPriceAtQuantity(tiers, quantity, fallback) {
  const sorted = [...tiers].sort((a, b) => a.min_quantity - b.min_quantity);
  let matched;
  for (const tier of sorted) {
    if (quantity >= tier.min_quantity) {
      if (tier.max_quantity == null || quantity <= tier.max_quantity) {
        matched = tier;
      }
    }
  }
  return matched ? parsePrice(matched.unit_price) : fallback;
}
function getPriceRange(product) {
  const tiers = product.quantity_pricing;
  if (tiers && tiers.length > 1) {
    const prices = tiers.map((t) => parsePrice(t.unit_price));
    return { min: Math.min(...prices), max: Math.max(...prices) };
  }
  const variants = product.variants;
  if (variants && variants.length > 1) {
    const base = parsePrice(product.default_price);
    const prices = variants.map(
      (v) => base + parsePrice(v.price_adjustment ?? 0)
    );
    return { min: Math.min(...prices), max: Math.max(...prices) };
  }
  return null;
}
function formatPriceRange(min, max, currency = "GHS") {
  return `${formatPrice(min, currency)} \u2013 ${formatPrice(max, currency)}`;
}

// src/utils/payment.ts
function categorizePaymentError(error, errorCode) {
  let message = "An unexpected error occurred during payment processing. Please try again or contact support.";
  let recoverable = true;
  let code = errorCode || "PAYMENT_ERROR";
  const technical = error.stack;
  const errorMessage = error.message?.toLowerCase() || "";
  if (errorCode === "INSUFFICIENT_FUNDS" || errorMessage.includes("insufficient") || errorMessage.includes("funds")) {
    code = "INSUFFICIENT_FUNDS";
    message = "Your payment method has insufficient funds. Please try another payment method.";
  } else if (errorCode === "CARD_DECLINED" || errorMessage.includes("declined")) {
    code = "CARD_DECLINED";
    message = "Your card was declined. Please try another card or payment method.";
  } else if (errorMessage.includes("cancelled") || errorMessage.includes("canceled") || errorCode === "PAYMENT_CANCELLED") {
    code = "PAYMENT_CANCELLED";
    message = "Payment was cancelled. You can try again when ready.";
  } else if (errorMessage.includes("network") || errorMessage.includes("connection") || errorCode === "NETWORK_ERROR") {
    code = "NETWORK_ERROR";
    message = "Network connection issue. Please check your internet connection and try again.";
  } else if (errorMessage.includes("timeout") || errorCode === "TIMEOUT") {
    code = "TIMEOUT";
    message = "Payment processing timed out. Please try again.";
  } else if (errorCode === "PAYMENT_ACTION_NOT_COMPLETED") {
    code = "PAYMENT_ACTION_NOT_COMPLETED";
    message = "Payment action was not completed. Please try again.";
  } else if (errorCode === "AUTHORIZATION_FAILED") {
    code = "AUTHORIZATION_FAILED";
    message = "Authorization failed. Please check your code and try again.";
  } else if (errorCode === "INVALID_OTP") {
    code = "INVALID_OTP";
    message = "Invalid verification code. Please check and try again.";
  }
  return { code, message, recoverable, technical };
}
function isQuickPaymentResponse(response) {
  return response !== null && typeof response === "object" && "payment" in response && typeof response.payment === "object";
}
function isWebPaymentResponse(response) {
  return response !== null && typeof response === "object" && "transaction" in response && typeof response.transaction === "object";
}
function normalizePaymentResponse(response) {
  if (!response) {
    return {
      method: "unknown",
      provider: "unknown",
      requires_action: false,
      metadata: {}
    };
  }
  if (isQuickPaymentResponse(response)) {
    return {
      method: response.payment.type?.toLowerCase() || "unknown",
      provider: response.payment.provider?.toLowerCase() || "unknown",
      requires_action: !!response.payment.redirect_url || !!response.payment.access_code,
      public_key: response.payment.public_key,
      client_secret: response.payment.access_code,
      access_code: response.payment.access_code,
      redirect_url: response.payment.redirect_url,
      transaction_id: response.payment.reference,
      order_id: response.order_id,
      reference: response.payment.reference,
      instructions: response.payment.instructions,
      metadata: response.payment.metadata
    };
  }
  if (isWebPaymentResponse(response)) {
    const objectAuthType = response.authorization_type && typeof response.authorization_type === "object" && "address" in response.authorization_type ? "address" : void 0;
    const authType = typeof response.authorization_type === "string" ? response.authorization_type.trim().toLowerCase().replace(/[\s-]+/g, "_") : void 0;
    const validStringAuthTypes = ["otp", "pin", "phone", "birthday", "address"];
    const safeAuthType = objectAuthType || (authType && validStringAuthTypes.includes(authType) ? authType : void 0);
    return {
      provider: response.transaction.provider_type?.toLowerCase() || "unknown",
      requires_action: response.requires_action || false,
      public_key: response.public_key,
      client_secret: response.client_secret,
      redirect_url: response.authorization_url,
      transaction_id: response.transaction.id,
      order_id: response.transaction.order_id,
      reference: response.transaction.provider_reference,
      metadata: response.transaction.metadata,
      method: response.transaction.payment_method?.toLowerCase() || "unknown",
      instructions: response.display_text,
      display_text: response.display_text,
      requires_authorization: response.requires_authorization,
      authorization_type: safeAuthType,
      provider_payment_id: response.provider_payment_id || response.transaction.provider_reference
    };
  }
  return {
    method: "unknown",
    provider: "unknown",
    requires_action: false,
    metadata: {}
  };
}
var PAYMENT_SUCCESS_STATUSES = /* @__PURE__ */ new Set([
  "success",
  "succeeded",
  "paid",
  "captured",
  "completed",
  "authorized"
]);
var PAYMENT_FAILURE_STATUSES = /* @__PURE__ */ new Set([
  "failed",
  "declined",
  "cancelled",
  "voided",
  "error",
  "abandoned"
]);
var PAYMENT_REQUIRES_ACTION_STATUSES = /* @__PURE__ */ new Set([
  "requires_action",
  "requires_payment_method",
  "requires_capture"
]);
var PAYMENT_STATUS_ALIAS_MAP = {
  ok: "captured",
  done: "captured",
  paid: "captured",
  paid_in_full: "captured",
  paid_successfully: "captured",
  succeeded: "captured",
  success: "captured",
  captured: "captured",
  completed: "captured",
  pending_confirmation: "pending",
  requires_authorization: "requires_action",
  requires_action: "requires_action",
  requires_payment_method: "requires_action",
  requires_capture: "authorized",
  partially_paid: "pending",
  partially_refunded: "refunded",
  card_declined: "failed",
  declined: "failed",
  canceled: "cancelled",
  authorized: "authorized",
  cancelled: "cancelled",
  unresolved: "pending",
  error: "failed"
};
var KNOWN_PAYMENT_STATUSES = /* @__PURE__ */ new Set([
  "initialized",
  "pending",
  "processing",
  "authorized",
  "captured",
  "failed",
  "cancelled",
  "refunded",
  "unknown",
  "voided",
  "requires_action",
  "abandoned",
  "reversed",
  "disputed",
  "refund_pending"
]);
function normalizeStatusToken(status) {
  return status?.trim().toLowerCase().replace(/[\s-]+/g, "_") ?? "";
}
function normalizePaymentStatusValue(status) {
  const normalized = normalizeStatusToken(status);
  if (Object.prototype.hasOwnProperty.call(PAYMENT_STATUS_ALIAS_MAP, normalized)) {
    return PAYMENT_STATUS_ALIAS_MAP[normalized];
  }
  return KNOWN_PAYMENT_STATUSES.has(normalized) ? normalized : "unknown";
}
function isPaymentStatusSuccess(status) {
  const normalizedStatus = normalizePaymentStatusValue(status);
  return PAYMENT_SUCCESS_STATUSES.has(normalizedStatus);
}
function isPaymentStatusFailure(status) {
  const normalizedStatus = normalizePaymentStatusValue(status);
  return PAYMENT_FAILURE_STATUSES.has(normalizedStatus);
}
function isPaymentStatusRequiresAction(status) {
  const normalizedStatus = normalizePaymentStatusValue(status);
  return PAYMENT_REQUIRES_ACTION_STATUSES.has(normalizedStatus);
}
function normalizeStatusResponse(response) {
  if (!response || typeof response !== "object") {
    return {
      status: "pending",
      paid: false,
      amount: chunkXA3ZNR75_js.moneyFromNumber(0),
      currency: "",
      message: "No status available"
    };
  }
  const res = response;
  const normalizedStatus = normalizePaymentStatusValue(res.status ?? void 0);
  const normalizedAmount = typeof res.amount === "string" ? chunkXA3ZNR75_js.money(res.amount) : typeof res.amount === "number" && Number.isFinite(res.amount) ? chunkXA3ZNR75_js.moneyFromNumber(res.amount) : chunkXA3ZNR75_js.moneyFromNumber(0);
  const normalizedCurrency = typeof res.currency === "string" && res.currency.trim().length > 0 ? res.currency : "";
  const paidValue = res.paid === true;
  const derivedPaid = paidValue || [
    "success",
    "succeeded",
    "paid",
    "captured",
    "authorized",
    "completed"
  ].includes(normalizedStatus);
  return {
    status: normalizedStatus,
    paid: derivedPaid,
    amount: normalizedAmount,
    currency: normalizedCurrency,
    reference: res.reference,
    message: res.message || ""
  };
}
var MOBILE_MONEY_PROVIDERS = {
  mtn: { name: "MTN Mobile Money", prefix: ["024", "025", "053", "054", "055", "059"] },
  vodafone: { name: "Telecel Cash", prefix: ["020", "050"] },
  airtel: { name: "AirtelTigo Money", prefix: ["026", "027", "056", "057"] }
};
function detectMobileMoneyProvider(phoneNumber) {
  const cleaned = phoneNumber.replace(/\D/g, "");
  const networkCode = cleaned.slice(-9, -7);
  for (const [provider, info] of Object.entries(MOBILE_MONEY_PROVIDERS)) {
    if (info.prefix.some((p) => p.slice(1) === networkCode)) {
      return provider;
    }
  }
  return null;
}

exports.CURRENCY_SYMBOLS = CURRENCY_SYMBOLS;
exports.MOBILE_MONEY_PROVIDERS = MOBILE_MONEY_PROVIDERS;
exports.categorizePaymentError = categorizePaymentError;
exports.detectMobileMoneyProvider = detectMobileMoneyProvider;
exports.formatMoney = formatMoney;
exports.formatNumberCompact = formatNumberCompact;
exports.formatPrice = formatPrice;
exports.formatPriceAdjustment = formatPriceAdjustment;
exports.formatPriceCompact = formatPriceCompact;
exports.formatPriceRange = formatPriceRange;
exports.formatPriceWithTax = formatPriceWithTax;
exports.formatProductPrice = formatProductPrice;
exports.getBasePrice = getBasePrice;
exports.getCurrencySymbol = getCurrencySymbol;
exports.getDiscountPercentage = getDiscountPercentage;
exports.getDisplayPrice = getDisplayPrice;
exports.getMarkupPercentage = getMarkupPercentage;
exports.getPriceRange = getPriceRange;
exports.getProductCurrency = getProductCurrency;
exports.getTaxAmount = getTaxAmount;
exports.getUnitPriceAtQuantity = getUnitPriceAtQuantity;
exports.hasTaxInfo = hasTaxInfo;
exports.isOnSale = isOnSale;
exports.isPaymentStatusFailure = isPaymentStatusFailure;
exports.isPaymentStatusRequiresAction = isPaymentStatusRequiresAction;
exports.isPaymentStatusSuccess = isPaymentStatusSuccess;
exports.isTaxInclusive = isTaxInclusive;
exports.normalizePaymentResponse = normalizePaymentResponse;
exports.normalizeStatusResponse = normalizeStatusResponse;
exports.parsePrice = parsePrice;
