import { useEffect, useMemo, useState } from 'react'
import { Link, router, usePage } from '@inertiajs/react'
import { ChevronRight, RotateCcw, Search, Settings } from 'lucide-react'
import { CustomizeColumnsModal } from '@/Components/Proto/Modals/CustomizeColumnsModal'
import { useColumnPrefs } from '@/lib/useColumnPrefs'
import AppLayout from '@/Layouts/AppLayout'
import { FilterPill } from '@/Components/ui/filter-pill'
import { ListFooter } from '@/Components/Table/ListFooter'
import { TOOLBAR_GEAR, TOOLBAR_FILTERS } from '@/Components/Table'
import { StatusBadge } from '@/Components/Proto/UI/StatusBadge'
import { DateText } from '@/Components/Proto/UI/DateText'
import { useResizableColumns, ColumnResizeGrip } from '@/lib/useResizableColumns'
import { useServerSort, SortButton } from '@/lib/ServerSort'
import { stripDefaults } from '@/lib/listParams'
import { complaintTypeTone } from '@/lib/complaintTone'

// Sortable header ids — MUST mirror LoadsComplainDetail::SORT_COLUMNS. `status` is omitted on
// purpose: every row in this queue is at Done, so the column is not rendered here.
const SORTABLE = new Set([
    'reportNo', 'complainType', 'company', 'creator',
    'division', 'complainDate', 'inputDate', 'address', 'telp',
])

// A pill's value travels as a comma-separated list of IDS, never display names — a CompanyName
// can itself contain a comma. See ViewRequest/Index.jsx for the full note.
const idsOf = (csv) => (csv ? String(csv).split(',').filter(Boolean).map(Number) : [])

const RELOAD = { only: ['complaints', 'filters'], preserveState: true, preserveScroll: true, replace: true }

// Complaint & Returns — Close (menu 256, legacy listcomplainsearchclose.php): every complaint
// at status 4 ("Done"), to anyone holding the menu grant (PRD §4.2, §6.4). Same merged
// filter-bar + list grammar as the five list scopes (ViewRequest/Index), and like them it now
// searches, filters, sorts and pages on the SERVER (ATURAN #26, GH #447). No Status column:
// everything in this queue is at Done by definition.
// Data-driven columns — ⚙ opens CustomizeColumnsModal (hide/show + reorder), headers
// are also drag-to-reorder directly. Default widths feed the table-fixed layout.
const COLUMN_GROUPS = [{ id: 'queue', label: 'Queue' }]
const COLUMN_DEFS = [
    { id: 'reportNo', label: 'Report No', groupId: 'queue', required: true }, // row anchor
    { id: 'details', label: 'Details', groupId: 'queue' },
    { id: 'complainType', label: 'Complain Type', groupId: 'queue' },
    { id: 'company', label: 'Company Name', groupId: 'queue' },
    { id: 'creator', label: 'Creator', groupId: 'queue' },
    { id: 'division', label: 'Division', groupId: 'queue' },
    { id: 'complainDate', label: 'Complain Date', groupId: 'queue' },
    { id: 'inputDate', label: 'Input Date', groupId: 'queue' },
    { id: 'address', label: 'Address', groupId: 'queue' },
    { id: 'telp', label: 'Telp', groupId: 'queue' },
]
const COL_W = {
    reportNo: 110, details: 110, complainType: 150, company: 220,
    creator: 150, division: 130, complainDate: 150, inputDate: 150, address: 260, telp: 140,
}
const COL_W_FALLBACK = 150

// Truncated address; click to expand the full text (and click again to collapse).
function AddressCell({ value }) {
    const [open, setOpen] = useState(false)
    if (!value || value === '—') return <span className="text-muted-foreground">—</span>
    return (
        <button type="button" title={value}
            onClick={(e) => { e.stopPropagation(); setOpen((o) => !o) }}
            className={`block max-w-[260px] cursor-pointer text-left text-muted-foreground transition-colors hover:text-primary ${open ? 'whitespace-normal' : 'truncate'}`}>
            {value}
        </button>
    )
}

