import React, {FormEvent, useEffect, useMemo, useState} from 'react';
import {usePage} from '@inertiajs/react';
import axios from 'axios';
import ListingPagination from '@/components/ListingPagination';
import Modal from '@/components/ui/modal/Modal';
import {makeGetRequest, makePostRequest, makePutRequest} from '@/lib/request';
import {notify} from '@/lib/notify';

const types = ['statutory_limitation', 'filing_deadline', 'court_ordered', 'service_deadline', 'appeal_deadline', 'response_submission', 'other'];
const priorities = ['low', 'normal', 'high', 'critical'];
const statuses = ['upcoming', 'in_progress', 'completed', 'overdue', 'cancelled'];
const transitions: Record<string, string[]> = {upcoming: ['in_progress', 'completed', 'cancelled'], in_progress: ['upcoming', 'completed', 'cancelled'], overdue: ['in_progress', 'completed', 'cancelled'], completed: [], cancelled: []};
const reminderPresets: Record<string, {label: string; intervals: number[]}> = {
    light: {label: 'Light — 3 days before and on deadline day', intervals: [4320, 0]},
    standard: {label: 'Standard — 7 days, 1 day, and deadline day', intervals: [10080, 1440, 0]},
    early: {label: 'Early notice — 14 days, 3 days, and deadline day', intervals: [20160, 4320, 0]},
    frequent: {label: 'Frequent — 14, 7, 3, and 1 day, plus deadline day', intervals: [20160, 10080, 4320, 1440, 0]},
};

type Props = {record: any; documents: any[]; team: any[]; token?: string};
type ActionMode = 'reschedule' | 'status' | 'reminders' | null;

