"use client";
import { useMemo, useState } from "react";
import { Download, Plus, Search, Inbox, Pencil, Trash2, Printer } from "lucide-react";
import { RESOURCES, MODULES, type Field } from "@/lib/resources";
import { Alert, Field as FieldBox, Modal, useAction } from "../ui";

const ACTS = ["view", "create", "edit", "delete"];
const fmt = (f: Field, v: any) => f.type === "money" ? "৳" + Number(v || 0).toLocaleString("en-US") : f.type === "bool" ? (v ? "Yes" : "—") : v === "" || v == null ? "—" : String(v);
const tone = (v: string) => (["active", "paid", "present", "filed", "sent", "in", "ok", "sent "].includes(v) ? "ok" : ["overdue", "absent", "out", "left", "failed", "error"].includes(v) ? "bad" : ["draft", "pending", "prospect", "late", "on leave", "leave"].includes(v) ? "warn" : "gray");

function Matrix({ value, onChange }: { value: any; onChange: (v: any) => void }) {
  const v = value || {};
  const toggle = (m: string, a: string) => { const cur: string[] = v[m] || []; const next = cur.includes(a) ? cur.filter((x) => x !== a) : [...cur, a]; onChange({ ...v, [m]: next }); };
  return (<div className="overflow-x-auto rounded-xl border border-slate-200"><table className="tbl"><thead><tr><th>Module</th>{ACTS.map((a) => <th key={a} className="text-center">{a}</th>)}</tr></thead>
    <tbody>{MODULES.map((m) => <tr key={m}><td className="capitalize">{m}</td>{ACTS.map((a) => <td key={a} className="text-center"><input type="checkbox" aria-label={`${m} ${a}`} checked={(v[m] || []).includes(a)} onChange={() => toggle(m, a)} /></td>)}</tr>)}</tbody></table></div>);
}

