// Pure formatting and date helpers used by the Medora components and the live app.
// No demo data here: `lib/mock-data.ts` re-exports these for the design-system demos, but live pages and
// components import from this file, so the mock dataset never reaches the app's bundle.

const n0 = new Intl.NumberFormat("en-US", { maximumFractionDigits: 0 });
const n2 = new Intl.NumberFormat("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 });

/**
 * 12450 -> "KES 12,450.00". P5: money is always KES with two decimals. `{ decimals: false }` is only for chart
 * axis ticks (K10), never for a figure someone reads.
 */
export function formatKES(amount: number, opts: { decimals?: boolean } = {}): string {
  return `KES ${(opts.decimals === false ? n0 : n2).format(amount)}`;
}

const MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
/**
 * "2026-10-20" -> "20 Oct 2026". A date is pure string maths, independent of the viewer's timezone. A full timestamp
 * ("2028-12-30T21:00:00.000Z", how the API sends a DATE column it read as a JavaScript date) is read in local time,
 * so it shows the day the pharmacy stored (31 Dec 2028 in Nairobi), not the UTC day before.
 */
export function formatDate(iso: string, opts: { short?: boolean } = {}): string {
  let [y, m, d] = iso.slice(0, 10).split("-").map(Number);
  if (/T\d\d:\d\d/.test(iso)) {
    const t = new Date(iso);
    if (!Number.isNaN(t.getTime())) [y, m, d] = [t.getFullYear(), t.getMonth() + 1, t.getDate()];
  }
  return opts.short ? `${d} ${MONTHS[m - 1]}` : `${d} ${MONTHS[m - 1]} ${y}`;
}

/** "1 unit", "3 units": a count with its noun, singular for one. */
export function count(n: number, one: string, many = `${one}s`): string {
  return `${n.toLocaleString("en-US")} ${n === 1 ? one : many}`;
}

/** A unit name in the singular, whether it was stored as "Bottle" or "bottles". */
export function unitSingular(u: string): string {
  if (/ies$/i.test(u)) return u.slice(0, -3) + "y";
  if (/(x|ch|sh|ss)es$/i.test(u)) return u.slice(0, -2);
  if (/s$/i.test(u) && !/ss$/i.test(u)) return u.slice(0, -1);
  return u;
}

/** A unit name in the plural: "Bottles", "Boxes". */
export function unitPlural(u: string): string {
  const one = unitSingular(u);
  return /(x|s|ch|sh)$/i.test(one) ? one + "es" : /[^aeiou]y$/i.test(one) ? one.slice(0, -1) + "ies" : one + "s";
}

/** "1 Bottle", "28 Bottles", "2 Boxes": a quantity with its unit name, singular for one. */
export function unitCount(n: number, unit: string): string {
  return `${n.toLocaleString("en-US")} ${n === 1 ? unitSingular(unit) : unitPlural(unit)}`;
}

export function addDays(iso: string, days: number): string {
  const [y, m, d] = iso.split("-").map(Number);
  const t = new Date(Date.UTC(y, m - 1, d + days));
  return t.toISOString().slice(0, 10);
}

export function daysBetween(fromIso: string, toIso: string): number {
  const f = (s: string) => {
    const [y, m, d] = s.split("-").map(Number);
    return Date.UTC(y, m - 1, d);
  };
  return Math.round((f(toIso) - f(fromIso)) / 86400000);
}

/**
 * Today's date as "YYYY-MM-DD" in the device's local time, not UTC: a sale or expiry check at 01:00 in
 * Nairobi belongs to that day, the same rule the API uses for day buckets (`localDay()` in sales.service.ts).
 * Components default their `today` to this; demos pass a fixed date instead so their figures don't move.
 */
export function localToday(now: Date = new Date()): string {
  const p2 = (n: number) => String(n).padStart(2, "0");
  return `${now.getFullYear()}-${p2(now.getMonth() + 1)}-${p2(now.getDate())}`;
}

/** The local YYYY-MM-DD of an API timestamp (a date string comes back unchanged). */
export function localDate(iso: string): string {
  return /T\d\d:\d\d/.test(iso) ? localToday(new Date(iso)) : iso.slice(0, 10);
}

/**
 * A phone number shown read-only, as the phone input spec says (01-actions-and-inputs §4): Kenyan numbers, stored as
 * 2547…, +2547… or 07…, read "+254 712 345 678"; anything else is shown as stored.
 */
export function formatPhone(phone: string | null | undefined): string {
  const p = String(phone ?? "").replace(/[\s-]/g, "");
  const m = /^(?:\+?254|0)([17]\d{8})$/.exec(p);
  return m ? `+254 ${m[1].slice(0, 3)} ${m[1].slice(3, 6)} ${m[1].slice(6)}` : String(phone ?? "");
}

export function initials(name: string): string {
  return name
    .split(" ")
    .map((p) => p[0])
    .slice(0, 2)
    .join("")
    .toUpperCase();
}

export type StockStatus = "In stock" | "Low stock" | "Out of stock";
export function stockStatus(p: { stock: number; minStock: number; type?: "Product" | "Service" }): StockStatus {
  if (p.type === "Service") return "In stock";
  if (p.stock === 0) return "Out of stock";
  return p.stock <= p.minStock ? "Low stock" : "In stock";
}