export default function DocketWorkspace({record, documents, team, token}: Props): JSX.Element {
    const {auth} = usePage<{auth: {user: any}}>().props;
    const permissions: string[] = auth?.user?.user_permissions ?? [];
    const canCreate = permissions.includes('docket_create');
    const canUpdate = permissions.includes('docket_update');
    const canReschedule = permissions.includes('docket_reschedule');
    const canComplete = permissions.includes('docket_complete');
    const canConfigure = permissions.includes('docket_configure_reminders');
    const canAcknowledge = permissions.includes('docket_acknowledge_escalations');
    const [items, setItems] = useState<any[]>([]);
    const [sourceEvents, setSourceEvents] = useState<any[]>([]);
    const [summary, setSummary] = useState<any>({});
    const [recentChanges, setRecentChanges] = useState<any[]>([]);
    const [defaults, setDefaults] = useState<number[]>([]);
    const [loading, setLoading] = useState(true);
    const [page, setPage] = useState(1);
    const [meta, setMeta] = useState({current_page: 1, last_page: 1, total: 0});
    const [filters, setFilters] = useState({search: '', entry_type: '', court: '', priority: '', status: '', responsible_user_id: '', date_from: '', date_to: ''});
    const [formOpen, setFormOpen] = useState(false);
    const [editing, setEditing] = useState<any | null>(null);
    const [selected, setSelected] = useState<any | null>(null);
    const [actionEntry, setActionEntry] = useState<any | null>(null);
    const [actionMode, setActionMode] = useState<ActionMode>(null);
    const [sourceView, setSourceView] = useState<'list' | 'calendar'>('list');

    async function load() {
        setLoading(true);
        try {
            const params = new URLSearchParams({page: String(page)});
            Object.entries(filters).forEach(([key, value]) => { if (value) params.set(key, value); });
            const response = await makeGetRequest(`/api/litigation/${record.id}/docket?${params}`, {token});
            const payload = response.data?.result ?? response.data ?? {};
            const entries = payload.entries ?? {};
            setItems(entries.data ?? []);
            setMeta({current_page: entries.current_page ?? page, last_page: entries.last_page ?? 1, total: entries.total ?? 0});
            setSourceEvents(payload.source_events ?? []); setSummary(payload.summary ?? {}); setRecentChanges(payload.recent_changes ?? []); setDefaults(payload.default_reminder_intervals ?? []);
        } catch (error: any) { notify.toastErrorMessage(firstError(error) || 'Unable to load court docket'); }
        finally { setLoading(false); }
    }

    useEffect(() => { const timer = window.setTimeout(load, 250); return () => window.clearTimeout(timer); }, [record.id, token, page, JSON.stringify(filters)]);
    async function details(item: any) { try { const response = await makeGetRequest(`/api/litigation/${record.id}/docket/${item.id}`, {token}); return response.data?.result ?? response.data; } catch (error: any) { notify.toastErrorMessage(firstError(error) || 'Unable to load docket entry'); return null; } }
    async function openDetails(item: any) { const entry = await details(item); if (entry) setSelected(entry); }
    async function openEdit(item: any) { const entry = await details(item); if (entry) { setEditing(entry); setFormOpen(true); } }
    async function openAction(item: any, mode: ActionMode) { const entry = await details(item); if (entry) { setActionEntry(entry); setActionMode(mode); } }
    async function saved(entry?: any) { setFormOpen(false); setEditing(null); setActionMode(null); setActionEntry(null); if (selected?.id === entry?.id) setSelected(entry); await load(); }

    const calendarGroups = useMemo(() => {
        const combined = [...sourceEvents, ...items.map(item => ({...item, key: `deadline-${item.id}`, scheduled_at: item.deadline_at, type: item.entry_type, source: 'deadline'}))];
        return combined.filter(item => item.scheduled_at).sort((a, b) => String(a.scheduled_at).localeCompare(String(b.scheduled_at))).reduce((groups: Record<string, any[]>, item) => { const key = new Date(item.scheduled_at).toLocaleDateString(undefined, {month: 'long', year: 'numeric'}); (groups[key] ??= []).push(item); return groups; }, {});
    }, [sourceEvents, items]);

    return <>
        <div className="mb-5 flex flex-wrap items-start justify-between gap-3"><div><h5 className="font-semibold">Court docket</h5><p className="text-sm text-gray-500">Centralized court dates, litigation deadlines, reminders, escalation, and source-record milestones.</p></div>{canCreate ? <button type="button" className="ti-btn ti-btn-primary" onClick={() => { setEditing(null); setFormOpen(true); }}><i className="fa fa-plus me-2" />Add deadline</button> : null}</div>
        <div className="mb-5 grid grid-cols-2 gap-3 lg:grid-cols-6">
            <Metric title="Upcoming hearings" value={summary.upcoming_hearings} /><Metric title="Upcoming deadlines" value={summary.upcoming_deadlines} /><Metric title="Overdue" value={summary.overdue_deadlines} danger /><Metric title="Critical" value={summary.critical_deadlines} danger /><Metric title="Unassigned" value={summary.unassigned_deadlines} /><Metric title="Awaiting completion" value={summary.awaiting_completion} />
        </div>
        <div className="mb-5 grid grid-cols-1 gap-3 md:grid-cols-3 xl:grid-cols-9">
            <input className="ti-form-input xl:col-span-2" placeholder="Search docket…" value={filters.search} onChange={e => { setPage(1); setFilters({...filters, search: e.target.value}); }} />
            <Select value={filters.entry_type} first="All deadline types" values={types} onChange={value => { setPage(1); setFilters({...filters, entry_type: value}); }} />
            <input className="ti-form-input" placeholder="Court or tribunal" value={filters.court} onChange={e => { setPage(1); setFilters({...filters, court: e.target.value}); }} />
            <Select value={filters.priority} first="All priorities" values={priorities} onChange={value => { setPage(1); setFilters({...filters, priority: value}); }} />
            <Select value={filters.status} first="All statuses" values={statuses} onChange={value => { setPage(1); setFilters({...filters, status: value}); }} />
            <UserSelect users={team} value={filters.responsible_user_id} onChange={(value: string) => { setPage(1); setFilters({...filters, responsible_user_id: value}); }} />
            <input type="date" className="ti-form-input" value={filters.date_from} onChange={e => { setPage(1); setFilters({...filters, date_from: e.target.value}); }} />
            <input type="date" className="ti-form-input" value={filters.date_to} onChange={e => { setPage(1); setFilters({...filters, date_to: e.target.value}); }} />
        </div>
        <div className="table-responsive"><table className="table whitespace-nowrap min-w-full"><thead className="bg-gray-100 dark:bg-bodybg"><tr><th>Reference / deadline</th><th>Type</th><th>Due</th><th>Responsible</th><th>Priority</th><th>Status</th><th className="!text-end">Actions</th></tr></thead><tbody>
            {loading ? <tr><td colSpan={7} className="py-8 text-center">Loading…</td></tr> : items.length === 0 ? <tr><td colSpan={7} className="py-8 text-center text-gray-500">No managed court deadlines found.</td></tr> : items.map(item => <tr key={item.id}><td><button type="button" className="text-start font-semibold text-primary hover:underline" onClick={() => openDetails(item)}>{item.docket_reference}<span className="block max-w-xs truncate text-xs font-normal text-gray-500">{item.title}</span></button></td><td>{label(item.entry_type)}</td><td>{dateTime(item.deadline_at)}<span className="block text-xs text-gray-500">{item.timezone}</span></td><td>{item.responsible_user?.name ?? <span className="text-warning">Unassigned</span>}</td><td><Badge value={item.priority} /></td><td><Badge value={item.effective_status ?? item.status} /></td><td className="text-end"><div className="flex justify-end gap-1"><Icon title="View deadline" icon="fa-eye" onClick={() => openDetails(item)} />{canUpdate ? <Icon title="Edit deadline" icon="fa-pencil" onClick={() => openEdit(item)} /> : null}{canReschedule && !['completed', 'cancelled'].includes(item.effective_status ?? item.status) ? <Icon title="Reschedule deadline" icon="fa-calendar" color="text-purple-600 hover:bg-purple-50" onClick={() => openAction(item, 'reschedule')} /> : null}{canComplete && transitions[item.effective_status ?? item.status]?.length ? <Icon title="Update deadline status" icon="fa-refresh" color="text-amber-600 hover:bg-amber-50" onClick={() => openAction(item, 'status')} /> : null}{canConfigure ? <Icon title="Configure reminders" icon="fa-bell" color="text-green-600 hover:bg-green-50" onClick={() => openAction(item, 'reminders')} /> : null}</div></td></tr>)}
        </tbody></table></div>
        <ListingPagination currentPage={meta.current_page} lastPage={meta.last_page} total={meta.total} itemCount={items.length} onPageChange={setPage} className="px-1 pb-2" />

        <div className="mt-7 border-t pt-5"><div className="mb-4 flex flex-wrap items-center justify-between gap-3"><div><h5 className="font-semibold">Authoritative source records</h5><p className="text-sm text-gray-500">Hearings, rulings, service dates, and e-filings remain managed by their original modules.</p></div><div className="flex rounded border p-1"><button type="button" className={`px-3 py-1 text-sm ${sourceView === 'list' ? 'rounded bg-primary text-white' : ''}`} onClick={() => setSourceView('list')}>List</button><button type="button" className={`px-3 py-1 text-sm ${sourceView === 'calendar' ? 'rounded bg-primary text-white' : ''}`} onClick={() => setSourceView('calendar')}>Calendar</button></div></div>
            {sourceView === 'list' ? <div className="table-responsive"><table className="table whitespace-nowrap min-w-full"><thead><tr><th>Reference</th><th>Source</th><th>Type</th><th>Title</th><th>Date</th><th>Conflict</th><th>Status</th></tr></thead><tbody>{sourceEvents.length ? sourceEvents.map(item => <tr key={item.key}><td>{item.docket_reference}</td><td>{label(item.source)}</td><td>{label(item.type)}</td><td>{item.title}</td><td>{dateTime(item.scheduled_at)}</td><td>{item.has_conflict ? <span className="text-danger">Scheduling conflict</span> : "—"}</td><td><Badge value={item.status} /></td></tr>) : <tr><td colSpan={7} className="py-6 text-center text-gray-500">No linked court milestones.</td></tr>}</tbody></table></div> : <div className="space-y-5">{Object.keys(calendarGroups).length ? Object.entries(calendarGroups).map(([month, events]) => <div key={month}><h6 className="mb-2 font-semibold">{month}</h6><div className="grid grid-cols-1 gap-2 md:grid-cols-2 xl:grid-cols-3">{events.map(item => <div key={item.key} className="rounded-lg border p-3"><div className="text-xs text-gray-500">{dateTime(item.scheduled_at)}</div><div className="mt-1 font-medium">{item.title}</div><div className="mt-2 flex justify-between"><span className="text-xs">{label(item.type)}{item.has_conflict ? <span className="ms-2 text-danger">Conflict</span> : null}</span><Badge value={item.effective_status ?? item.status} /></div></div>)}</div></div>) : <Empty text="No court dates to display." />}</div>}
        </div>

        {recentChanges.length ? <div className="mt-7 border-t pt-5"><h5 className="mb-3 font-semibold">Recent deadline changes</h5><div className="grid grid-cols-1 gap-2 lg:grid-cols-2">{recentChanges.map(change => <div key={change.id} className="rounded-lg bg-gray-50 p-3 text-sm dark:bg-bodybg"><strong>{label(change.action)}</strong><div className="text-xs text-gray-500">{change.changed_by?.name ?? 'System'} · {dateTime(change.created_at)}</div>{change.reason ? <div className="mt-1">{change.reason}</div> : null}</div>)}</div></div> : null}

        {formOpen ? <DeadlineForm record={record} entry={editing} documents={documents} team={team} defaults={defaults} token={token} onClose={() => { setFormOpen(false); setEditing(null); }} onSaved={saved} /> : null}
        {selected ? <DetailsModal entry={selected} token={token} canAcknowledge={canAcknowledge} onClose={() => setSelected(null)} onUpdated={() => openDetails(selected)} /> : null}
        {actionEntry && actionMode ? <ActionModal mode={actionMode} entry={actionEntry} documents={documents} token={token} onClose={() => { setActionEntry(null); setActionMode(null); }} onSaved={saved} /> : null}
    </>;
}

