import { useEffect, useMemo, useRef, useState } from 'react';
import { TOOLBAR_GEAR, TOOLBAR_FILTERS } from '@/Components/Table';
import { router } from '@inertiajs/react';
import { RotateCcw, Search, Settings } from 'lucide-react';
import AppLayout from '@/Layouts/AppLayout';
import { cn } from '@/lib/utils';
import { ListFooter } from '@/Components/Table/ListFooter';
import { StatusBadge } from '@/Components/Proto/UI/StatusBadge';
import { CustomizeColumnsModal } from '@/Components/Proto/Modals/CustomizeColumnsModal';
import { statusTone } from '@/lib/sampleOrderStatusTones';
import { SelectPill } from '@/Components/MenuQuotations/QuotationListPage/QuotationListPills';
import { useResizableColumns, ColumnResizeGrip } from '@/lib/useResizableColumns';
import { SortButton } from '@/lib/ClientSort';
import { useServerSortNav } from '@/lib/ServerSort';

// Sortable columns — id → row value (alphabetical A→Z on first click).
// Columns the SERVER can order by — must mirror the controller's SORT_COLUMNS.
// A column not listed here renders a plain label instead of a dead sort button.
const SORTABLE = new Set(['id', 'company', 'status', 'division', 'delivery', 'tanggal', 'sales', 'creator', 'awb', 'lines', 'comment']);

// ─────────────────────────────────────────────────────────────────────────────
// Feedback queue (PRD §6.13 / BR-23). Lists the actor's status-8 (Sample Received)
// sample orders awaiting feedback — the creator-only scope (UserIDInput = me;
// legacy-literal, a deliberate divergence from Good Issue's mine-or-admin) is
// enforced server-side. Click a row to open the feedback screen. UNWIRED until the
// controller + routes land: rendered by SampleOrderController@feedback via
// Inertia::render('MenuSampleOrders/Feedback/Index', [...]) and expects these route
// names (mirrors the Good Issue queue):
//   sample-orders.feedback        (GET  this queue)
//   sample-orders.feedback.show   (GET  the feedback screen for {id})
// Props (mirror the Good Issue / Surat Jalan queues):
//   sampleOrders: Laravel paginator → { data: [{ id, company, division, delivery,
//                 tanggal, sales, creator, awb, lines, comment }], current_page,
//                 last_page, per_page, from, to, total }  (lines = # status-5 items)
//   filters:      { search, division, sales, per_page }
//   filterOptions:{ divisions: [], sales: [] }
// ─────────────────────────────────────────────────────────────────────────────

const FILTER_PILLS = [
    { key: 'division', label: 'Division', opt: 'divisions' },
    { key: 'sales', label: 'Sales', opt: 'sales' },
];

// Column catalogue — `groupId` buckets the column inside the Customize Columns modal
// (hide + reorder); SO No stays `required` as the row anchor. Order here = default order.
const COLUMN_GROUPS = [
    { id: 'identifiers', label: 'Identifiers' },
    { id: 'metadata', label: 'Metadata' },
    { id: 'order', label: 'Order & Dates' },
];
const COLUMN_DEFS = [
    { id: 'id', label: 'SO No', groupId: 'identifiers', required: true },
    { id: 'company', label: 'Company', groupId: 'identifiers' },
    { id: 'status', label: 'Status', groupId: 'identifiers' },
    { id: 'division', label: 'Division', groupId: 'metadata' },
    { id: 'delivery', label: 'Delivery', groupId: 'order' },
    { id: 'tanggal', label: 'Date', groupId: 'order' },
    { id: 'sales', label: 'Sales', groupId: 'metadata' },
    { id: 'creator', label: 'Creator', groupId: 'metadata' },
    { id: 'awb', label: 'AWB', groupId: 'order' },
    { id: 'lines', label: 'Items', numeric: true, groupId: 'order' },
    { id: 'comment', label: 'Comment', groupId: 'order' },
];
const COL_W = {
    id: 110, company: 220, status: 140, division: 130, delivery: 130,
    tanggal: 130, sales: 130, creator: 130, awb: 150, lines: 110, comment: 220,
};
const COL_W_FALLBACK = 150;

