import { useEffect, useMemo, useRef, useState } from 'react';
import { Link } from '@inertiajs/react';
import { ChevronLeft, ChevronRight, Search } from 'lucide-react';
import { FilterPill } from '@/Components/ui/filter-pill';
import { MultiOptionPill } from '@/Components/MenuCompanies/MarketSurvey/MultiOptionPill';
import { ExportButton } from '@/lib/excel/ExportButton';
import { useClientSort, SortButton } from '@/lib/ClientSort';
import { useColumnPrefs } from '@/lib/useColumnPrefs';
import { useResizableColumns, ColumnResizeGrip } from '@/lib/useResizableColumns';

// Sortable columns — id → RAW row value. The product cells sort on their
// "principal / product" text (one product per row, matching what is displayed).
const SORT_GETTERS = {
    company: (r) => r.company,
    sales: (r) => r.sales,
    division: (r) => r.division,
    application: (r) => r.application,
    cc: (r) => [r.cc?.principal, r.cc?.product].filter(Boolean).join(' / '),
    comp: (r) => [r.comp?.principal, r.comp?.product].filter(Boolean).join(' / '),
};

// Data-driven columns (default order left→right) + default widths for the table-fixed
// layout. Headers are drag-to-reorder (all data columns — nothing pinned here).
const COLUMN_DEFS = [
    { id: 'company', label: 'Company Name', required: true }, // row anchor
    { id: 'sales', label: 'Sales Name' },
    { id: 'division', label: 'Division' },
    { id: 'application', label: 'Application' },
    { id: 'cc', label: 'Product CC' },
    { id: 'comp', label: 'Product Comp' },
];
const COL_W = { company: 190, sales: 150, division: 120, application: 150, cc: 250, comp: 250 };
const TD_CLASS = {
    company: 'whitespace-nowrap font-semibold text-foreground',
    sales: 'whitespace-nowrap',
    division: 'whitespace-nowrap',
    application: 'whitespace-nowrap',
    cc: '!whitespace-normal',
    comp: '!whitespace-normal',
};

// One product cell (CC or Comp). Renders principal / product + volume & price lines, each with
// its own unit — faithful to the legacy view (Volume/Month : <v> <unit> / Price ($) : <p> /<unit>).
function ProductBlock({ p }) {
    if (!p || (!p.product && !p.principal)) return <span className="text-muted-foreground/70">/</span>;
    return (
        <div className="leading-snug">
            <div className="font-semibold text-foreground">{p.principal || '—'} / {p.product || '—'}</div>
            <div className="text-[11px] text-muted-foreground tabular-nums">Volume/Month : {p.volume}{p.volumeUnit ? ` ${p.volumeUnit}` : ''}</div>
            <div className="text-[11px] text-muted-foreground tabular-nums">Price ($) : {p.price} /{p.priceUnit || ''}</div>
        </div>
    );
}

// Per-column cell renderer — markup identical to the previous hardcoded <td>s.
function renderCell(r, colId) {
    switch (colId) {
        case 'company': return r.company || '—';
        case 'sales': return r.sales || '—';
        case 'division': return r.division || '—';
        case 'application': return r.application || '—';
        case 'cc': return <ProductBlock p={r.cc} />;
        case 'comp': return <ProductBlock p={r.comp} />;
        default: return null;
    }
}

/**
 * Shared body for the three Market Survey list views. Receives the full scoped dataset (`rows`)
 * + dropdown `filterOptions`; filters + paginates client-side (proto behaviour). The CC Principal
 * filter matches `cc.principalId` only — faithful to the legacy `cp.CCPrincipalID IN (...)`.
 */