function DeadlineForm({record, entry, documents, team, defaults, token, onClose, onSaved}: any): JSX.Element {
    const [submitting, setSubmitting] = useState(false);
    const [form, setForm] = useState<any>({entry_type: entry?.entry_type ?? 'filing_deadline', title: entry?.title ?? '', description: entry?.description ?? '', court: entry?.court ?? record.court ?? '', scheduled_at: inputDateTime(entry?.scheduled_at), deadline_at: inputDateTime(entry?.deadline_at), timezone: entry?.timezone ?? Intl.DateTimeFormat().resolvedOptions().timeZone, responsible_user_id: entry?.responsible_user_id ?? '', priority: entry?.priority ?? 'normal', source_basis: entry?.source_basis ?? '', calculation_mode: entry?.calculation_mode ?? 'manual', trigger_date: inputDateTime(entry?.trigger_date), limitation_period_value: entry?.limitation_period_value ?? '', limitation_period_unit: entry?.limitation_period_unit ?? 'days', rule_reference: entry?.rule_reference ?? '', rule_version: entry?.rule_version ?? '', confirm_deadline: Boolean(entry?.confirmed_at), litigation_proceeding_id: entry?.litigation_proceeding_id ?? '', litigation_pleading_id: entry?.litigation_pleading_id ?? '', litigation_decision_id: entry?.litigation_decision_id ?? '', service_process_id: entry?.service_process_id ?? '', e_filing_id: entry?.e_filing_id ?? '', task_id: entry?.task_id ?? '', create_task: false, supporting_document_id: entry?.supporting_document_id ?? '', reminder_intervals: entry?.reminder_intervals ?? defaults, escalation_enabled: entry?.escalation_enabled ?? true, remarks: entry?.remarks ?? '', version: entry?.version});
    async function submit(event: FormEvent) { event.preventDefault(); setSubmitting(true); try { const payload = normalize(form); if (entry) { delete payload.deadline_at; delete payload.task_id; delete payload.create_task; delete payload.confirm_deadline; delete payload.reminder_intervals; } const response = entry ? await makePutRequest(`/api/litigation/${record.id}/docket/${entry.id}`, payload, {token}) : await makePostRequest(`/api/litigation/${record.id}/docket`, payload, {token}); notify.toastSuccessMessage(entry ? 'Court deadline updated' : 'Court deadline created'); onSaved(response.data?.result ?? response.data); } catch (error: any) { notify.toastErrorMessage(firstError(error) || 'Unable to save court deadline'); } finally { setSubmitting(false); } }
    return <Modal open={true} onClose={onClose} title={entry ? 'Edit court deadline' : 'Add court deadline'} maxWidthClassName="max-w-5xl" bodyClassName="max-h-[76vh] overflow-y-auto" footer={<><button type="button" className="ti-btn ti-btn-light" onClick={onClose}>Cancel</button><button type="submit" form="docket-form" className="ti-btn ti-btn-primary" disabled={submitting}>{submitting ? 'Saving…' : entry ? 'Update deadline' : 'Create deadline'}</button></>}><form id="docket-form" onSubmit={submit} className="grid grid-cols-1 gap-4 sm:grid-cols-2">
        <Field title="Deadline type"><Select value={form.entry_type} first="Select type" values={types} required onChange={value => setForm({...form, entry_type: value})} /></Field><Field title="Title"><input required className="ti-form-input" value={form.title} onChange={e => setForm({...form, title: e.target.value})} /></Field>
        <Field title="Court or tribunal"><input className="ti-form-input" value={form.court} onChange={e => setForm({...form, court: e.target.value})} /></Field><Field title="Responsible team member"><UserSelect users={team} value={form.responsible_user_id} onChange={value => setForm({...form, responsible_user_id: value})} /></Field>
        <Field title="Priority"><Select value={form.priority} first="Select priority" values={priorities} required onChange={value => setForm({...form, priority: value})} /></Field><Field title="Calculation mode"><Select value={form.calculation_mode} first="Select mode" values={['manual', 'calculated']} required disabled={Boolean(entry)} onChange={value => setForm({...form, calculation_mode: value})} /></Field>
        {!entry && form.calculation_mode === 'manual' ? <Field title="Deadline date and time"><input required type="datetime-local" className="ti-form-input" value={form.deadline_at} onChange={e => setForm({...form, deadline_at: e.target.value})} /></Field> : null}
        {!entry && form.calculation_mode === 'calculated' ? <><Field title="Trigger date and time"><input required type="datetime-local" className="ti-form-input" value={form.trigger_date} onChange={e => setForm({...form, trigger_date: e.target.value})} /></Field><Field title="Limitation period"><div className="flex gap-2"><input required type="number" min="1" className="ti-form-input" value={form.limitation_period_value} onChange={e => setForm({...form, limitation_period_value: e.target.value})} /><Select value={form.limitation_period_unit} first="Unit" values={['days', 'weeks', 'months', 'years']} required onChange={value => setForm({...form, limitation_period_unit: value})} /></div></Field><Field title="Legal rule reference"><input required className="ti-form-input" value={form.rule_reference} onChange={e => setForm({...form, rule_reference: e.target.value})} /></Field><Field title="Rule version"><input required className="ti-form-input" value={form.rule_version} onChange={e => setForm({...form, rule_version: e.target.value})} /></Field></> : null}
        <Field title="Time zone"><input required className="ti-form-input" value={form.timezone} onChange={e => setForm({...form, timezone: e.target.value})} /></Field><Field title="Related hearing"><LinkedSelect items={record.proceedings ?? []} value={form.litigation_proceeding_id} render={(x: any) => x.calendar_event?.title} onChange={value => setForm({...form, litigation_proceeding_id: value})} /></Field>
        <Field title="Related pleading"><LinkedSelect items={record.pleadings ?? []} value={form.litigation_pleading_id} render={(x: any) => `${label(x.document_type)} · ${x.court_reference || 'No court reference'}`} onChange={value => setForm({...form, litigation_pleading_id: value})} /></Field><Field title="Related court order"><LinkedSelect items={record.decisions ?? []} value={form.litigation_decision_id} render={(x: any) => `${label(x.decision_type)} · ${String(x.summary).slice(0, 50)}`} onChange={value => setForm({...form, litigation_decision_id: value})} /></Field>
        <Field title="Related service record"><LinkedSelect items={record.service_processes ?? []} value={form.service_process_id} render={(x: any) => `${x.party_name} · ${label(x.service_status)}`} onChange={value => setForm({...form, service_process_id: value})} /></Field><Field title="Related e-filing"><LinkedSelect items={record.matter?.e_filings ?? []} value={form.e_filing_id} render={(x: any) => `${x.provider} · ${label(x.status)}`} onChange={value => setForm({...form, e_filing_id: value})} /></Field>
        {!entry ? <Field title="Existing task"><LinkedSelect items={record.matter?.tasks ?? []} value={form.task_id} render={(x: any) => `${x.title} · ${label(x.status)}`} onChange={value => setForm({...form, task_id: value})} /></Field> : null}<Field title="Supporting document"><LinkedSelect items={documents} value={form.supporting_document_id} render={(x: any) => x.title} onChange={value => setForm({...form, supporting_document_id: value})} /></Field>
        <div className="sm:col-span-2"><Field title="Source or legal basis"><textarea className="ti-form-input" rows={2} value={form.source_basis} onChange={e => setForm({...form, source_basis: e.target.value})} /></Field></div><div className="sm:col-span-2"><Field title="Description"><textarea className="ti-form-input" rows={3} value={form.description} onChange={e => setForm({...form, description: e.target.value})} /></Field></div>
        {!entry ? <><label className="flex items-center gap-2"><input type="checkbox" checked={form.create_task} disabled={Boolean(form.task_id)} onChange={e => setForm({...form, create_task: e.target.checked})} />Create an actionable deadline task</label><label className="flex items-center gap-2"><input type="checkbox" checked={form.confirm_deadline} onChange={e => setForm({...form, confirm_deadline: e.target.checked})} />Confirm this deadline date</label></> : null}
        <Field title="Reminder schedule"><ReminderPresetSelect intervals={form.reminder_intervals} onChange={(intervals: number[]) => setForm({...form, reminder_intervals: intervals})} /></Field><label className="flex items-center gap-2"><input type="checkbox" checked={form.escalation_enabled} onChange={e => setForm({...form, escalation_enabled: e.target.checked})} />Enable escalation</label>
    </form></Modal>;
}