export function ResourceView({ resource, rows, printHref }: { resource: string; rows: any[]; printHref?: string }) {
  const def = RESOURCES[resource]; const { run, busy, error, setError } = useAction();
  const [q, setQ] = useState(""), [flt, setFlt] = useState("all"), [edit, setEdit] = useState<any>(null);
  const cols = def.fields.filter((f) => f.col);
  const shown = useMemo(() => rows.filter((r) => (flt === "all" || r[def.filter!.key] === flt) && (!q || JSON.stringify(r).toLowerCase().includes(q.toLowerCase()))), [rows, q, flt, def]);
  const sum = def.sumKey ? shown.reduce((s, r) => s + Number(r[def.sumKey!] || 0), 0) : null;
  const blank = () => Object.fromEntries(def.fields.map((f) => [f.key, f.def ?? (f.type === "bool" ? false : f.type === "matrix" ? {} : f.type === "date" ? new Date().toISOString().slice(0, 10) : "")]));
  const csv = () => {
    const esc = (s: any) => `"${String(s ?? "").replace(/"/g, '""')}"`;
    const out = [def.fields.map((f) => esc(f.label)).join(","), ...shown.map((r) => def.fields.map((f) => esc(r[f.key])).join(","))].join("\n");
    const a = document.createElement("a"); a.href = URL.createObjectURL(new Blob(["﻿" + out], { type: "text/csv" })); a.download = `${resource}.csv`; a.click();
  };
  const readOnly = resource.endsWith("log");
  const save = async (e: React.FormEvent) => { e.preventDefault(); if (await run(`/api/dashboard/r/${resource}`, { action: "save", data: edit })) setEdit(null); };
  return (
    <div className="m-card">
      <div className="flex flex-wrap items-center gap-3 border-b border-slate-100 p-3">
        <label className="relative min-w-[200px] flex-1 sm:max-w-xs"><Search size={15} className="absolute left-3 top-1/2 -translate-y-1/2 text-slate-400" /><input className="m-input !pl-9" placeholder={`Search ${def.title.toLowerCase()}…`} value={q} onChange={(e) => setQ(e.target.value)} /></label>
        {def.filter && <div className="flex flex-wrap gap-1.5">{["all", ...def.filter.options].map((o) => <button key={o} onClick={() => setFlt(o)} className={`chip ${flt === o ? "chip-on" : ""}`}>{o === "all" ? "All" : o[0].toUpperCase() + o.slice(1)}</button>)}</div>}
        <div className="ml-auto flex gap-2">{def.csv && <button className="m-btn" onClick={csv}><Download size={15} />CSV</button>}{!readOnly && <button className="m-btn m-btn-primary" onClick={() => { setError(""); setEdit(blank()); }}><Plus size={15} />Add {def.singular}</button>}</div>
      </div>
      {shown.length === 0 ? <div className="grid place-items-center px-4 py-14 text-center"><span className="grid h-11 w-11 place-items-center rounded-xl bg-slate-100 text-slate-400"><Inbox size={20} /></span><b className="mt-3 text-sm">{rows.length ? "No matches" : "No " + def.title.toLowerCase() + " yet"}</b><p className="mt-1 text-sm text-slate-500">{rows.length ? "Try a different search or filter." : def.empty}</p>{!rows.length && !readOnly && <button className="m-btn m-btn-primary mt-4" onClick={() => setEdit(blank())}><Plus size={15} />Add {def.singular}</button>}</div> :
        <div className="overflow-x-auto"><table className="tbl m-tbl"><thead><tr>{cols.map((c) => <th key={c.key}>{c.label}</th>)}<th /></tr></thead>
          <tbody>{shown.map((r) => <tr key={r.id}>{cols.map((c, i) => <td key={c.key} className={i === 0 ? "font-medium" : ""}>{c.type === "select" && c.key !== "kind" && c.key !== "type" ? <span className={`badge ${tone(String(r[c.key]))}`}>{fmt(c, r[c.key])}</span> : fmt(c, r[c.key])}</td>)}
            <td className="whitespace-nowrap text-right">{printHref && <a className="m-icon" aria-label="Print" href={`${printHref}/${r.id}`} target="_blank"><Printer size={14} /></a>}{!readOnly && <button className="m-icon" aria-label="Edit" onClick={() => { setError(""); setEdit({ ...r }); }}><Pencil size={14} /></button>}<button className="m-icon hover:!text-rose-600" aria-label="Delete" onClick={() => run(`/api/dashboard/r/${resource}`, { action: "delete", id: r.id }, { confirm: "Delete this " + def.singular + "?" })}><Trash2 size={14} /></button></td></tr>)}</tbody></table></div>}
      {sum !== null && shown.length > 0 && <div className="flex justify-end border-t border-slate-100 px-4 py-2.5 text-sm text-slate-500">Total <b className="ml-2 text-slate-900">৳{sum.toLocaleString("en-US")}</b></div>}
      <Modal open={!!edit} onClose={() => setEdit(null)} title={`${edit?.id ? "Edit" : "Add"} ${def.singular}`} wide>
        {edit && <form className="grid gap-4 sm:grid-cols-2" onSubmit={save}>
          {def.fields.filter((f) => !(f.hint?.includes("omputed")) ).map((f) => <div key={f.key} className={f.wide || f.type === "textarea" || f.type === "matrix" ? "sm:col-span-2" : ""}><FieldBox label={f.label + (f.required ? " *" : "")} hint={f.hint}>
            {f.type === "select" ? <select className="m-input" value={edit[f.key] ?? ""} onChange={(e) => setEdit({ ...edit, [f.key]: e.target.value })}>{f.options!.map((o) => <option key={o}>{o}</option>)}</select> :
              f.type === "textarea" ? <textarea className="m-input min-h-24" value={edit[f.key] ?? ""} onChange={(e) => setEdit({ ...edit, [f.key]: e.target.value })} /> :
              f.type === "bool" ? <label className="flex items-center gap-2 text-sm"><input type="checkbox" checked={!!edit[f.key]} onChange={(e) => setEdit({ ...edit, [f.key]: e.target.checked })} />Yes</label> :
              f.type === "matrix" ? <Matrix value={edit[f.key]} onChange={(v) => setEdit({ ...edit, [f.key]: v })} /> :
              <input className="m-input" required={f.required} type={f.type === "money" || f.type === "number" ? "number" : f.type === "date" ? "date" : f.type === "email" ? "email" : "text"} step="any" value={edit[f.key] ?? ""} onChange={(e) => setEdit({ ...edit, [f.key]: e.target.value })} />}</FieldBox></div>)}
          <div className="sm:col-span-2"><Alert>{error}</Alert></div>
          <div className="flex justify-end gap-2 sm:col-span-2"><button type="button" className="m-btn" onClick={() => setEdit(null)}>Cancel</button><button className="m-btn m-btn-primary" disabled={busy}>{busy ? "Saving…" : "Save"}</button></div>
        </form>}
      </Modal>
    </div>
  );
}
