import { useState } from 'react';
import { Link, router } from '@inertiajs/react';
import { RotateCcw, Search, Settings } from 'lucide-react';
import AppLayout from '@/Layouts/AppLayout';
import { OptionPill, DateRangePill } from '@/Components/MenuQuotations/QuotationListPage/QuotationListPills';
import { ListFooter } from '@/Components/Table/ListFooter';
import { SortButton } from '@/lib/ClientSort';
import { useServerSortNav } from '@/lib/ServerSort';
import { useColumnPrefs } from '@/lib/useColumnPrefs';
import { splitDateTime } from '@/Components/Proto/UI/DateText';
import { CustomizeColumnsModal } from '@/Components/Proto/Modals/CustomizeColumnsModal';
import { useResizableColumns, ColumnResizeGrip } from '@/lib/useResizableColumns';

// ─────────────────────────────────────────────────────────────────────────────
// Relabel History — wires legacy printlabelnsproducthistory.php (+ its view). Look
// follows Proto RelabelHistory; data follows legacy. Server-driven: filter/paginate
// go through PrintLabelController@history via Inertia partial reload (only: rows+filters),
// so the dropdown `options` closure prop is only computed on the initial load.
//   Inertia::render('MenuPrintLabel/RelabelHistory', { rows, filters, options })
// ─────────────────────────────────────────────────────────────────────────────

const EMPTY_PAGINATOR = { data: [], current_page: 1, last_page: 1, per_page: 10, from: 0, to: 0, total: 0 };
const CARD = 'rounded-2xl border border-border bg-card shadow-sm';
const TH = 'whitespace-nowrap bg-secondary/50 px-3.5 py-3 text-left text-[11px] font-semibold uppercase tracking-wide text-muted-foreground';

// Columns (default order left→right) — id + header label; No is the row number
// (not sortable, and pinned out of the header drag-to-reorder).
const COLUMN_GROUPS = [{ id: 'label', label: 'Label' }];
const COLUMN_DEFS = [
    { id: 'no', label: 'No', groupId: 'label' },
    { id: 'createDate', label: 'Create Date', groupId: 'label' },
    { id: 'product', label: 'Product / Print', required: true, groupId: 'label' }, // row anchor
    { id: 'principal', label: 'Principal', groupId: 'label' },
    { id: 'creator', label: 'Creator', groupId: 'label' },
    { id: 'lot', label: 'Lot Number / Print', groupId: 'label' },
    { id: 'gross', label: 'Gross', groupId: 'label' },
    { id: 'nett', label: 'Nett', groupId: 'label' },
    { id: 'origin', label: 'Origin', groupId: 'label' },
    { id: 'mfg', label: 'Mfg Date', groupId: 'label' },
    { id: 'exp', label: 'Expiry', groupId: 'label' },
    { id: 'page', label: 'Page', groupId: 'label' },
];

// Sortable columns — id → RAW row value (data columns only).
// Columns the SERVER can order by — must mirror PrintLabelController::HISTORY_SORT_COLUMNS.
// A column not listed here renders a plain label instead of a dead sort button.
const SORTABLE = new Set(['createDate', 'product', 'principal', 'creator', 'lot', 'gross', 'nett', 'origin', 'mfg', 'exp', 'page']);

// Default column widths (px) for the resizable table-fixed layout.
// createDate holds "YYYY-MM-DD HH:MM:SS" (19 chars) — at 120px the seconds were clipped by
// the `overflow-hidden` on td, so it reads 155px wide.
const COL_W = { no: 70, createDate: 178, product: 200, principal: 140, creator: 140, lot: 200, gross: 100, nett: 100, origin: 110, mfg: 135, exp: 135, page: 90 };

// "primary / print" — collapses to one line when both halves are identical (Proto A3#1).
function Pair({ a, b }) {
    return (
        <span className="block leading-tight">
            <span className="font-semibold text-foreground">{a || '—'}</span>
            {b && b !== a ? <span className="block text-[11px] text-muted-foreground">{b}</span> : null}
        </span>
    );
}

const em = <span className="text-muted-foreground/40">—</span>;

// Per-column td classes + cell renderer — markup identical to the previous hardcoded <td>s.
const TD_CLASS = {
    no: 'pl-5 tabular-nums text-muted-foreground',
    createDate: 'whitespace-nowrap tabular-nums text-muted-foreground',
    product: 'min-w-[150px]',
    principal: 'whitespace-nowrap',
    lot: 'min-w-[200px] tabular-nums',
    gross: 'whitespace-nowrap',
    nett: 'whitespace-nowrap font-medium',
    mfg: 'whitespace-nowrap tabular-nums text-muted-foreground',
    exp: 'whitespace-nowrap tabular-nums text-muted-foreground',
};
const validDate = (v) => v && v !== '0000-00-00';

