// Visit Report — Approval PM queue (legacy listvisitplanreportallpm.php +
// listvisitplanreportallviewpm.php, menu 95). A flat per-line list of the Visit Report
// Action lines whose principal the PM heads (userprincipal.IsHeadDiv=1, scoped server-side).
// The PM fills a PMRemark per line then runs a batch decision — Pending (8) / Submited (9)
// / Confirm (10) — which writes PMRemark + the status + a status-6 history row. New page,
// modeled on the app's list/queue vocabulary (not a proto port).
import { Fragment, useMemo, useState } from 'react';
import { Link, useForm } from '@inertiajs/react';
import { ArrowLeft, ListChecks, Search, Check, Clock, Send, Inbox, MessageSquare, ChevronDown } from 'lucide-react';
import DOMPurify from 'dompurify';
import AppLayout from '@/Layouts/AppLayout';
import { StatusBadge } from '@/Components/Proto/UI/StatusBadge';
import { ActionLineHistory } from '@/Components/MenuVisitPlans/ActionLineHistory';
import { useToast } from '@/Components/Toast';
import { NativeSelect } from '@/Components/ui/native-select';
import { useClientSort, SortButton } from '@/lib/ClientSort';
import { useResizableColumns, ColumnResizeGrip } from '@/lib/useResizableColumns';
import { SELECTED_BG } from '@/lib/rowTint';

const CARD = 'rounded-2xl border border-border bg-card shadow-sm';
const ACTION_TONE = { 8: 'warning', 9: 'primary', 10: 'success' };
const SEL = 'h-9 min-w-[150px] rounded-lg border border-input bg-card px-2.5 text-[12.5px] text-foreground outline-none transition-colors focus:border-primary disabled:opacity-50';

// Sortable columns — id → raw row value (house ClientSort pattern). Remark (rich HTML +
// history toggle) and PM Remark (editable textarea) stay unsorted.
const SORT_GETTERS = {
    visit: (l) => l.visitPlanId,
    action: (l) => l.actionName,
    principal: (l) => l.principalName,
    reportDate: (l) => l.reportDate,
};

// Resizable-column ids (left→right) + default widths for the table-fixed layout.
const COLS = ['check', 'visit', 'action', 'principal', 'reportDate', 'remark', 'pmRemark'];
const COL_W = { check: 48, visit: 190, action: 160, principal: 180, reportDate: 120, remark: 240, pmRemark: 240 };

function Html({ html }) {
    if (!html || !String(html).trim()) return <span className="text-muted-foreground/50">—</span>;
    return <div className="[&_*]:inline [&_p]:m-0" dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(html) }} />;
}

