import { formatCurrency } from '@/lib/format';
import type { Locale } from '@/lib/i18n/index';

/**
 * Money in Multideal is stored as integer AGOROT (1 ₪ = 100 agorot).
 * THIS MODULE IS THE ONLY PLACE agorot → string/number conversion is allowed.
 * Never write `(x / 100).toFixed(...)`, `x / 100`, or `Math.floor(x/100)` outside here.
 *
 * Pick by intent:
 *   Display (user sees ₪):  formatAgorotShekels(abs) | formatAgorotSigned | formatAgorotWhole
 *                           | formatAgorotPricePrefixed(deal cards) | formatAgorotLocale(whole, rounded)
 *                           | formatAgorotCurrencyILS(grouped) | formatAgorotDisplay(debt-safe)
 *   Data contract (API / i18n / log / CSV): formatAgorotPlain  (plain "X.XX", NO ₪, NO grouping)
 *   Raw number (math / thresholds): agorotToShekels | agorotToShekelsFloor
 */

export type AgorotDisplay = string | { isDebt: true; debtAgorot: number };

/** Negative-safe: positive/zero → "₪X.XX"; negative → {isDebt, debtAgorot}. */
export function formatAgorotDisplay(agorot: number): AgorotDisplay {
  if (agorot < 0) return { isDebt: true, debtAgorot: Math.abs(agorot) };
  return `₪${(agorot / 100).toFixed(2)}`;
}

/** "₪X.XX" — ABS (drops sign). Use ONLY where agorot is guaranteed ≥ 0. */
export function formatAgorotShekels(agorot: number): string {
  return `₪${(Math.abs(agorot) / 100).toFixed(2)}`;
}

/** "₪X.XX" — SIGN-FAITHFUL (no abs): negative → "₪-5.00". For refund/adjustment/balance rows. */
export function formatAgorotSigned(agorot: number): string {
  return `₪${(agorot / 100).toFixed(2)}`;
}

/** "₪X" whole shekels (toFixed(0) → rounds). */
export function formatAgorotWhole(agorot: number): string {
  return `₪${(agorot / 100).toFixed(0)}`;
}

/**
 * Locale Intl ILS via formatCurrency — maximumFractionDigits:0, so cents are DROPPED
 * and value ROUNDED to whole shekels ("₪151" from 15050). Use only for whole-shekel display.
 * NOT a formatPrice replacement (which keeps 2 decimals) — use formatAgorotPricePrefixed for deal prices.
 */
export function formatAgorotLocale(agorot: number, locale: Locale = 'he'): string {
  return formatCurrency(agorot / 100, locale);
}

/**
 * "₪150.5" — PREFIX ₪, plain he-IL grouping, 0–2 decimals. Matches legacy DealCard/ticker formatPrice output exactly.
 * Use when value is integer agorot (e.g. 15050 → "₪150.5", 15000 → "₪150").
 */
export function formatAgorotPricePrefixed(agorot: number): string {
  return `₪${(agorot / 100).toLocaleString('he-IL', { minimumFractionDigits: 0, maximumFractionDigits: 2 })}`;
}

/** Locale ILS via toLocaleString he-IL, min 2 fraction digits, grouped: "₪1,234.56". Sign-faithful. */
export function formatAgorotCurrencyILS(agorot: number): string {
  return (agorot / 100).toLocaleString('he-IL', {
    style: 'currency',
    currency: 'ILS',
    minimumFractionDigits: 2,
  });
}

/** "₪1,234.56" — prefix ₪, he-IL grouping, min 2 decimals, SIGN-FAITHFUL. For settlement/balance rows that are grouped + can go negative. */
export function formatAgorotGrouped(agorot: number): string {
  return `₪${(agorot / 100).toLocaleString('he-IL', { minimumFractionDigits: 2 })}`;
}

/** Plain decimal string, NO ₪, NO grouping — API payloads, i18n interpolation, logs, CSV. Sign-faithful. */
export function formatAgorotPlain(agorot: number, fractionDigits: 0 | 2 = 2): string {
  return (agorot / 100).toFixed(fractionDigits);
}

/**
 * Format a float shekel value (e.g. 45.5 from a numeric DB column) as "₪45.50".
 * Only use when the upstream value is a float shekel, NOT an agorot integer.
 * For agorot integers use formatAgorotShekels instead.
 */
export function formatShekelFloat(shekels: number | string): string {
  return `₪${Number(shekels).toFixed(2)}`;
}

/**
 * Serialize a float shekel value to a plain decimal string for API payloads.
 * Output matches amountStringSchema: "45.50" with no currency symbol.
 * Use when sending price values to the API, not for display.
 */
export function shekelFloatToDecimalString(shekels: number): string {
  return Number(shekels).toFixed(2);
}

/** agorot → shekels Number (no rounding). For arithmetic / comparisons. */
export function agorotToShekels(agorot: number): number {
  return agorot / 100;
}

/** agorot → whole-shekel integer (floor). For min-threshold display/compare. */
export function agorotToShekelsFloor(agorot: number): number {
  return Math.floor(agorot / 100);
}

/** floor(agorot × percent / 100) — percent is whole-number (10 = 10%). */
export function floorAgorotPercent(agorot: number, percent: number): number {
  return Math.floor((agorot * percent) / 100);
}

/** floor(agorot × bps / 10000) — basis points (500 bps = 5%). */
export function floorAgorotBps(agorot: number, bps: number): number {
  return Math.floor((agorot * bps) / 10000);
}

/** shekels (decimal) → integer agorot. Always round — never truncate. */
export function shekelsToAgorot(shekels: number): number {
  return Math.round(shekels * 100);
}

/**
 * Split a payment amount into commission and vendor portions.
 *
 * @param amountPaid — Shekel float string or number (e.g. "99.90" or 99.9)
 * @param rate — Commission rate as decimal fraction (e.g. 0.10 = 10%)
 * @returns { commission: "9.99", vendor: "89.91" } — both toFixed(2) strings
 *
 * Verified identical at all 6 call sites: group-reservation, purchase,
 * group-deal, cart-checkout/machine, purchases/pending.
 */
export function splitCommission(
  amountPaid: number | string,
  rate: number | string,
): { commission: string; vendor: string } {
  const commission = (parseFloat(String(amountPaid)) * parseFloat(String(rate))).toFixed(2);
  const vendor = (parseFloat(String(amountPaid)) - parseFloat(commission)).toFixed(2);
  return { commission, vendor };
}