// This list is dense (12 columns); the shared <DateText> stacks the time under the date and
// would make every row two lines tall. Same house format, laid out inline instead.
function DateInline({ value }) {
    const { date, time } = splitDateTime(value);
    return (
        <span className="inline-flex items-baseline gap-1.5 whitespace-nowrap">
            <span className="font-medium tabular-nums text-foreground">{date}</span>
            {time && <span className="text-[11px] tabular-nums text-muted-foreground">{time}</span>}
        </span>
    );
}

function renderCell(r, colId, ctx) {
    switch (colId) {
        case 'no': return ctx.rowNumber;
        case 'createDate': return r.createDate ? <DateInline value={r.createDate} /> : em;
        case 'product': return <Pair a={r.product} b={r.productPrint} />;
        case 'principal': return r.principal || em;
        case 'creator': return r.creator || em;
        case 'lot': return <Pair a={r.lot} b={r.lotPrint} />;
        case 'gross': return r.gross || em;
        case 'nett': return r.nett || em;
        case 'origin': return r.origin || em;
        case 'mfg': return validDate(r.mfg) ? <DateInline value={r.mfg} /> : em;
        case 'exp': return validDate(r.exp) ? <DateInline value={r.exp} /> : em;
        case 'page': return <span className="inline-flex rounded-md bg-secondary px-2 py-0.5 text-[11px] font-medium text-muted-foreground">{r.page}</span>;
        default: return null;
    }
}