export default function MarketSurveyListPage({ rows = [], filterOptions = {}, title, heading, breadcrumbLabel }) {
    const { divisions = [], companies = [], principals = [] } = filterOptions;

    // Multi-select (user decision 2026-08-20). These carry option IDs, not names, so the
    // predicate below still compares numerically — CC Principal was already multi.
    const [division, setDivision] = useState([]);
    const [company, setCompany] = useState([]);
    const [selectedPrincipals, setSelectedPrincipals] = useState([]);
    const [query, setQuery] = useState('');
    const [page, setPage] = useState(1);
    const [openPill, setOpenPill] = useState(null);
    const filterBarRef = useRef(null);
    const pageSize = 10;

    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 hasFilter = Boolean(query || division.length || company.length || selectedPrincipals.length);

    const filtered = useMemo(() => {
        const s = query.trim().toLowerCase();
        const princSet = new Set(selectedPrincipals.map(Number));
        return rows.filter((r) => {
            if (division.length && !division.some((d) => Number(d) === Number(r.divisionId))) return false;
            if (company.length && !company.some((c) => Number(c) === Number(r.companyId))) return false;
            // Legacy filters on CCPrincipalID only.
            if (princSet.size && !princSet.has(Number(r.cc?.principalId))) return false;
            if (s) {
                const hay = `${r.company ?? ''} ${r.sales ?? ''} ${r.division ?? ''} ${r.application ?? ''} ${r.cc?.principal ?? ''} ${r.cc?.product ?? ''} ${r.comp?.principal ?? ''} ${r.comp?.product ?? ''}`.toLowerCase();
                if (!hay.includes(s)) return false;
            }
            return true;
        });
    }, [rows, division, company, selectedPrincipals, query]);

    // Sort the filtered set BEFORE the pagination slice; resizable columns (house pattern).
    const { sorted, sortKey, sortDir, toggleSort } = useClientSort(filtered, SORT_GETTERS);
    const { widthOf, startResize, resizingId, resizeRef } = useResizableColumns(COL_W);
    // Column order — persisted (shared by the three Market Survey views); headers drag-to-reorder.
    const prefs = useColumnPrefs('marketSurveyColumns_v1', COLUMN_DEFS, { resizeGuardRef: resizeRef });
    const tableWidth = useMemo(() => prefs.visibleCols.reduce((sum, c) => sum + widthOf(c.id), 0), [prefs.visibleCols, widthOf]);

    const totalPages = Math.max(1, Math.ceil(filtered.length / pageSize));
    const currentPage = Math.min(page, totalPages);
    const pageRows = sorted.slice((currentPage - 1) * pageSize, currentPage * pageSize);

    const togglePrincipal = (id) => {
        const n = Number(id);
        setSelectedPrincipals((prev) => (prev.map(Number).includes(n) ? prev.filter((x) => Number(x) !== n) : [...prev, n]));
        setPage(1);
    };

    const resetFilters = () => { setDivision([]); setCompany([]); setSelectedPrincipals([]); setQuery(''); setPage(1); };

    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">
                    <Link href={route('companies.index')} className="no-underline hover:text-primary">Companies</Link>
                    <span aria-hidden="true">›</span>
                    <span className="text-foreground">{breadcrumbLabel}</span>
                </p>
                <h1 className="m-0 text-xl font-bold leading-[1.2] text-card-foreground">{title}</h1>
            </header>

            {/* Filter bar + list — one merged card */}
            <article className="overflow-hidden rounded-2xl border border-border bg-card shadow-sm">
                <div ref={filterBarRef} className="flex flex-wrap items-center gap-2.5 border-b border-border/50 px-5 py-4">
                    <label className="relative inline-flex h-8 w-[280px] max-w-full 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 market survey">
                        <Search aria-hidden="true" className="size-3.5 shrink-0" />
                        <input type="search" placeholder="Search company, sales, product…" autoComplete="off" value={query}
                            onChange={(e) => { setQuery(e.target.value); setPage(1); }}
                            className="min-w-0 flex-1 bg-transparent text-[12.5px] font-medium text-foreground outline-none placeholder:text-muted-foreground/70" />
                    </label>
                    <FilterPill label="Division" value={division} options={divisions}
                        onChange={(v) => { setDivision(v); setPage(1); }} />
                    <FilterPill label="Company" value={company} options={companies}
                        onChange={(v) => { setCompany(v); setPage(1); }} />
                    <MultiOptionPill label="CC Principal" values={selectedPrincipals} options={principals} searchable
                        open={openPill === 'principal'} onToggle={() => setOpenPill(openPill === 'principal' ? null : 'principal')}
                        onToggleValue={togglePrincipal} onClear={() => { setSelectedPrincipals([]); setPage(1); }} />
                    {hasFilter && (
                        <button type="button" onClick={resetFilters}
                            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">Reset filters</button>
                    )}
                    {/* Client-side export: the full scoped set is already in memory; export the
                        currently-FILTERED rows (what the user sees). No server endpoint. */}
                    <ExportButton specKey="marketSurveyExport" rows={filtered} className="ml-auto h-8 px-3 text-xs" />
                </div>

                <header className="flex flex-wrap items-center justify-between gap-3 border-b border-border px-5 py-4">
                    <h2 className="m-0 text-sm font-extrabold leading-[1.2] text-card-foreground">{heading}</h2>
                    <span className="text-[11px] font-semibold text-muted-foreground">{filtered.length} result{filtered.length === 1 ? '' : 's'}</span>
                </header>

                <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]:border-b [&_tbody_td]:border-border/60 [&_tbody_td]:px-3.5 [&_tbody_td]:py-[16px] [&_tbody_td]:align-top [&_tbody_td]:text-[12px] [&_tbody_td]:text-card-foreground [&_tbody_tr:last-child_td]:border-b-0 [&_tbody_tr:nth-child(even)_td]:bg-secondary/25 [&_tbody_tr:hover_td]:bg-secondary/60 [&_thead_th]:whitespace-nowrap [&_thead_th]:bg-[color-mix(in_srgb,var(--color-secondary)_50%,var(--color-card))] [&_thead_th]:px-3.5 [&_thead_th]:py-3 [&_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 [&_tbody_td:first-child]:pl-7 [&_thead_th:last-child]:rounded-r-full [&_thead_th:last-child]:pr-5 [&_tbody_td:last-child]:pr-5">
                        <colgroup>
                            {prefs.visibleCols.map((col) => <col key={col.id} style={{ width: widthOf(col.id) }} />)}
                        </colgroup>
                        <thead>
                            <tr>
                                {prefs.visibleCols.map((col) => (
                                    <th key={col.id} {...prefs.dragProps(col.id)} className={`group/col relative ${prefs.dragClass(col.id)}`}>
                                        <SortButton id={col.id} label={col.label} sortKey={sortKey} sortDir={sortDir} onToggle={toggleSort} />
                                        <ColumnResizeGrip onMouseDown={(e) => startResize(e, col.id)} active={resizingId === col.id} />
                                    </th>
                                ))}
                            </tr>
                        </thead>
                        <tbody>
                            {pageRows.length === 0 ? (
                                <tr>
                                    <td colSpan={prefs.visibleCols.length} className="px-4 py-10 text-center italic text-muted-foreground">No market survey rows match the filter.</td>
                                </tr>
                            ) : (
                                pageRows.map((r) => (
                                    <tr key={r.id}>
                                        {prefs.visibleCols.map((col) => (
                                            <td key={col.id} className={TD_CLASS[col.id]}>
                                                {renderCell(r, col.id)}
                                            </td>
                                        ))}
                                    </tr>
                                ))
                            )}
                        </tbody>
                    </table>
                </div>

                {/* Pagination footer */}
                <div className="flex flex-wrap items-center justify-between gap-4 border-t border-border px-5 py-4">
                    <nav className="inline-flex items-center gap-1" aria-label="Pagination">
                        <button type="button" disabled={currentPage === 1} onClick={() => setPage((p) => Math.max(1, p - 1))}
                            className="inline-grid size-8 place-items-center rounded-md border border-border bg-card text-foreground disabled:cursor-not-allowed disabled:opacity-50 enabled:hover:border-primary enabled:hover:text-primary">
                            <ChevronLeft className="size-3.5" />
                        </button>
                        {Array.from({ length: totalPages }, (_, n) => n + 1).map((p) => (
                            <button key={p} type="button" onClick={() => setPage(p)}
                                className={`inline-grid size-8 place-items-center rounded-md border px-2 text-xs font-medium tabular-nums ${p === currentPage ? 'border-transparent bg-linear-to-br from-violet-500 to-primary font-bold text-primary-foreground shadow-sm hover:brightness-105' : 'border-border bg-card text-foreground hover:border-primary hover:text-primary'}`}>
                                {p}
                            </button>
                        ))}
                        <button type="button" disabled={currentPage === totalPages} onClick={() => setPage((p) => Math.min(totalPages, p + 1))}
                            className="inline-flex h-8 items-center gap-1 rounded-md border border-border bg-card px-2.5 text-xs font-medium text-foreground disabled:cursor-not-allowed disabled:opacity-50 enabled:hover:border-primary enabled:hover:text-primary">
                            Next <ChevronRight className="size-3.5" />
                        </button>
                    </nav>
                    <span className="text-xs font-medium text-muted-foreground">Page {currentPage} of {totalPages}</span>
                </div>
            </article>
        </section>
    );
}