// Per-column cell renderer + td classes. `ctx.openDetail` navigates to the report.
const TD_CLASS = {
    reportNo: 'whitespace-nowrap !text-[13px] font-bold tabular-nums !text-primary',   // `!` wajib: [&_tbody_td]:text-foreground/text-[12px] di <table> = spesifisitas (0,1,2), menang atas kelas polos di td
    details: 'whitespace-nowrap text-center',
    complainType: 'whitespace-nowrap',
    company: 'whitespace-nowrap font-semibold text-foreground',
    creator: 'whitespace-nowrap text-foreground',
    division: 'whitespace-nowrap text-muted-foreground',
    complainDate: 'whitespace-nowrap',
    inputDate: 'whitespace-nowrap',
    address: 'max-w-[260px]',
    telp: 'whitespace-nowrap tabular-nums text-muted-foreground',
}
function renderCell(c, colId, ctx) {
    switch (colId) {
        case 'reportNo': return c.ID
        case 'details': return (
            <button type="button" onClick={() => ctx.openDetail(c)}
                className="group/link inline-flex items-center gap-1 text-[12px] font-bold text-primary transition-colors hover:underline">
                Details <ChevronRight className="size-3.5 transition-transform duration-200 group-hover/link:translate-x-0.5" aria-hidden="true" />
            </button>
        )
        case 'complainType': return c.ComplainTypeName ? <StatusBadge tone={complaintTypeTone(c.ComplainTypeName)}>{c.ComplainTypeName}</StatusBadge> : <span className="text-muted-foreground">—</span>
        case 'company': return c.CompanyName || '—'
        case 'creator': return c.Creator || '—'
        case 'division': return c.DivisionName || '—'
        case 'complainDate': return <DateText value={c.ComplainDate} />
        case 'inputDate': return <DateText value={c.InputDate} />
        case 'address': return <AddressCell value={c.CompanyAddress} />
        case 'telp': return c.Telp || '—'
        default: return '—'
    }
}