export default function RelabelHistory({ rows = EMPTY_PAGINATOR, filters = {}, options = {} }) {
    const [f, setF] = useState({
        q: filters.q || '',
        early: filters.early || '',
        end: filters.end || '',
        creator: filters.creator ? String(filters.creator) : '',
        product: filters.product ? String(filters.product) : '',
    });
    const [dateOpen, setDateOpen] = useState(false);

    // Client-side sort over the current server page + resizable columns (house pattern).
    // Server-side sort: the DATABASE orders the whole table, not the browser the page.
    const { sortKey, sortDir, toggleSort } = useServerSortNav('print-label.history', filters);
    const data = rows.data ?? [];
    const { widthOf, startResize, resizingId, resizeRef } = useResizableColumns(COL_W);
    // Column order — persisted; direct header drag-to-reorder ("No" pinned via fixedIds).
    const prefs = useColumnPrefs('relabelHistoryColumns_v1', COLUMN_DEFS, { resizeGuardRef: resizeRef, fixedIds: ['no'] });
    const [customizeOpen, setCustomizeOpen] = useState(false);
    const tableWidth = prefs.visibleCols.reduce((sum, c) => sum + widthOf(c.id), 0);
    const perPage = Number(filters.per_page || 10);
    const from = rows.from || 0;

    // Server visit with Inertia partial reload — only rows + echoed filters refresh.
    const visit = (state, overrides = {}) => {
        const cur = { ...state, ...overrides };
        const params = {};
        if (cur.q) params.q = cur.q;
        if (cur.early) params.early = cur.early;
        if (cur.end) params.end = cur.end;
        if (cur.creator) params.creator = cur.creator;
        if (cur.product) params.product = cur.product;
        const pp = overrides.per_page ?? perPage;
        if (pp && Number(pp) !== 10) params.per_page = pp;
        if (overrides.page && Number(overrides.page) !== 1) params.page = overrides.page;
        router.get(route('print-label.history'), params, {
            only: ['rows', 'filters'], preserveState: true, preserveScroll: true, replace: true,
        });
    };

    // Picking a filter reloads immediately (list-page grammar) — no Search button.
    const apply = (patch) => {
        const next = { ...f, ...patch };
        setF(next);
        visit(next, { page: 1 });
    };
    const reset = () => {
        const empty = { q: '', early: '', end: '', creator: '', product: '' };
        setF(empty);
        visit(empty, { page: 1 });
    };
    const hasFilter = Boolean(f.q || f.early || f.end || f.creator || f.product);

    return (
        <section className="flex min-w-0 flex-col gap-5">
            <header>
                <p className="m-0 mb-1.5 flex items-center gap-2 text-xs font-semibold text-muted-foreground">
                    <span>Print Label CC Product</span>
                    <span aria-hidden="true">›</span>
                    <span className="text-foreground">Relabel History</span>
                </p>
                <h1 className="m-0 text-2xl font-bold leading-[1.15] tracking-tight text-card-foreground">Relabel History</h1>
            </header>

            {/* Tabs: active batch vs print history — mirrors PrintRelabel.jsx (same strip, History active). */}
            <div className="flex items-center gap-6 border-b border-border">
                <Link href={route('print-label.relabel')} className="flex h-9 items-center text-sm font-medium text-muted-foreground no-underline transition-colors hover:text-foreground">
                    Active Batch
                </Link>
                <span className="relative flex h-9 items-center text-sm font-semibold text-primary">
                    History
                    <span className="absolute inset-x-0 -bottom-px h-0.5 rounded-full bg-primary" aria-hidden="true" />
                </span>
            </div>

            {/* One card: compact filter toolbar sits straight on top of the table (list-page
                grammar). Picking a pill reloads immediately — the old separate "Search" card with
                its own Search button is gone; its h2 only repeated the page title. */}
            <article className={`${CARD} overflow-hidden`}>
                <div className="flex flex-wrap items-center gap-2 px-4 py-3">
                    <label className="relative inline-flex h-8 w-[240px] items-center gap-2 rounded-full border border-transparent bg-muted/60 px-3.5 text-muted-foreground transition-colors hover:bg-muted focus-within:border-primary/40 focus-within:bg-card">
                        <Search aria-hidden="true" className="size-3.5 shrink-0" />
                        <input
                            type="search"
                            placeholder="Search product / lot / principal…"
                            autoComplete="off"
                            value={f.q}
                            onChange={(e) => setF((prev) => ({ ...prev, q: e.target.value }))}
                            onKeyDown={(e) => { if (e.key === 'Enter') apply({ q: f.q }); }}
                            className="min-w-0 flex-1 bg-transparent text-[12.5px] font-medium text-foreground outline-none placeholder:text-muted-foreground/70"
                        />
                    </label>
                    <DateRangePill
                        label="Create Date"
                        from={f.early}
                        to={f.end}
                        open={dateOpen}
                        onToggle={() => setDateOpen((o) => !o)}
                        onApply={(from, to) => { setDateOpen(false); apply({ early: from, end: to }); }}
                    />
                    <OptionPill label="Creator" value={f.creator} options={options.creators ?? []} onPick={(v) => apply({ creator: v })} />
                    <OptionPill label="Product" value={f.product} options={options.products ?? []} onPick={(v) => apply({ product: v })} />
                    {hasFilter && (
                        <button type="button" onClick={reset}
                            className="inline-flex h-8 items-center gap-1.5 rounded-full px-2.5 text-[12.5px] font-semibold text-muted-foreground transition-colors hover:text-primary">
                            <RotateCcw className="size-3" /> Reset filters
                        </button>
                    )}
                    <div className="ml-auto">
                        <button type="button" onClick={() => setCustomizeOpen(true)} title="Customize columns (hide & reorder)" aria-label="Customize columns"
                            className="grid size-7 place-items-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-primary">
                            <Settings className="size-3.5" strokeWidth={2.5} />
                        </button>
                    </div>
                </div>
                <div className="overflow-x-auto">
                    <table className="w-full table-fixed border-separate border-spacing-0" style={{ minWidth: tableWidth }}>
                        <colgroup>
                            {prefs.visibleCols.map((c) => <col key={c.id} style={{ width: widthOf(c.id) }} />)}
                        </colgroup>
                        <thead>
                            <tr>
                                {prefs.visibleCols.map((c, i, arr) => (
                                    <th key={c.id} {...prefs.dragProps(c.id)}
                                        className={`${TH} group/col relative ${i === 0 ? 'rounded-l-full pl-7' : ''} ${i === arr.length - 1 ? 'rounded-r-full pr-5' : ''} ${prefs.dragClass(c.id)}`}>
                                        {SORTABLE.has(c.id)
                                            ? <SortButton id={c.id} label={c.label} sortKey={sortKey} sortDir={sortDir} onToggle={toggleSort} />
                                            : c.label}
                                        <ColumnResizeGrip onMouseDown={(e) => startResize(e, c.id)} active={resizingId === c.id} />
                                    </th>
                                ))}
                            </tr>
                        </thead>
                        <tbody>
                            {data.length === 0 ? (
                                <tr><td colSpan={prefs.visibleCols.length} className="px-4 py-12 text-center text-[13px] text-muted-foreground">Tidak ada riwayat untuk filter ini.</td></tr>
                            ) : data.map((r, i) => (
                                <tr key={r.id} className="[&_td]:overflow-hidden [&_td]:border-b [&_td]:border-border/60 [&_td]:px-3.5 [&_td]:py-[16px] [&_td:first-child]:pl-7 [&_td:last-child]:pr-5 [&_td]:align-top [&_td]:text-[12px] last:[&_td]:border-b-0 [&_td]:text-foreground even:[&_td]:bg-secondary/25 hover:[&_td]:bg-secondary/60">
                                    {prefs.visibleCols.map((c) => (
                                        <td key={c.id} className={TD_CLASS[c.id]}>
                                            {renderCell(r, c.id, { rowNumber: from + i })}
                                        </td>
                                    ))}
                                </tr>
                            ))}
                        </tbody>
                    </table>
                </div>
                <ListFooter
                    page={rows.current_page} totalPages={rows.last_page} onPage={(p) => visit(f, { page: p })}
                    pageSize={perPage} onPageSize={(n) => visit(f, { per_page: n, page: 1 })} pageSizeOptions={[10, 20, 50, 100]}
                    total={rows.total ?? 0} itemLabel="labels" />
            </article>

            <CustomizeColumnsModal
                open={customizeOpen}
                onClose={() => setCustomizeOpen(false)}
                groups={COLUMN_GROUPS}
                definitions={COLUMN_DEFS}
                state={prefs.columnState}
                onApply={prefs.applyColumns}
                onReset={prefs.resetColumns}
            />
        </section>
    );
}

RelabelHistory.layout = [AppLayout];