function ActionModal({mode, entry, documents, token, onClose, onSaved}: any): JSX.Element {
    const options = transitions[entry.effective_status ?? entry.status] ?? [];
    const [submitting, setSubmitting] = useState(false);
    const [form, setForm] = useState<any>({deadline_at: inputDateTime(entry.deadline_at), reason: '', supporting_document_id: '', status: options[0] ?? '', reminder_intervals: entry.reminder_intervals ?? reminderPresets.standard.intervals, escalation_enabled: Boolean(entry.escalation_enabled)});
    async function submit(event: FormEvent) { event.preventDefault(); setSubmitting(true); try { const base = `/api/litigation/${entry.litigation_case_id}/docket/${entry.id}`; let response; if (mode === 'reschedule') response = await patch(`${base}/reschedule`, {deadline_at: form.deadline_at, reason: form.reason, supporting_document_id: nullableNumber(form.supporting_document_id), version: entry.version}, token); else if (mode === 'status') response = await patch(`${base}/status`, {status: form.status, reason: form.reason || null, version: entry.version}, token); else response = await patch(`${base}/reminders`, {reminder_intervals: form.reminder_intervals, escalation_enabled: form.escalation_enabled, version: entry.version}, token); notify.toastSuccessMessage(mode === 'reschedule' ? 'Deadline rescheduled' : mode === 'status' ? 'Deadline status updated' : 'Reminder configuration updated'); onSaved(response.data?.result ?? response.data); } catch (error: any) { notify.toastErrorMessage(firstError(error) || 'Unable to update deadline'); } finally { setSubmitting(false); } }
    const title = mode === 'reschedule' ? 'Reschedule court deadline' : mode === 'status' ? 'Update deadline status' : 'Configure reminders';
    return <Modal open={true} onClose={onClose} title={title} footer={<><button type="button" className="ti-btn ti-btn-light" onClick={onClose}>Cancel</button><button type="submit" form="docket-action" className="ti-btn ti-btn-primary" disabled={submitting}>{submitting ? 'Saving…' : 'Save'}</button></>}><form id="docket-action" onSubmit={submit} className="space-y-4">
        {mode === 'reschedule' ? <><Field title="New deadline"><input required type="datetime-local" className="ti-form-input" value={form.deadline_at} onChange={e => setForm({...form, deadline_at: e.target.value})} /></Field><Field title="Reason for modification"><textarea required minLength={5} className="ti-form-input" rows={3} value={form.reason} onChange={e => setForm({...form, reason: e.target.value})} /></Field><Field title="Supporting court order or document"><LinkedSelect items={documents} value={form.supporting_document_id} render={(x: any) => x.title} onChange={value => setForm({...form, supporting_document_id: value})} /></Field></> : null}
        {mode === 'status' ? <><Field title="New status"><Select value={form.status} first="Select status" values={options} required onChange={value => setForm({...form, status: value})} /></Field><Field title={form.status === 'cancelled' ? 'Cancellation reason' : 'Completion notes or remarks'}><textarea required={form.status === 'cancelled'} className="ti-form-input" rows={3} value={form.reason} onChange={e => setForm({...form, reason: e.target.value})} /></Field></> : null}
        {mode === 'reminders' ? <><Field title="Reminder schedule"><ReminderPresetSelect intervals={form.reminder_intervals} onChange={(intervals: number[]) => setForm({...form, reminder_intervals: intervals})} /></Field><label className="flex items-center gap-2"><input type="checkbox" checked={form.escalation_enabled} onChange={e => setForm({...form, escalation_enabled: e.target.checked})} />Enable critical and overdue escalation</label></> : null}
    </form></Modal>;
}

