import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";
import type { POStatus } from "@prisma/client";

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs));
}

export function formatCurrency(amount: number | string, currency = "INR"): string {
  return new Intl.NumberFormat("en-IN", { style: "currency", currency }).format(
    Number(amount)
  );
}

// Compact INR formatter using the Indian short scale (lakh = 1e5, crore = 1e7).
// Produces readable abbreviations for dashboard stat cards, e.g. ₹2 Cr, ₹49 L,
// ₹75 K, ₹500. Values are rounded to at most 2 decimals with trailing zeros
// trimmed (₹2.5 Cr, not ₹2.50 Cr). Negative amounts keep their sign.
export function formatCompactINR(amount: number | string): string {
  const n = Number(amount);
  if (!Number.isFinite(n)) return "₹0";

  const sign = n < 0 ? "-" : "";
  const abs = Math.abs(n);

  const format = (value: number, suffix: string) => {
    const rounded = Math.round(value * 100) / 100;
    // Trim trailing zeros: 2 -> "2", 2.5 -> "2.5", 2.05 -> "2.05".
    const text = rounded.toFixed(2).replace(/\.?0+$/, "");
    return `${sign}₹${text}${suffix}`;
  };

  if (abs >= 1e7) return format(abs / 1e7, " Cr");
  if (abs >= 1e5) return format(abs / 1e5, " L");
  if (abs >= 1e3) return format(abs / 1e3, " K");
  return format(abs, "");
}

export function formatDate(date: Date | string): string {
  return new Intl.DateTimeFormat("en-US", {
    year: "numeric",
    month: "short",
    day: "numeric",
  }).format(new Date(date));
}

export function formatDateTime(date: Date | string): string {
  return new Intl.DateTimeFormat("en-US", {
    year: "numeric",
    month: "short",
    day: "numeric",
    hour: "2-digit",
    minute: "2-digit",
  }).format(new Date(date));
}

export function generatePoNumber(): string {
  const year = new Date().getFullYear();
  const seq = Math.floor(Math.random() * 100000)
    .toString()
    .padStart(5, "0");
  return `PO-${year}-${seq}`;
}

export const PO_STATUS_LABELS: Record<POStatus, string> = {
  DRAFT: "Draft",
  SUBMITTED: "Submitted",
  MGR_REVIEW: "Under Review",
  VENDOR_ID_PENDING: "Vendor ID Pending",
  EDITS_REQUESTED: "Edits Requested",
  REJECTED: "Rejected",
  MGR_APPROVED: "Approved",
  SENT_FOR_PAYMENT: "Sent for Payment",
  PARTIALLY_PAID: "Partially Paid",
  PAID_DELIVERED: "Paid",
  PARTIALLY_CLOSED: "Partially Received",
  CLOSED: "Closed",
  CANCELLED: "Cancelled",
};

// Statuses a PO can be in once it has received manager approval. A PO keeps its
// `approvedAt` timestamp as it moves through these states, so "approved this month"
// aggregations must match against all of them — not just MGR_APPROVED.
export const POST_APPROVAL_STATUSES = [
  "MGR_APPROVED",
  "SENT_FOR_PAYMENT",
  "PARTIALLY_PAID",
  "PAID_DELIVERED",
  "PARTIALLY_CLOSED",
  "CLOSED",
] as const satisfies readonly POStatus[];

export type BadgeVariant =
  | "default"
  | "secondary"
  | "success"
  | "warning"
  | "danger"
  | "outline";

export const PO_STATUS_VARIANTS: Record<POStatus, BadgeVariant> = {
  DRAFT: "outline",
  SUBMITTED: "secondary",
  MGR_REVIEW: "secondary",
  VENDOR_ID_PENDING: "warning",
  EDITS_REQUESTED: "warning",
  REJECTED: "danger",
  MGR_APPROVED: "success",
  SENT_FOR_PAYMENT: "default",
  PARTIALLY_PAID: "warning",
  PAID_DELIVERED: "success",
  PARTIALLY_CLOSED: "warning",
  CLOSED: "secondary",
  CANCELLED: "danger",
};
