import { randomBytes } from "crypto";

const CODE_ALPHABET = "ABCDEFGHJKMNPQRSTUVWXYZ23456789"; // no ambiguous chars

function randomCode(len: number): string {
  const bytes = randomBytes(len);
  let out = "";
  for (let i = 0; i < len; i++) out += CODE_ALPHABET[bytes[i] % CODE_ALPHABET.length];
  return out;
}

export const newRegCode = () => `CFX-${randomCode(6)}`;
export const newCertId = () => `CFX-CERT-${randomCode(8)}`;
export const newTxnId = () => `txn_${randomBytes(10).toString("hex")}`;

export function slugify(s: string): string {
  return s.toLowerCase().trim().replace(/[^a-z0-9\s-]/g, "").replace(/[\s-]+/g, "-").slice(0, 60);
}

// price stored in paise
export function formatMoney(paise: number, currency = "INR"): string {
  if (paise === 0) return "Free";
  const amount = paise / 100;
  return new Intl.NumberFormat("en-IN", { style: "currency", currency, maximumFractionDigits: amount % 1 === 0 ? 0 : 2 }).format(amount);
}

const TZ = "Asia/Kolkata";

export function fmtDate(d: Date | string): string {
  return new Date(d).toLocaleDateString("en-IN", { day: "numeric", month: "short", year: "numeric", timeZone: TZ });
}

export function fmtDateTime(d: Date | string): string {
  return new Date(d).toLocaleString("en-IN", { day: "numeric", month: "short", hour: "numeric", minute: "2-digit", hour12: true, timeZone: TZ });
}

export function fmtTime(d: Date | string): string {
  return new Date(d).toLocaleTimeString("en-IN", { hour: "numeric", minute: "2-digit", hour12: true, timeZone: TZ });
}

export function fmtDay(d: Date | string): string {
  return new Date(d).toLocaleDateString("en-IN", { weekday: "long", day: "numeric", month: "long", timeZone: TZ });
}

export function dayKey(d: Date | string): string {
  return new Date(d).toLocaleDateString("en-CA", { timeZone: TZ }); // YYYY-MM-DD
}

export function dateRange(start: Date | string, end: Date | string): string {
  const s = new Date(start), e = new Date(end);
  if (dayKey(s) === dayKey(e)) return fmtDate(s);
  const sameMonth = s.getMonth() === e.getMonth() && s.getFullYear() === e.getFullYear();
  if (sameMonth)
    return `${s.toLocaleDateString("en-IN", { day: "numeric", timeZone: TZ })}–${e.toLocaleDateString("en-IN", { day: "numeric", month: "short", year: "numeric", timeZone: TZ })}`;
  return `${fmtDate(s)} – ${fmtDate(e)}`;
}

export function initials(name: string): string {
  return name.split(/\s+/).slice(0, 2).map((w) => w[0]?.toUpperCase() ?? "").join("");
}

export function parseJSON<T>(s: string | null | undefined, fallback: T): T {
  if (!s) return fallback;
  try { return JSON.parse(s) as T; } catch { return fallback; }
}