function DetailsModal({entry, token, canAcknowledge, onClose, onUpdated}: any): JSX.Element {
    async function acknowledge(delivery: any) { try { await makePostRequest(`/api/litigation/${entry.litigation_case_id}/docket/${entry.id}/deliveries/${delivery.id}/acknowledge`, {}, {token}); notify.toastSuccessMessage('Escalation acknowledged'); await onUpdated(); } catch (error: any) { notify.toastErrorMessage(firstError(error) || 'Unable to acknowledge escalation'); } }
    return <Modal open={true} onClose={onClose} title={`${entry.docket_reference} · ${entry.title}`} maxWidthClassName="max-w-5xl" bodyClassName="max-h-[78vh] overflow-y-auto"><div className="grid grid-cols-1 gap-5 lg:grid-cols-2"><Section title="Deadline details"><Details values={[["Type", label(entry.entry_type)], ["Status", label(entry.effective_status ?? entry.status)], ["Priority", label(entry.priority)], ["Deadline", dateTime(entry.deadline_at)], ["Time zone", entry.timezone], ["Responsible", entry.responsible_user?.name], ["Court", entry.court], ["Source or basis", entry.source_basis], ["Description", entry.description], ["Remarks", entry.remarks]]} /></Section><Section title="Calculation and links"><Details values={[["Calculation mode", label(entry.calculation_mode)], ["Trigger date", dateTime(entry.trigger_date)], ["Limitation period", entry.limitation_period_value ? `${entry.limitation_period_value} ${entry.limitation_period_unit}` : null], ["Rule", entry.rule_reference], ["Rule version", entry.rule_version], ["Confirmed", dateTime(entry.confirmed_at)], ["Task", entry.task?.title], ["Pleading", entry.pleading ? label(entry.pleading.document_type) : null], ["Order", entry.decision ? label(entry.decision.decision_type) : null], ["Filing", entry.e_filing ? `${entry.e_filing.provider} · ${label(entry.e_filing.status)}` : null], ["Document", entry.supporting_document?.title]]} /></Section><Section title="Deadline history"><div className="space-y-2">{(entry.histories ?? []).length ? entry.histories.slice().reverse().map((item: any) => <div key={item.id} className="rounded bg-gray-50 p-3 text-sm dark:bg-bodybg"><strong>{label(item.action)}</strong><div className="text-xs text-gray-500">{item.changed_by?.name ?? 'System'} · {dateTime(item.created_at)}</div>{item.previous_deadline_at || item.new_deadline_at ? <div className="mt-1">{dateTime(item.previous_deadline_at)} → {dateTime(item.new_deadline_at)}</div> : null}{item.reason ? <div className="mt-1">{item.reason}</div> : null}</div>) : <Empty text="No history recorded." />}</div></Section><Section title="Reminder and escalation history"><div className="space-y-2">{(entry.deliveries ?? []).length ? entry.deliveries.slice().reverse().map((item: any) => <div key={item.id} className="rounded bg-gray-50 p-3 text-sm dark:bg-bodybg"><strong>{label(item.delivery_type)} · {label(item.trigger_key)}</strong><div className="text-xs text-gray-500">{item.recipient?.name} · sent {dateTime(item.sent_at)}</div>{item.acknowledged_at ? <div className="mt-1 text-success">Acknowledged {dateTime(item.acknowledged_at)}</div> : item.delivery_type === 'escalation' ? <div className="mt-1 flex items-center justify-between gap-2 text-warning"><span>Awaiting acknowledgement</span>{canAcknowledge ? <button type="button" className="ti-btn ti-btn-sm ti-btn-success" onClick={() => acknowledge(item)}>Acknowledge</button> : null}</div> : null}</div>) : <Empty text="No reminders or escalations delivered." />}</div></Section></div></Modal>;
}