// Per-column cell renderer — markup identical to the previous hardcoded <td>s.
function renderCell(so, colId) {
    switch (colId) {
        case 'id': return <span className="font-bold text-primary tabular-nums">#{so.id}</span>;
        case 'company': return so.company ? <span className="text-[12px] font-semibold text-foreground">{so.company}</span> : '—';
        case 'status': return so.status ? <StatusBadge tone={statusTone(so.status)}>{so.status}</StatusBadge> : '—';
        case 'division': return so.division ? <span className="inline-flex items-center rounded-full bg-secondary px-2 py-0.5 text-[10px] font-bold uppercase text-muted-foreground">{so.division}</span> : '—';
        case 'delivery': return so.delivery ? <span className="text-[11px] tabular-nums text-muted-foreground">{so.delivery}</span> : '—';
        case 'tanggal': return so.tanggal ? <span className="text-[11px] tabular-nums text-muted-foreground">{so.tanggal}</span> : '—';
        case 'sales': return so.sales || '—';
        case 'creator': return so.creator || '—';
        case 'awb': return so.awb ? <span className="text-[11px] tabular-nums text-muted-foreground">{so.awb}</span> : '—';
        case 'lines': return so.lines;
        case 'comment': return so.comment ? <span className="text-[11px] text-muted-foreground">{so.comment}</span> : '—';
        default: return null;
    }
}

// Column state = ordered [{id, visible}] — order AND visibility both persist.
const defaultColumnState = () => COLUMN_DEFS.map((d) => ({ id: d.id, visible: true }));
function loadColumnState(storageKey) {
    try {
        const raw = localStorage.getItem(storageKey);
        if (!raw) return defaultColumnState();
        const parsed = JSON.parse(raw).filter((c) => c && COLUMN_DEFS.some((d) => d.id === c.id));
        COLUMN_DEFS.forEach((d, i) => { if (!parsed.some((c) => c.id === d.id)) parsed.splice(i, 0, { id: d.id, visible: true }); });
        return parsed;
    } catch {
        return defaultColumnState();
    }
}

const EMPTY_PAGINATOR = { data: [], current_page: 1, last_page: 1, per_page: 10, from: 0, to: 0, total: 0 };