export default function Index({ complaints, filters = {}, filterOptions }) {
    // This list's server-side defaults, so go() can leave them out of the URL (lib/listParams.js).
    const { listDefaults } = usePage().props
    const pageRows = complaints?.data ?? []

    // The search BOX is local; the committed term lives in `filters.search`.
    const [searchDraft, setSearchDraft] = useState(filters.search || '')
    const [customizeOpen, setCustomizeOpen] = useState(false)

    // Every pill is MULTI-select (user decision 2026-08-20) — preserved on the server side.
    const division = useMemo(() => idsOf(filters.division), [filters.division])
    const company = useMemo(() => idsOf(filters.company), [filters.company])
    const creator = useMemo(() => idsOf(filters.creator), [filters.creator])

    // Resizable columns — drag a header's right edge to resize.
    const { widthOf, startResize, resizingId, resizeRef } = useResizableColumns(COL_W, COL_W_FALLBACK)
    // Column order + visibility — ⚙ modal AND direct header drag, persisted per user.
    const prefs = useColumnPrefs('complaintCloseColumns_v1', COLUMN_DEFS, { resizeGuardRef: resizeRef })
    const tableWidth = useMemo(() => prefs.visibleCols.reduce((sum, col) => sum + widthOf(col.id), 0), [prefs.visibleCols, widthOf])

    useEffect(() => { setSearchDraft(filters.search || '') }, [filters.search])

    const go = (overrides = {}) => {
        const params = {
            search: filters.search ?? '',
            division: filters.division ?? '',
            company: filters.company ?? '',
            creator: filters.creator ?? '',
            sort: filters.sort,
            dir: filters.dir,
            per_page: complaints?.per_page,
            ...overrides,
        }
        Object.keys(params).forEach((k) => {
            if (params[k] === '' || params[k] === null || params[k] === undefined) delete params[k]
        })
        router.get(route('complaints.close.index'), stripDefaults(params, listDefaults), RELOAD)
    }

    const { sortKey, sortDir, toggleSort } = useServerSort(filters, go)

    const hasFilter = Boolean(filters.search || filters.division || filters.company || filters.creator || searchDraft)
    const resetFilters = () => {
        setSearchDraft('')
        router.get(route('complaints.close.index'), {}, RELOAD)
    }

    const openDetail = (c) => router.visit(route('complaints.close.show', c.ID))

    return (
        <section className="flex min-w-0 flex-col gap-[18px]">
            <header className="flex items-start justify-between gap-4">
                <div>
                    <p className="m-0 mb-1.5 flex items-center gap-2 text-xs font-semibold text-muted-foreground">
                        <Link href={route('complaints.close.index')} className="no-underline hover:text-primary">Complain &amp; Returns</Link>
                        <span aria-hidden="true">›</span>
                        <span className="text-foreground">Close Complaint</span>
                    </p>
                    <h1 className="m-0 text-xl font-bold leading-[1.2] text-card-foreground">Close Complaint — Complain &amp; Returns</h1>
                </div>
            </header>

            {/* Filter bar + list — one merged card */}
            <article className="overflow-hidden rounded-2xl border border-border bg-card shadow-sm">
                <div 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-[260px] 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 complaint">
                        <Search aria-hidden="true" className="size-3.5 shrink-0" />
                        <input type="search" placeholder="Search report no, company, address…" autoComplete="off" value={searchDraft}
                            onChange={(e) => setSearchDraft(e.target.value)}
                            onKeyDown={(e) => { if (e.key === 'Enter') go({ search: searchDraft.trim(), page: 1 }) }}
                            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}>
                        <button type="button" onClick={() => go({ search: searchDraft.trim(), page: 1 })}
                            className="inline-flex h-8 shrink-0 items-center gap-1.5 rounded-full bg-linear-to-br from-violet-500 to-primary px-4 text-xs font-bold text-white shadow-sm transition-[filter] hover:brightness-105">
                            <Search aria-hidden="true" className="size-3.5" /> Search
                        </button>
                        <FilterPill label="Division" value={division} options={filterOptions?.divisions ?? []}
                            onChange={(v) => go({ division: v.join(','), page: 1 })} />
                        <FilterPill label="Company" value={company} options={filterOptions?.companies ?? []}
                            onChange={(v) => go({ company: v.join(','), page: 1 })} />
                        <FilterPill label="Creator" value={creator} options={filterOptions?.creators ?? []}
                            onChange={(v) => go({ creator: v.join(','), page: 1 })} />
                        {hasFilter && (
                            <button type="button" onClick={resetFilters}
                                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>
                </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]:border-b [&_tbody_td]:border-border/60 [&_tbody_td]:px-3.5 [&_tbody_td]:py-[16px] [&_tbody_td]:align-middle [&_tbody_td]:text-[12px] [&_tbody_td]:text-foreground [&_tbody_tr:last-child_td]:border-b-0 [&_tbody_tr:hover_td]:bg-secondary/60 [&_tbody_tr:nth-child(even)_td]:bg-secondary/25 [&_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_tr:first-child_th:first-child]:rounded-tl-full [&_thead_tr:first-child_th:first-child]:pl-7 [&_thead_tr:first-child_th:last-child]:rounded-tr-full [&_thead_tr:first-child_th:last-child]:pr-5 [&_thead_tr:last-child_th:first-child]:rounded-bl-full [&_thead_tr:last-child_th:first-child]:pl-7 [&_thead_tr:last-child_th:last-child]:rounded-br-full [&_thead_tr:last-child_th:last-child]:pr-5 [&_tbody_td:first-child]:pl-7 [&_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)}`}>
                                        {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>
                            {pageRows.length === 0 ? (
                                <tr>
                                    <td colSpan={prefs.visibleCols.length} className="px-4 py-10 text-center italic text-muted-foreground">Tidak ada complaint yang siap ditutup.</td>
                                </tr>
                            ) : (
                                pageRows.map((c) => (
                                    <tr key={c.ID} onClick={() => openDetail(c)} className="cursor-pointer group/row">
                                        {prefs.visibleCols.map((col) => (
                                            <td key={col.id} className={TD_CLASS[col.id]}
                                                onClick={col.id === 'details' ? (e) => e.stopPropagation() : undefined}>
                                                {renderCell(c, col.id, { openDetail })}
                                            </td>
                                        ))}
                                    </tr>
                                ))
                            )}
                        </tbody>
                    </table>
                </div>

                <ListFooter
                    page={complaints?.current_page} totalPages={complaints?.last_page} onPage={(p) => go({ page: p })}
                    pageSize={complaints?.per_page} onPageSize={(n) => go({ per_page: n, page: 1 })} pageSizeOptions={[10, 20, 50, 100]}
                    total={complaints?.total} from={complaints?.from} to={complaints?.to} itemLabel="results" />
            </article>

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

Index.layout = [AppLayout]
