import { router } from '@inertiajs/react';
import { useState } from 'react';
import AppLayout from '@/Layouts/AppLayout';
import Pagination from '@/Components/Pagination';
import { ExportButton } from '@/lib/excel/ExportButton';
import { useServerSort } from '@/lib/ServerSort';
import { FilterPill } from '@/Components/ui/filter-pill';
import { SelectPill, DateRangePill } from '@/Components/MenuQuotations/QuotationListPage/QuotationListPills';
import {
    TopBar, Crumb, CrumbSep, CrumbCurrent, PrimaryButton,
    ListCard, Toolbar, SearchField, ResetButton,
    ListTable, Th, Td, TdActions, Row, EmptyRow, RowActions, YesNoBadge,
    ListFooter, DeleteModal,
} from '@/Components/Table';

const STATUS_OPTIONS = [
    { value: 'active', label: 'Aktif' },
    { value: 'deleted', label: 'Terhapus' },
    { value: 'all', label: 'Semua' },
];

// Pills take {id,name}; the leading "— Semua … —" row is gone because a multi pill clears
// itself with its own NONE button (design-system.md: that explicit all-row is the select-none
// for SINGLE-choice pills only).
const asOptions = (rows, labelKey) => (rows ?? []).map((r) => ({ id: String(r.ID), name: r[labelKey] }));

// Wire format for the three multi filters is a comma-joined id list (PaginatesList::multiIds).
// Arrays are NOT interchangeable here: `?branch_id[]=1` is read as "no filter".
const toList = (v) => String(v ?? '').split(',').filter(Boolean);