export default function SampleOrderFeedbackIndex({ sampleOrders = EMPTY_PAGINATOR, filters = {}, filterOptions = {} }) {
    // Server-side sort: the DATABASE orders the whole table, not the browser the page.
    const { sortKey, sortDir, toggleSort } = useServerSortNav('sample-orders.feedback', filters);
    const rows = sampleOrders.data ?? [];
    const pageSize = filters.per_page || 10;
    const currentPage = sampleOrders.current_page;
    const totalPages = sampleOrders.last_page;

    const [quickQuery, setQuickQuery] = useState(filters.search || '');
    const [openPill, setOpenPill] = useState(null);
    const filterBarRef = useRef(null);
    const searchDebounce = useRef(null);

    // One pill open at a time; click outside closes it.
    useEffect(() => {
        if (!openPill) return undefined;
        const onDoc = (e) => { if (filterBarRef.current && !filterBarRef.current.contains(e.target)) setOpenPill(null); };
        document.addEventListener('mousedown', onDoc);
        return () => document.removeEventListener('mousedown', onDoc);
    }, [openPill]);

    const buildParams = (overrides = {}) => {
        const params = {};
        const search = overrides.search ?? quickQuery;
        const perPage = overrides.per_page ?? pageSize;
        const page = overrides.page ?? currentPage;
        if (search) params.search = search;
        if (perPage && Number(perPage) !== 10) params.per_page = perPage;
        if (page && Number(page) !== 1) params.page = page;
        FILTER_PILLS.forEach(({ key }) => {
            const v = overrides[key] ?? filters[key] ?? '';
            if (v) params[key] = v;
        });
        return params;
    };
    // only: — see SampleOrders/List.jsx; `filters` drives the page size.
    const go = (overrides) => router.get(route('sample-orders.feedback'), buildParams(overrides), {
        only: ['sampleOrders', 'filters'],
        preserveState: true, preserveScroll: true, replace: true,
    });

    const onSearchChange = (val) => {
        setQuickQuery(val);
        clearTimeout(searchDebounce.current);
        searchDebounce.current = setTimeout(() => go({ search: val, page: 1 }), 300);
    };
    const setFilter = (key, value) => { setOpenPill(null); go({ [key]: value, page: 1 }); };
    const activeFilterCount = FILTER_PILLS.reduce((n, { key }) => n + (filters[key] ? 1 : 0), 0);
    const clearFilters = () => {
        setOpenPill(null);
        go(Object.fromEntries([...FILTER_PILLS.map(({ key }) => [key, '']), ['page', 1]]));
    };

    // Resizable columns — drag a header's right edge to resize.
    // Column show/hide + reorder, persisted per user (same grammar as View Details).
    const colDefById = useMemo(() => new Map(COLUMN_DEFS.map((d) => [d.id, d])), []);
    const storageKey = 'sampleOrderFeedbackColumns_v1';
    const [columnState, setColumnState] = useState(() => loadColumnState(storageKey));
    const [customizeOpen, setCustomizeOpen] = useState(false);
    const visibleCols = useMemo(() => columnState.filter((c) => c.visible).map((c) => colDefById.get(c.id)).filter(Boolean), [columnState, colDefById]);
    const isDefaultOrder = columnState.length === COLUMN_DEFS.length && columnState.every((c, i) => c.id === COLUMN_DEFS[i].id && c.visible);

    const persist = (next) => { try { localStorage.setItem(storageKey, JSON.stringify(next)); } catch { /* ignore */ } };
    const handleApplyColumns = (next) => { setColumnState(next); persist(next); };
    // Returns the default state so the modal's Reset can seed its draft with it.
    const resetCols = () => {
        const next = defaultColumnState();
        setColumnState(next);
        try { localStorage.removeItem(storageKey); } catch { /* ignore */ }
        return next;
    };

    // Header drag-to-reorder — drop one column title onto another; splices the same
    // columnState order and persists it (mirrors LwrListPage).
    const [dragColId, setDragColId] = useState(null);
    const [dragOverColId, setDragOverColId] = useState(null);
    const reorderCols = (fromId, toId) => {
        if (!fromId || !toId || fromId === toId) return;
        setColumnState((prev) => {
            const fi = prev.findIndex((c) => c.id === fromId);
            const ti = prev.findIndex((c) => c.id === toId);
            if (fi < 0 || ti < 0) return prev;
            const next = [...prev];
            const [moved] = next.splice(fi, 1);
            next.splice(ti, 0, moved);
            persist(next);
            return next;
        });
    };

    const { widthOf, startResize, resizingId, resizeRef } = useResizableColumns(COL_W, COL_W_FALLBACK);
    const tableWidth = useMemo(() => visibleCols.reduce((s, c) => s + widthOf(c.id), 0), [visibleCols, widthOf]);

    return (
        <section className="flex min-w-0 flex-col gap-[18px]">
            <header>
                <p className="m-0 mb-1.5 flex items-center gap-2 text-xs font-semibold text-muted-foreground">
                    <span>Sample Order</span>
                    <span aria-hidden="true">›</span>
                    <span className="text-foreground">Feedback</span>
                </p>
                <h1 className="m-0 text-xl font-bold leading-[1.2] text-card-foreground">Feedback — Sample Order</h1>
            </header>

            <article className="overflow-hidden rounded-2xl border border-border bg-card p-0 shadow-sm">
                {/* Toolbar: search far left, filter pills, count on the right. */}
                <div ref={filterBarRef} className="flex flex-wrap items-center gap-2.5 border-b border-border/50 p-[16px_22px]">
                    <label className="relative inline-flex h-8 min-w-[200px] max-w-[320px] flex-1 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" aria-label="Search feedback queue">
                        <Search aria-hidden="true" className="size-3.5 shrink-0" />
                        <input
                            type="search"
                            placeholder="Search SO No, Company, or AWB"
                            autoComplete="off"
                            value={quickQuery}
                            onChange={(e) => onSearchChange(e.target.value)}
                            className="min-w-0 flex-1 bg-transparent text-[12.5px] font-medium text-foreground outline-none placeholder:text-muted-foreground/70"
                        />
                    </label>
                    {/* ⚙ on line ONE: DOM position, not `order` — a flex line is filled in order
                        sequence and TOOLBAR_FILTERS is w-full. See TOOLBAR_ROW in Components/Table. */}
                    <button type="button" onClick={() => setCustomizeOpen(true)} title="Customize columns" aria-label="Customize columns"
                        className={TOOLBAR_GEAR}>
                        <Settings className="size-3.5" strokeWidth={2.5} />
                    </button>
                    <div className={TOOLBAR_FILTERS}>
                    {FILTER_PILLS.map(({ key, label, opt }) => (
                        <SelectPill
                            key={key}
                            label={label}
                            value={filters[key] || ''}
                            options={filterOptions[opt] || []}
                            open={openPill === key}
                            onToggle={() => setOpenPill(openPill === key ? null : key)}
                            onPick={(v) => setFilter(key, v)}
                        />
                    ))}
                    {activeFilterCount > 0 && (
                        <button type="button" onClick={clearFilters}
                            title="Reset all active filters"
                            className="inline-flex h-8 cursor-pointer items-center gap-1.5 rounded-full px-2.5 text-[12.5px] font-semibold text-muted-foreground transition-colors hover:bg-danger/10 hover:text-danger-text">
                            <RotateCcw className="size-3.5" />
                            <span>Reset filters</span>
                        </button>
                    )}
                    <div className="ml-auto inline-flex items-center gap-2">
                        {!isDefaultOrder && (
                            <button type="button" onClick={resetCols} title="Reset column order"
                                className="inline-flex h-8 items-center gap-1.5 rounded-full px-2.5 text-[12px] font-bold text-muted-foreground transition-colors hover:text-primary">
                                <RotateCcw className="size-3.5" /> Reset
                            </button>
                        )}
                    </div>
                    </div>
                </div>
                <div className="overflow-x-auto">
                    <table style={{ minWidth: tableWidth }} className="w-full table-fixed border-separate border-spacing-0 [&_tbody_td]:overflow-hidden [&_tbody_td]:whitespace-nowrap [&_tbody_td]:border-b [&_tbody_td]:border-border/60 [&_tbody_td]:px-[14px] [&_tbody_td]:py-[16px] [&_tbody_td]:text-[12px] [&_tbody_td]:text-card-foreground [&_tbody_td:first-child]:pl-7 [&_tbody_td:last-child]:pr-5 [&_tbody_tr]:cursor-pointer [&_tbody_tr]:even:bg-secondary/25 [&_tbody_tr:hover]:bg-secondary/60 [&_tbody_tr:last-child_td]:border-b-0 [&_thead_th]:whitespace-nowrap [&_thead_th]:bg-[color-mix(in_srgb,var(--color-secondary)_50%,var(--color-card))] [&_thead_th]:p-[11px_14px] [&_thead_th]:text-left [&_thead_th]:text-[11px] [&_thead_th]:font-semibold [&_thead_th]:uppercase [&_thead_th]:tracking-wide [&_thead_th]:text-muted-foreground [&_thead_th:first-child]:rounded-l-full [&_thead_th:first-child]:pl-7 [&_thead_th:last-child]:rounded-r-full [&_thead_th:last-child]:pr-5">
                        <colgroup>
                            {visibleCols.map((col) => <col key={col.id} style={{ width: widthOf(col.id) }} />)}
                        </colgroup>
                        <thead>
                            <tr>
                                {visibleCols.map((col) => (
                                    <th key={col.id}
                                        draggable
                                        onDragStart={(e) => { if (resizeRef.current) { e.preventDefault(); return; } setDragColId(col.id); }}
                                        onDragOver={(e) => { e.preventDefault(); setDragOverColId(col.id); }}
                                        onDrop={() => { reorderCols(dragColId, col.id); setDragColId(null); setDragOverColId(null); }}
                                        onDragEnd={() => { setDragColId(null); setDragOverColId(null); }}
                                        title="Drag to reorder"
                                        className={cn('group/col relative cursor-grab select-none active:cursor-grabbing', col.numeric && '!text-right',
                                            dragColId === col.id && 'opacity-40',
                                            dragOverColId === col.id && dragColId !== col.id && '!bg-accent !text-primary')}>
                                        {SORTABLE.has(col.id) ? <SortButton id={col.id} label={col.label} sortKey={sortKey} sortDir={sortDir} onToggle={toggleSort} /> : col.label}
                                        <ColumnResizeGrip onMouseDown={(e) => startResize(e, col.id)} active={resizingId === col.id} />
                                    </th>
                                ))}
                            </tr>
                        </thead>
                        <tbody>
                            {rows.length === 0 ? (
                                <tr className="!cursor-default">
                                    <td colSpan={visibleCols.length} className="p-[28px_16px] text-center italic text-muted-foreground">
                                        No sample orders waiting for feedback.
                                    </td>
                                </tr>
                            ) : (
                                rows.map((so) => (
                                    <tr key={so.id} onClick={() => router.visit(route('sample-orders.feedback.show', so.id))}>
                                        {visibleCols.map((col) => (
                                            <td key={col.id} className={cn(
                                                col.numeric && 'text-right font-bold tabular-nums',
                                                col.id === 'comment' && 'max-w-[220px] truncate',
                                            )}>
                                                {renderCell(so, col.id)}
                                            </td>
                                        ))}
                                    </tr>
                                ))
                            )}
                        </tbody>
                    </table>
                </div>

                {/* Footer — design-system ListFooter (Showing · ghost pager · rows-per-page) */}
                <ListFooter
                    page={currentPage} totalPages={totalPages} onPage={(p) => go({ page: p })}
                    pageSize={Number(pageSize)} onPageSize={(n) => go({ per_page: n, page: 1 })} pageSizeOptions={[5, 10, 15, 20]}
                    total={sampleOrders.total} from={sampleOrders.from} to={sampleOrders.to} itemLabel="entries"
                />
            </article>

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

SampleOrderFeedbackIndex.layout = [AppLayout];