function Metric({title, value, danger = false}: any): JSX.Element { return <div className="rounded-lg border p-3"><div className="text-xs uppercase tracking-wide text-gray-500">{title}</div><div className={`mt-1 text-2xl font-semibold ${danger && value ? 'text-danger' : ''}`}>{value ?? 0}</div></div>; }
function Section({title, children}: any): JSX.Element { return <div className="rounded-lg border"><div className="border-b px-4 py-3 font-semibold">{title}</div><div className="p-4">{children}</div></div>; }
function Details({values}: any): JSX.Element { return <dl className="grid grid-cols-1 gap-3 text-sm sm:grid-cols-2">{values.map(([title, value]: any) => <div key={title}><dt className="text-xs uppercase tracking-wide text-gray-500">{title}</dt><dd className="mt-1 break-words font-medium">{value || '—'}</dd></div>)}</dl>; }
function Field({title, children}: any): JSX.Element { return <label className="block"><span className="ti-form-label">{title}</span>{children}</label>; }
function Select({value, first, values, onChange, required = false, disabled = false}: any): JSX.Element { return <select required={required} disabled={disabled} className="ti-form-input" value={value} onChange={e => onChange(e.target.value)}><option value="">{first}</option>{values.map((item: string) => <option key={item} value={item}>{label(item)}</option>)}</select>; }
function UserSelect({users, value, onChange}: any): JSX.Element { return <select className="ti-form-input" value={value} onChange={e => onChange(e.target.value)}><option value="">Unassigned</option>{users.map((user: any) => <option key={user.id} value={user.id}>{user.name}</option>)}</select>; }
function ReminderPresetSelect({intervals, onChange}: {intervals: number[]; onChange: (intervals: number[]) => void}): JSX.Element { const current = reminderPresetKey(intervals); return <><select className="ti-form-input" value={current} onChange={event => onChange(reminderPresets[event.target.value].intervals)}>{Object.entries(reminderPresets).map(([key, preset]) => <option key={key} value={key}>{preset.label}</option>)}</select><span className="mt-1 block text-xs text-gray-500">Standard is recommended for routine deadlines. Use Frequent only for genuinely critical dates.</span></>; }
function LinkedSelect({items, value, render, onChange}: any): JSX.Element { return <select className="ti-form-input" value={value} onChange={e => onChange(e.target.value)}><option value="">Not linked</option>{items.map((item: any) => <option key={item.id} value={item.id}>{render(item)}</option>)}</select>; }
function Icon({title, icon, onClick, color = 'text-primary hover:bg-primary/10'}: any): JSX.Element { return <button type="button" title={title} aria-label={title} className={`h-8 w-8 rounded-full p-0 ti-btn ${color}`} onClick={event => { event.stopPropagation(); onClick(); }}><i className={`fa ${icon}`} /></button>; }
function Badge({value}: any): JSX.Element { const danger = ['overdue', 'critical', 'cancelled', 'rejected', 'failed'].includes(value); const success = ['completed', 'accepted', 'recorded'].includes(value); return <span className={`badge ${danger ? 'bg-danger/10 text-danger' : success ? 'bg-success/10 text-success' : 'bg-primary/10 text-primary'}`}>{label(value)}</span>; }
function Empty({text}: any): JSX.Element { return <div className="py-6 text-center text-sm text-gray-500">{text}</div>; }
function label(value: string = ''): string { return String(value ?? '').replaceAll('_', ' ').replace(/\b\w/g, letter => letter.toUpperCase()); }
function dateTime(value?: string): string { return value ? new Date(value).toLocaleString() : '—'; }
function inputDateTime(value?: string): string { if (!value) return ''; const date = new Date(value); return new Date(date.getTime() - date.getTimezoneOffset() * 60000).toISOString().slice(0, 16); }
function nullableNumber(value: any): number | null { return value === '' || value === null || value === undefined ? null : Number(value); }
function reminderPresetKey(intervals: number[] = []): string { const normalized = [...intervals].map(Number).sort((a, b) => b - a).join(','); return Object.entries(reminderPresets).find(([, preset]) => preset.intervals.join(',') === normalized)?.[0] ?? 'standard'; }
function normalize(form: any): any { const payload = {...form}; for (const key of ['responsible_user_id', 'litigation_proceeding_id', 'litigation_pleading_id', 'litigation_decision_id', 'service_process_id', 'e_filing_id', 'task_id', 'supporting_document_id', 'limitation_period_value']) if (key in payload) payload[key] = nullableNumber(payload[key]); if (payload.calculation_mode === 'manual') { payload.trigger_date = null; payload.limitation_period_value = null; payload.limitation_period_unit = null; payload.rule_reference = null; payload.rule_version = null; } else payload.deadline_at = null; return payload; }
function firstError(error: any): string | null { const errors = error?.response?.data?.errors; return errors ? String(Object.values(errors).flat()[0] ?? '') : error?.response?.data?.message ?? null; }
function patch(url: string, payload: any, token?: string) { return axios.patch(url, payload, {headers: token ? {Authorization: `Bearer ${token}`} : {}}); }