export default function Index({ employees, filters, branchOptions, departmentOptions, roleOptions }) {
    const [f, setF] = useState({
        search: filters.search || '',
        email: filters.email || '',
        phone: filters.phone || '',
        branch_id: filters.branch_id || '',
        department_id: filters.department_id || '',
        role_id: filters.role_id || '',
        join_from: filters.join_from || '',
        join_to: filters.join_to || '',
        status: filters.status || 'active',
    });
    const [deleteTarget, setDeleteTarget] = useState(null);
    // Only DateRangePill still needs an owner for its open state; FilterPill holds its own.
    const [activePill, setActivePill] = useState(null);

    const set = (key, value) => setF((prev) => ({ ...prev, [key]: value }));

    // Export params come from this live state, not the URL — the URL drops default-valued
    // filters, which would silently export more rows than the screen is showing.
    const go = (next = {}) => router.get(route('employees.index'),
        { ...f, sort: filters.sort, dir: filters.dir, ...next },
        { preserveState: true, preserveScroll: true, replace: true });

    // Clears filters only — sort/dir are carried over from the current URL rather than
    // reset to the default, matching how Reset behaves on the other server-sorted lists.
    // Built as an explicit object (not via go()) because go() closes over the STALE `f`
    // from this render; setF()'s update would not be visible to it yet.
    const reset = () => {
        const cleared = {
            search: '', email: '', phone: '', branch_id: '', department_id: '',
            role_id: '', join_from: '', join_to: '', status: 'active',
        };
        setF(cleared);
        router.get(route('employees.index'), { ...cleared, sort: filters.sort, dir: filters.dir },
            { preserveState: true, preserveScroll: true, replace: true });
    };

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

    return (
        <section className="grid grid-cols-[minmax(0,1fr)] gap-[18px]">
            <TopBar
                title="Employee"
                breadcrumb={<><Crumb href={route('employees.index')}>Employee</Crumb><CrumbSep /><CrumbCurrent>List</CrumbCurrent></>}
                action={<PrimaryButton href={route('employees.create')}>New employee</PrimaryButton>}
            />

            <ListCard>
                {/* List-page grammar (.claude/rules/design-system.md): pills that reload on
                    selection, text boxes that commit on Enter/debounce, `Reset filters`, and
                    NO Search button — nine full-width native controls stacked into an ~360px
                    wall on a 390px screen before a single row of data was visible. */}
                <Toolbar
                    rightActions={
                        <>
                            <ExportButton
                                specKey="employeeExport"
                                url={route('employees.export-data')}
                                params={f}
                                className="h-8 px-3"
                            />
                            <ResetButton onClick={reset} />
                        </>
                    }
                >
                    <SearchField value={f.search} onChange={(v) => set('search', v)} onEnter={() => go()} placeholder="Nama..." />
                    <SearchField value={f.email} onChange={(v) => set('email', v)} onEnter={() => go()} placeholder="Email..." width="w-[150px]" />
                    <SearchField value={f.phone} onChange={(v) => set('phone', v)} onEnter={() => go()} placeholder="Phone..." width="w-[130px]" />
                    <FilterPill
                        label="Branch"
                        value={toList(f.branch_id)}
                        options={asOptions(branchOptions, 'BranchName')}
                        onChange={(v) => { const s = v.join(','); set('branch_id', s); go({ branch_id: s }); }}
                    />
                    <FilterPill
                        label="Department"
                        value={toList(f.department_id)}
                        options={asOptions(departmentOptions, 'DepartmentName')}
                        onChange={(v) => { const s = v.join(','); set('department_id', s); go({ department_id: s }); }}
                    />
                    <FilterPill
                        label="Role"
                        value={toList(f.role_id)}
                        options={asOptions(roleOptions, 'RoleName')}
                        onChange={(v) => { const s = v.join(','); set('role_id', s); go({ role_id: s }); }}
                    />
                    <DateRangePill
                        label="Join"
                        from={f.join_from}
                        to={f.join_to}
                        open={activePill === 'join'}
                        onToggle={() => setActivePill(activePill === 'join' ? null : 'join')}
                        onApply={(from, to) => {
                            setF((prev) => ({ ...prev, join_from: from, join_to: to }));
                            setActivePill(null);
                            go({ join_from: from, join_to: to });
                        }}
                    />
                    {/* Status stays SINGLE: Aktif / Terhapus / Semua are mutually exclusive
                        views of the same rows, not a set to intersect. "Semua" is its
                        select-none, which is why it keeps an explicit all-row. */}
                    <SelectPill
                        label="Status"
                        value={f.status}
                        options={STATUS_OPTIONS.map((o) => ({ id: o.value, name: o.label }))}
                        onPick={(v) => { const s = v || 'active'; set('status', s); go({ status: s }); }}
                    />
                </Toolbar>

                <ListTable sort={{ sortKey, sortDir, toggleSort }} minWidth="min-w-[1100px]">
                    <thead>
                        <tr>
                            <Th sortId="nama">Nama</Th>
                            <Th sortId="position">Position</Th>
                            <Th sortId="department">Department</Th>
                            <Th sortId="branch">Branch</Th>
                            <Th sortId="head">Head</Th>
                            <Th sortId="phone">Phone</Th>
                            <Th sortId="join">Join Date</Th>
                            <Th sortId="headDept">Head Dept</Th>
                            <Th draggable={false} className="text-right">Actions</Th>
                        </tr>
                    </thead>
                    <tbody>
                        {employees.data.length === 0 && <EmptyRow colSpan={9}>Belum ada data employee.</EmptyRow>}
                        {employees.data.map((e) => (
                            <Row key={e.ID} onClick={(ev) => { if (ev.target.closest('a,button,input,label')) return; router.visit(route('employees.show', e.ID)); }}>
                                <Td className="pl-7 font-semibold text-text-heading">{e.Nama}</Td>
                                <Td className="text-text-muted">{e.PositionName || '—'}</Td>
                                <Td className="text-text-muted">{e.department?.DepartmentName ?? '—'}</Td>
                                <Td className="text-text-muted">{e.branch?.BranchName ?? '—'}</Td>
                                <Td className="text-text-muted">{e.head?.Nama ?? '—'}</Td>
                                <Td className="text-text-muted">{e.PhoneNumber || '—'}</Td>
                                <Td className="text-text-muted">
                                    {e.JoinDate && !String(e.JoinDate).startsWith('0000') ? String(e.JoinDate).slice(0, 10) : '—'}
                                </Td>
                                <Td><YesNoBadge value={e.IsHeadDept} yesLabel="Head" noLabel="Staff" /></Td>
                                <TdActions>
                                    <RowActions
                                        isDeleted={e.IsDeleted}
                                        onShow={() => router.visit(route('employees.show', e.ID))}
                                        onEdit={() => router.visit(route('employees.edit', e.ID))}
                                        onDelete={() => setDeleteTarget(e)}
                                        onRestore={() => router.post(route('employees.restore', e.ID), {}, { preserveScroll: true })}
                                    />
                                </TdActions>
                            </Row>
                        ))}
                    </tbody>
                </ListTable>

                <ListFooter paginator={employees}>
                    <Pagination links={employees.links} />
                </ListFooter>
            </ListCard>

            {deleteTarget && (
                <DeleteModal
                    label={deleteTarget.Nama}
                    message="Employee akan dihapus (soft delete). Kendaraan yang dimiliki employee ini ikut dihapus."
                    onCancel={() => setDeleteTarget(null)}
                    onConfirm={() => router.delete(route('employees.destroy', deleteTarget.ID), {
                        preserveScroll: true,
                        onSuccess: () => setDeleteTarget(null),
                    })}
                />
            )}
        </section>
    );
}

Index.layout = [AppLayout];
