/* ============================================================================
 * utils.jsx — pure helpers (no React state)
 * ----------------------------------------------------------------------------
 * Provides:
 *   • LABELS              → human-readable mappings for enum values
 *   • humanize(snake)     → fallback formatter for unknown enums
 *   • formatPhone()       → normalize a phone to E.164 with default country code
 *   • validatePhone()     → boolean for forms (E.164 + country-aware)
 *   • formatMoney(n)      → ₱ formatter
 *   • formatDate(d)       → short date
 *   • debounce(fn, ms)
 *
 * Exposes everything onto window so other Babel files can use them.
 * ========================================================================= */

/* Human-readable labels for snake_case enum values used throughout the DB.
 * To add a new value: just add a key. The `humanize()` fallback handles
 * anything missing automatically. */
const LABELS = {
  // contacts.type
  individual: "Individual",
  reseller: "Reseller",
  franchise: "Franchise",
  resto: "Restaurant",
  supplier: "Supplier",

  // contacts.lifecycle_status
  lead: "Lead",
  prospect: "Prospect",
  customer: "Customer",
  vip: "VIP",
  inactive: "Inactive",
  churned: "Churned",

  // contacts.source
  walk_in: "Walk-in",
  referral: "Referral",
  facebook: "Facebook",
  instagram: "Instagram",
  tiktok: "TikTok",
  google: "Google",
  event: "Event",
  other: "Other",

  // price_tier
  retail: "Retail",
  wholesale: "Wholesale",

  // orders.status
  pending: "Pending",
  preparing: "Preparing",
  ready: "Ready for Pickup",
  out_for_delivery: "Out for Delivery",
  delivered: "Delivered",
  completed: "Completed",
  cancelled: "Cancelled",

  // orders.payment_method
  cash: "Cash",
  gcash: "GCash",
  paymaya: "PayMaya",
  bank_transfer: "Bank Transfer",
  card: "Credit / Debit Card",
  cod: "Cash on Delivery",

  // orders.delivery_method
  pickup: "Pickup",
  delivery: "Delivery",
  lalamove: "Lalamove",
  grab_express: "Grab Express",
  shipping: "Shipping",

  // orders.payment status (derived)
  paid: "Paid",
  partial: "Partial",
  unpaid: "Unpaid",
  refunded: "Refunded",

  // expenses
  business: "Business",
  personal: "Personal",

  // products / inventory
  flan: "Flan",
  ingredients: "Ingredients",
  packaging: "Packaging",
  active: "Active",

  // user roles
  admin: "Administrator",
  manager: "Manager",
  staff: "Staff",
  viewer: "Viewer",
};

/* Generic snake_case → Title Case fallback. */
function humanize(value) {
  if (value === null || value === undefined || value === "") return "";
  if (LABELS[value]) return LABELS[value];
  return String(value)
    .split(/[_\s-]+/)
    .map(s => s.charAt(0).toUpperCase() + s.slice(1).toLowerCase())
    .join(" ");
}

/* ----- PHONE NORMALIZATION ------------------------------------------------- */
/* Converts user input like "0917 123 4567", "+639171234567", "9171234567"
 * into a clean E.164 string. Default country code from config. */
function formatPhone(raw, cc) {
  cc = cc || (window.WYF_CONFIG && window.WYF_CONFIG.DEFAULT_COUNTRY_CODE) || "+63";
  if (!raw) return "";
  let s = String(raw).trim().replace(/[^\d+]/g, "");
  if (!s) return "";
  if (s.startsWith("+")) return s;                         // already E.164
  if (cc === "+63") {
    if (s.startsWith("63")) return "+" + s;                // "63917..." → "+63917..."
    if (s.startsWith("0"))  return cc + s.slice(1);        // "0917..."  → "+63917..."
    if (s.startsWith("9") && s.length === 10) return cc + s;
  }
  return cc + s;
}

/* True if the normalized number looks like a valid E.164 phone for the given
 * country. PH mobile numbers are +63 + 10 digits starting with 9.            */
function validatePhone(raw, cc) {
  cc = cc || (window.WYF_CONFIG && window.WYF_CONFIG.DEFAULT_COUNTRY_CODE) || "+63";
  if (!raw) return false;
  const e164 = formatPhone(raw, cc);
  if (!/^\+\d{8,15}$/.test(e164)) return false;
  if (cc === "+63") {
    // PH mobile: +639XXXXXXXXX (12 chars total). Landline: +632XXXXXXXX (varies).
    if (/^\+639\d{9}$/.test(e164)) return true;            // mobile
    if (/^\+632\d{7,8}$/.test(e164)) return true;          // NCR landline
    if (/^\+63\d{9,10}$/.test(e164)) return true;          // other regional
    return false;
  }
  return true;
}

function formatMoney(n) {
  if (n === null || n === undefined || n === "") return "—";
  const num = Number(n);
  if (Number.isNaN(num)) return String(n);
  return "₱" + num.toLocaleString("en-PH", { minimumFractionDigits: 2, maximumFractionDigits: 2 });
}

function formatDate(d) {
  if (!d) return "—";
  const date = (d instanceof Date) ? d : new Date(d);
  if (Number.isNaN(date.getTime())) return String(d);
  return date.toLocaleDateString("en-PH", { year: "numeric", month: "short", day: "numeric" });
}

function formatDateTime(d) {
  if (!d) return "—";
  const date = (d instanceof Date) ? d : new Date(d);
  if (Number.isNaN(date.getTime())) return String(d);
  return date.toLocaleString("en-PH", { dateStyle: "medium", timeStyle: "short" });
}

function debounce(fn, ms) {
  let t;
  return function (...args) {
    clearTimeout(t);
    t = setTimeout(() => fn.apply(this, args), ms);
  };
}

/* ----- ENUM OPTION SETS — single source of truth used by forms ----------- */
const ENUM_OPTIONS = {
  contact_type:        ["individual", "reseller", "franchise", "resto", "supplier"],
  lifecycle_status:    ["lead", "prospect", "customer", "vip", "inactive", "churned"],
  contact_source:      ["walk_in", "referral", "facebook", "instagram", "tiktok", "google", "event", "other"],
  price_tier:          ["retail", "wholesale"],
  order_status:        ["pending", "preparing", "ready", "out_for_delivery", "delivered", "completed", "cancelled"],
  payment_method:      ["cash", "gcash", "paymaya", "bank_transfer", "card", "cod"],
  delivery_method:     ["pickup", "delivery", "lalamove", "grab_express", "shipping"],
  expense_classification: ["business", "personal"],
  user_role:           ["admin", "manager", "staff", "viewer"],
};

/* The four "business" classifications that unlock business-only contact
 * fields (TIN, business details, credit limit, payment terms, reseller
 * discount, contact person). See Contacts view. */
const BUSINESS_CONTACT_TYPES = ["reseller", "franchise", "resto", "supplier"];

Object.assign(window, {
  LABELS,
  humanize,
  formatPhone,
  validatePhone,
  formatMoney,
  formatDate,
  formatDateTime,
  debounce,
  ENUM_OPTIONS,
  BUSINESS_CONTACT_TYPES,
});