export default function VisitPlanApprovalPm({ lines = [], actionStatuses = [] }) {
    const { show: showToast } = useToast();
    const [remarks, setRemarks] = useState(() => Object.fromEntries((lines ?? []).map((l) => [l.detailId, l.pmRemark || ''])));
    const [checked, setChecked] = useState(() => new Set());
    const [open, setOpen] = useState(() => new Set()); // lines whose history panel is expanded
    const [q, setQ] = useState(() => new URLSearchParams(window.location.search).get('q') || '');
    const [statusFilter, setStatusFilter] = useState('');
    const form = useForm({ items: [] });

    const rows = useMemo(() => (lines ?? []).filter((l) => {
        if (statusFilter && String(l.statusId ?? '') !== statusFilter) return false;
        if (q.trim()) {
            const hay = `${l.visitPlanId} ${l.company ?? ''} ${l.principalName ?? ''} ${l.barang ?? ''} ${l.sales ?? ''} ${l.actionName ?? ''}`.toLowerCase();
            if (!hay.includes(q.trim().toLowerCase())) return false;
        }
        return true;
    }), [lines, q, statusFilter]);

    // The checked ids that survive the current filter — the batch acts on exactly these.
    const visibleChecked = useMemo(() => rows.filter((l) => checked.has(l.detailId)).map((l) => l.detailId), [rows, checked]);

    // Column-header sort + resizable columns (house patterns) on the queue table.
    const { sorted, sortKey, sortDir, toggleSort } = useClientSort(rows, SORT_GETTERS);
    const { widthOf, startResize, resizingId } = useResizableColumns(COL_W);
    const tableWidth = COLS.reduce((sum, id) => sum + widthOf(id), 0);

    const setRemark = (id, val) => setRemarks((r) => ({ ...r, [id]: val }));
    const toggle = (id) => setChecked((s) => { const n = new Set(s); n.has(id) ? n.delete(id) : n.add(id); return n; });
    // Per-line history (visitplandetailassignment) — this is where the head/sm/mm tier comments
    // on a line surface for the PM. actionHistory() filters no statuses, so they arrive here
    // alongside the owner's edits and the PM's own past decisions.
    const toggleHistory = (id) => setOpen((s) => { const n = new Set(s); n.has(id) ? n.delete(id) : n.add(id); return n; });
    const allChecked = rows.length > 0 && rows.every((l) => checked.has(l.detailId));
    const toggleAll = () => setChecked((s) => {
        const n = new Set(s);
        if (allChecked) rows.forEach((l) => n.delete(l.detailId));
        else rows.forEach((l) => n.add(l.detailId));
        return n;
    });

    // Batch decision: gather the checked lines + their PMRemark, require every one filled
    // (legacy skips blank-remark lines; here we block early with a clear message), POST.
    const run = (action, label) => {
        if (form.processing) return;
        // Act ONLY on lines that are both checked AND currently visible. Checking rows and
        // then narrowing the search/status filter must not silently submit rows the PM can no
        // longer see — nor strand them on a "fill in the PM Remark" error for an off-screen row.
        const items = visibleChecked.map((id) => ({ detailId: id, pmRemark: (remarks[id] ?? '').trim() }));
        if (items.length === 0) { showToast('Pilih minimal satu action line yang terlihat.', 'error'); return; }
        if (items.some((i) => !i.pmRemark)) { showToast('Isi PM Remark untuk setiap line yang dipilih.', 'error'); return; }
        form.transform(() => ({ items }));
        form.post(route('visit-plans.approval-pm.act', action), {
            preserveScroll: true,
            onSuccess: () => { setChecked(new Set()); },
            onError: () => showToast('Processing failed — please check your entries.', 'error'),
        });
    };

    return (
        <section className="flex min-w-0 flex-col gap-5">
            <header className="flex flex-wrap items-start justify-between gap-3">
                <div>
                    <p className="m-0 mb-1.5 flex items-center gap-2 text-xs font-semibold text-muted-foreground">
                        <span>Visit Report</span>
                        <span aria-hidden="true">›</span>
                        <span className="text-foreground">Approval PM</span>
                    </p>
                    <div className="flex flex-wrap items-center gap-2.5">
                        <h1 className="m-0 text-2xl font-bold leading-[1.15] tracking-tight text-card-foreground">Approval PM — Visit Report Action</h1>
                        <span className="rounded-full bg-secondary px-2.5 py-0.5 text-[12px] font-bold tabular-nums text-muted-foreground">{rows.length} line</span>
                    </div>
                    <p className="mt-1 text-[12.5px] text-muted-foreground">Action line untuk principal yang Anda kepalai. Isi PM Remark lalu pilih keputusan.</p>
                </div>
                <Link href={route('visit-plans.index')} className="inline-flex h-9 items-center gap-1.5 rounded-lg border border-input bg-card px-3.5 text-xs font-bold text-foreground transition-colors hover:border-primary hover:text-primary">
                    <ArrowLeft className="size-3.5" /> Kembali
                </Link>
            </header>

            <article className={CARD}>
                <header className="flex flex-wrap items-center gap-2 border-b border-border px-5 py-3">
                    <span className="inline-grid size-6 place-items-center rounded-md bg-accent text-primary" aria-hidden="true"><ListChecks className="size-3.5" /></span>
                    <h2 className="m-0 mr-auto text-sm font-bold text-card-foreground">List Visit - PM</h2>
                    <div className="relative">
                        <Search className="pointer-events-none absolute left-2.5 top-1/2 size-3.5 -translate-y-1/2 text-muted-foreground" />
                        <input value={q} onChange={(e) => setQ(e.target.value)} placeholder="Cari No / company / principal / product…"
                            className="h-9 w-[240px] max-w-full rounded-lg border border-input bg-card pl-8 pr-3 text-[12.5px] outline-none focus:border-primary" />
                    </div>
                    <NativeSelect className={SEL} value={statusFilter} onChange={(e) => setStatusFilter(e.target.value)}>
                        <option value="">Semua Status</option>
                        {actionStatuses.map((s) => <option key={s.id} value={s.id}>{s.name}</option>)}
                    </NativeSelect>
                </header>

                {rows.length === 0 ? (
                    <div className="flex flex-col items-center gap-2 px-5 py-16 text-center text-muted-foreground">
                        <Inbox className="size-8 text-muted-foreground/50" aria-hidden="true" />
                        <p className="m-0 text-[13px]">Tidak ada action line untuk di-review.</p>
                    </div>
                ) : (
                    <div className="overflow-x-auto">
                        <table style={{ minWidth: tableWidth }} className="w-full table-fixed border-collapse text-[12.5px]">
                            <colgroup>
                                {COLS.map((id) => <col key={id} style={{ width: widthOf(id) }} />)}
                            </colgroup>
                            <thead>
                                <tr className="border-b border-border text-left text-[10px] font-bold uppercase tracking-wide text-muted-foreground">
                                    <th className="py-2.5 pl-5 pr-2">
                                        <input type="checkbox" checked={allChecked} onChange={toggleAll} className="size-4 accent-primary" aria-label="Pilih semua" />
                                    </th>
                                    <th className="group/col relative py-2.5 pr-3"><SortButton id="visit" label="Visit / Company" sortKey={sortKey} sortDir={sortDir} onToggle={toggleSort} /><ColumnResizeGrip onMouseDown={(e) => startResize(e, 'visit')} active={resizingId === 'visit'} /></th>
                                    <th className="group/col relative py-2.5 pr-3"><SortButton id="action" label="Action / Status" sortKey={sortKey} sortDir={sortDir} onToggle={toggleSort} /><ColumnResizeGrip onMouseDown={(e) => startResize(e, 'action')} active={resizingId === 'action'} /></th>
                                    <th className="group/col relative py-2.5 pr-3"><SortButton id="principal" label="Principal / Product" sortKey={sortKey} sortDir={sortDir} onToggle={toggleSort} /><ColumnResizeGrip onMouseDown={(e) => startResize(e, 'principal')} active={resizingId === 'principal'} /></th>
                                    <th className="group/col relative py-2.5 pr-3"><SortButton id="reportDate" label="Report Date" sortKey={sortKey} sortDir={sortDir} onToggle={toggleSort} /><ColumnResizeGrip onMouseDown={(e) => startResize(e, 'reportDate')} active={resizingId === 'reportDate'} /></th>
                                    <th className="group/col relative py-2.5 pr-3">Remark<ColumnResizeGrip onMouseDown={(e) => startResize(e, 'remark')} active={resizingId === 'remark'} /></th>
                                    <th className="group/col relative py-2.5 pr-5">PM Remark<ColumnResizeGrip onMouseDown={(e) => startResize(e, 'pmRemark')} active={resizingId === 'pmRemark'} /></th>
                                </tr>
                            </thead>
                            <tbody>
                                {sorted.map((l) => (
                                    <Fragment key={l.detailId}>
                                    <tr className={`border-b border-border/50 align-top transition-colors ${checked.has(l.detailId) ? SELECTED_BG : ''}`}>
                                        <td className="py-3 pl-5 pr-2">
                                            <input type="checkbox" checked={checked.has(l.detailId)} onChange={() => toggle(l.detailId)}
                                                className="size-4 accent-primary" aria-label={`Pilih line ${l.detailId}`} />
                                        </td>
                                        <td className="py-3 pr-3">
                                            <Link href={route('visit-plans.report', l.visitPlanId)} className="font-bold text-primary hover:underline">#{l.visitPlanId}</Link>
                                            <div className="text-foreground">{l.company || '—'}</div>
                                            <div className="text-[11px] text-muted-foreground">{l.sales || ''}</div>
                                        </td>
                                        <td className="py-3 pr-3">
                                            <div className="mb-1 font-semibold text-foreground">{l.actionName || '—'}</div>
                                            <StatusBadge tone={ACTION_TONE[l.statusId] ?? 'neutral'}>{l.statusName || '—'}</StatusBadge>
                                        </td>
                                        <td className="py-3 pr-3">
                                            <div className="font-semibold text-foreground">{l.principalName || '—'}</div>
                                            <div className="text-[11px] text-muted-foreground">{l.barang || ''}</div>
                                        </td>
                                        <td className="py-3 pr-3 tabular-nums text-muted-foreground">{l.reportDate || '—'}</td>
                                        <td className="max-w-[220px] py-3 pr-3 text-muted-foreground">
                                            <Html html={l.remark} />
                                            <button type="button" onClick={() => toggleHistory(l.detailId)} aria-expanded={open.has(l.detailId)}
                                                className="mt-1.5 inline-flex h-7 items-center gap-1 rounded-md border border-input bg-card px-2 text-[11.5px] font-bold text-muted-foreground transition-colors hover:border-primary hover:text-primary">
                                                <MessageSquare className="size-3" aria-hidden="true" />
                                                <span className="tabular-nums">{(l.history ?? []).length}</span>
                                                <ChevronDown className={`size-3 transition-transform ${open.has(l.detailId) ? 'rotate-180' : ''}`} aria-hidden="true" />
                                            </button>
                                        </td>
                                        <td className="py-3 pr-5">
                                            <textarea value={remarks[l.detailId] ?? ''} onChange={(e) => setRemark(l.detailId, e.target.value)} rows={2}
                                                placeholder="PM Remark…"
                                                className="w-[220px] max-w-full rounded-lg border border-input bg-card px-2.5 py-1.5 text-[12px] text-foreground outline-none focus:border-primary" />
                                        </td>
                                    </tr>
                                    {open.has(l.detailId) && (
                                        <tr className="border-b border-border/50 bg-secondary/20">
                                            <td colSpan={7} className="px-5 py-3">
                                                <ActionLineHistory history={l.history ?? []} />
                                            </td>
                                        </tr>
                                    )}
                                    </Fragment>
                                ))}
                            </tbody>
                        </table>
                    </div>
                )}
            </article>

            {/* Batch decision bar (sticky). Pending / Submited / Confirm act on the checked lines. */}
            <div className="sticky bottom-3 z-10 flex flex-wrap items-center justify-end gap-2.5 rounded-2xl border border-border bg-card/95 px-4 py-3 shadow-modal backdrop-blur">
                <span className="mr-auto text-[12.5px] font-semibold text-muted-foreground">
                    {visibleChecked.length} line dipilih
                    {checked.size > visibleChecked.length && (
                        <span className="ml-1 font-normal text-muted-foreground/70">
                            ({checked.size - visibleChecked.length} tersembunyi oleh filter)
                        </span>
                    )}
                </span>
                <button type="button" onClick={() => run('pending', 'Pending Action')} disabled={form.processing}
                    className="inline-flex h-9 items-center gap-1.5 rounded-lg border border-border bg-card px-4 text-[12.5px] font-bold text-muted-foreground transition-colors hover:border-warning hover:bg-warning-bg hover:text-warning-text disabled:cursor-not-allowed disabled:opacity-45">
                    <Clock className="size-3.5" /> Pending
                </button>
                <button type="button" onClick={() => run('submited', 'Submited Action')} disabled={form.processing}
                    className="inline-flex h-9 items-center gap-1.5 rounded-lg border border-input bg-card px-4 text-[12.5px] font-bold text-foreground transition-colors hover:border-primary hover:text-primary disabled:cursor-not-allowed disabled:opacity-45">
                    <Send className="size-3.5" /> Submited
                </button>
                <button type="button" onClick={() => run('confirm', 'Confirm Action')} disabled={form.processing}
                    className="inline-flex h-9 items-center gap-1.5 rounded-lg bg-linear-to-br from-violet-500 to-primary px-4 text-[12.5px] font-bold text-primary-foreground shadow-sm transition-[filter] hover:brightness-110 disabled:cursor-not-allowed disabled:opacity-45">
                    <Check className="size-3.5" /> Confirm
                </button>
            </div>
        </section>
    );
}

VisitPlanApprovalPm.layout = [AppLayout];
