import React, {FormEvent, useEffect, 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 categories = ['documentary', 'physical', 'electronic_digital', 'photographic', 'audio_video', 'other'];
const evidenceStatuses = ['registered', 'under_review', 'verified', 'prepared_for_submission', 'submitted', 'archived'];
const exhibitStatuses = ['proposed', 'prepared', 'submitted', 'admitted', 'rejected', 'withdrawn'];
const digitalCategories = ['electronic_digital', 'photographic', 'audio_video'];

const emptyEvidenceForm = {
    title: '', description: '', category: 'documentary', source_origin: '', date_obtained: '', date_registered: '',
    responsible_user_id: '', storage_location: '', current_custodian_user_id: '', current_custodian_name: '',
    primary_document_id: '', document_ids: [] as number[],
};

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

export default function EvidenceWorkspace({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('evidence_create');
    const canUpdate = permissions.includes('evidence_update');
    const canTransfer = permissions.includes('evidence_transfer_custody');
    const canManageExhibits = permissions.includes('evidence_manage_exhibits');
    const canVerify = permissions.includes('evidence_verify_integrity');
    const [items, setItems] = useState<any[]>([]);
    const [loading, setLoading] = useState(true);
    const [search, setSearch] = useState('');
    const [category, setCategory] = useState('');
    const [status, setStatus] = useState('');
    const [exhibitStatus, setExhibitStatus] = useState('');
    const [registeredFrom, setRegisteredFrom] = useState('');
    const [page, setPage] = useState(1);
    const [meta, setMeta] = useState({current_page: 1, last_page: 1, total: 0});
    const [formOpen, setFormOpen] = useState(false);
    const [editing, setEditing] = useState<any | null>(null);
    const [selected, setSelected] = useState<any | null>(null);
    const [actionEvidence, setActionEvidence] = useState<any | null>(null);
    const [detailLoading, setDetailLoading] = useState(false);
    const [actionMode, setActionMode] = useState<ActionMode>(null);

    async function load() {
        setLoading(true);
        try {
            const params = new URLSearchParams({litigation_case_id: String(record.id), page: String(page)});
            if (search) params.set('search', search);
            if (category) params.set('category', category);
            if (status) params.set('status', status);
            if (exhibitStatus) params.set('exhibit_status', exhibitStatus);
            if (registeredFrom) params.set('registered_from', registeredFrom);
            const response = await makeGetRequest(`/api/evidence?${params}`, {token});
            const payload = response.data?.result ?? response.data ?? {};
            const rows = payload.data ?? [];
            setItems(rows);
            setMeta({current_page: payload.current_page ?? page, last_page: payload.last_page ?? 1, total: payload.total ?? rows.length});
        } catch (error: any) {
            notify.toastErrorMessage(error?.response?.data?.message || 'Unable to load evidence register');
        } finally { setLoading(false); }
    }

    useEffect(() => { const timer = window.setTimeout(load, 250); return () => window.clearTimeout(timer); }, [record.id, token, search, category, status, exhibitStatus, registeredFrom, page]);

    async function fetchDetails(item: any) {
        setDetailLoading(true);
        try {
            const response = await makeGetRequest(`/api/evidence/${item.id}`, {token});
            return response.data?.result ?? response.data;
        } catch (error: any) {
            notify.toastErrorMessage(error?.response?.data?.message || 'Unable to load evidence details');
            return null;
        } finally { setDetailLoading(false); }
    }

    async function openDetails(item: any) {
        const evidence = await fetchDetails(item);
        if (evidence) setSelected(evidence);
    }
    async function openListEdit(item: any) {
        const evidence = await fetchDetails(item);
        if (evidence) { setEditing(evidence); setFormOpen(true); }
    }
    async function openListAction(item: any, mode: ActionMode) {
        const evidence = await fetchDetails(item);
        if (evidence) { setActionEvidence(evidence); setActionMode(mode); }
    }

    function openCreate() { setEditing(null); setFormOpen(true); }
    async function refreshSelected(updated?: any) {
        if (updated) setSelected(updated);
        else if (selected) await openDetails(selected);
        await load();
    }
    async function formSaved(updated: any) {
        setFormOpen(false);
        setEditing(null);
        if (selected?.id === updated?.id) setSelected(updated);
        await load();
    }
    async function actionSaved(updated: any) {
        setActionMode(null);
        setActionEvidence(null);
        if (selected?.id === updated?.id) setSelected(updated);
        await load();
    }
    function openSelectedAction(mode: ActionMode) {
        setActionEvidence(selected);
        setActionMode(mode);
    }

    return <>
        <div className="mb-5 flex flex-wrap items-start justify-between gap-3">
            <div><h5 className="font-semibold">Evidence register</h5><p className="text-sm text-gray-500">Evidence metadata linked to existing matter documents, custody records, and exhibits.</p></div>
            {canCreate ? <button type="button" className="ti-btn ti-btn-primary" onClick={openCreate}><i className="fa fa-plus me-2" />Register evidence</button> : null}
        </div>
        <div className="mb-5 grid grid-cols-1 gap-3 md:grid-cols-3 xl:grid-cols-5">
            <input className="ti-form-input" placeholder="Search reference, title, source…" value={search} onChange={event => { setPage(1); setSearch(event.target.value); }} />
            <select className="ti-form-input" value={category} onChange={event => { setPage(1); setCategory(event.target.value); }}><option value="">All categories</option>{categories.map(value => <option key={value} value={value}>{label(value)}</option>)}</select>
            <select className="ti-form-input" value={status} onChange={event => { setPage(1); setStatus(event.target.value); }}><option value="">All evidence statuses</option>{evidenceStatuses.map(value => <option key={value} value={value}>{label(value)}</option>)}</select>
            <select className="ti-form-input" value={exhibitStatus} onChange={event => { setPage(1); setExhibitStatus(event.target.value); }}><option value="">All exhibit statuses</option>{exhibitStatuses.map(value => <option key={value} value={value}>{label(value)}</option>)}</select>
            <input type="date" className="ti-form-input" title="Registered from" value={registeredFrom} onChange={event => { setPage(1); setRegisteredFrom(event.target.value); }} />
        </div>
        <div className="rounded-sm overflow-auto todo-table w-full">
            <table className="ti-custom-table ti-custom-table-head whitespace-nowrap w-full">
                <thead className="bg-gray-100 dark:bg-bodybg"><tr><th>Evidence</th><th>Category</th><th>Status</th><th>Exhibit</th><th>Custodian</th><th>Registered</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 evidence records found.</td></tr> : items.map(item => <tr key={item.id}>
                    <td><button type="button" className="block w-64 text-left text-indigo-600 hover:underline" onClick={() => openDetails(item)}><div className="truncate font-semibold">{item.title}</div><div className="truncate text-xs text-gray-500">{item.reference_number}</div></button></td>
                    <td>{label(item.category)}</td><td><StatusBadge value={item.status} /></td>
                    <td>{item.exhibit ? <><div className="font-medium">{item.exhibit.reference_number}</div><div className="text-xs text-gray-500">{label(item.exhibit.status)}</div></> : '—'}</td>
                    <td>{item.current_custodian?.name ?? item.current_custodian_name ?? '—'}</td><td>{date(item.date_registered)}</td>
                    <td className="text-end"><div className="flex justify-end gap-1"><button type="button" className="inline-flex h-8 w-8 items-center justify-center rounded-md text-blue-600 hover:bg-blue-50" title="View evidence" onClick={event => { event.stopPropagation(); openDetails(item); }}><i className={`fa ${detailLoading ? 'fa-spinner fa-spin' : 'fa-eye'}`} /></button>{canUpdate && item.status !== 'archived' ? <><button type="button" className="inline-flex h-8 w-8 items-center justify-center rounded-md text-gray-500 hover:bg-gray-100" title="Edit evidence" onClick={event => { event.stopPropagation(); openListEdit(item); }}><i className="fa fa-pencil" /></button><button type="button" className="inline-flex h-8 w-8 items-center justify-center rounded-md text-amber-600 hover:bg-amber-50" title="Update evidence status" onClick={event => { event.stopPropagation(); openListAction(item, 'status'); }}><i className="fa fa-refresh" /></button></> : null}{canTransfer && item.status !== 'archived' ? <button type="button" className="inline-flex h-8 w-8 items-center justify-center rounded-md text-emerald-600 hover:bg-emerald-50" title="Transfer custody" onClick={event => { event.stopPropagation(); openListAction(item, 'custody'); }}><i className="fa fa-exchange" /></button> : null}</div></td>
                </tr>)}</tbody>
            </table>
        </div>
        <ListingPagination currentPage={meta.current_page} lastPage={meta.last_page} total={meta.total} itemCount={items.length} onPageChange={setPage} />

        {formOpen ? <EvidenceForm record={record} evidence={editing} documents={documents} team={team} token={token} onClose={() => { setFormOpen(false); setEditing(null); }} onSaved={formSaved} /> : null}
        <Modal open={selected !== null} onClose={() => { setSelected(null); setActionMode(null); }} title={selected ? `${selected.reference_number} · ${selected.title}` : 'Evidence details'} maxWidthClassName="max-w-5xl" bodyClassName="max-h-[78vh] overflow-y-auto"
            footer={selected ? <EvidenceActions evidence={selected} currentUserId={auth?.user?.id} canTransfer={canTransfer} canManageExhibits={canManageExhibits} canVerify={canVerify} token={token} onAction={openSelectedAction} onUpdated={refreshSelected} /> : null}>
            {selected ? <EvidenceDetails evidence={selected} /> : null}
        </Modal>
        {actionEvidence && actionMode ? <EvidenceActionModal mode={actionMode} evidence={actionEvidence} proceedings={record.proceedings ?? []} team={team} token={token} onClose={() => { setActionMode(null); setActionEvidence(null); }} onSaved={actionSaved} /> : null}
    </>;
}

function EvidenceForm({record, evidence, documents, team, token, onClose, onSaved}: any): JSX.Element {
    const [form, setForm] = useState(() => evidence ? {
        title: evidence.title ?? '', description: evidence.description ?? '', category: evidence.category ?? 'documentary',
        source_origin: evidence.source_origin ?? '', date_obtained: dateInput(evidence.date_obtained), date_registered: dateTimeInput(evidence.date_registered),
        responsible_user_id: evidence.responsible_user_id ?? '', storage_location: evidence.storage_location ?? '',
        current_custodian_user_id: '', current_custodian_name: '', primary_document_id: evidence.primary_document_id ?? '',
        document_ids: (evidence.documents ?? []).map((document: any) => document.id),
    } : {...emptyEvidenceForm});
    const [submitting, setSubmitting] = useState(false);
    const isDigital = digitalCategories.includes(form.category);

    function toggleDocument(id: number, checked: boolean) {
        setForm({...form, document_ids: checked ? [...form.document_ids, id] : form.document_ids.filter((value: number) => value !== id)});
    }
    async function submit(event: FormEvent) {
        event.preventDefault();
        setSubmitting(true);
        const payload: any = {
            ...form, litigation_case_id: record.id, client_matter_id: record.client_matter_id,
            responsible_user_id: form.responsible_user_id ? Number(form.responsible_user_id) : null,
            primary_document_id: form.primary_document_id ? Number(form.primary_document_id) : null,
            current_custodian_user_id: form.current_custodian_user_id ? Number(form.current_custodian_user_id) : null,
            date_obtained: form.date_obtained || null, date_registered: form.date_registered || null,
        };
        if (evidence) {
            delete payload.client_matter_id; delete payload.primary_document_id;
            delete payload.current_custodian_user_id; delete payload.current_custodian_name; delete payload.date_registered;
        }
        try {
            const response = evidence ? await makePutRequest(`/api/evidence/${evidence.id}`, payload, {token}) : await makePostRequest('/api/evidence', payload, {token});
            notify.toastSuccessMessage(evidence ? 'Evidence metadata updated' : 'Evidence registered');
            onSaved(response.data?.result ?? response.data);
        } catch (error: any) {
            notify.toastErrorMessage(firstError(error) || 'Unable to save evidence');
        } finally { setSubmitting(false); }
    }

    return <Modal open={true} onClose={onClose} title={evidence ? 'Edit evidence metadata' : 'Register evidence'} maxWidthClassName="max-w-4xl" bodyClassName="max-h-[75vh] overflow-y-auto"
        footer={<><button type="button" className="ti-btn ti-btn-light" onClick={onClose} disabled={submitting}>Cancel</button><button type="submit" form="evidence-form" className="ti-btn ti-btn-primary" disabled={submitting}>{submitting ? 'Saving…' : evidence ? 'Update evidence' : 'Register evidence'}</button></>}>
        <form id="evidence-form" onSubmit={submit} className="grid grid-cols-1 gap-4 sm:grid-cols-2">
            <Field title="Evidence title"><input required className="ti-form-input" value={form.title} onChange={event => setForm({...form, title: event.target.value})} /></Field>
            <Field title="Category"><select required className="ti-form-input" value={form.category} onChange={event => setForm({...form, category: event.target.value})}>{categories.map(value => <option key={value} value={value}>{label(value)}</option>)}</select></Field>
            <div className="sm:col-span-2"><Field title="Description"><textarea rows={3} className="ti-form-input" value={form.description} onChange={event => setForm({...form, description: event.target.value})} /></Field></div>
            <Field title="Source or origin"><input className="ti-form-input" value={form.source_origin} onChange={event => setForm({...form, source_origin: event.target.value})} /></Field>
            <Field title="Date obtained"><input type="date" className="ti-form-input" value={form.date_obtained} onChange={event => setForm({...form, date_obtained: event.target.value})} /></Field>
            {!evidence ? <Field title="Date registered"><input type="datetime-local" className="ti-form-input" value={form.date_registered} onChange={event => setForm({...form, date_registered: event.target.value})} /></Field> : null}
            <Field title="Responsible staff"><select className="ti-form-input" value={form.responsible_user_id} onChange={event => setForm({...form, responsible_user_id: event.target.value})}><option value="">Current user</option>{team.map((user: any) => <option key={user.id} value={user.id}>{user.name}</option>)}</select></Field>
            <Field title="Storage location"><input className="ti-form-input" value={form.storage_location} onChange={event => setForm({...form, storage_location: event.target.value})} /></Field>
            {!evidence ? <><Field title="Initial custodian"><select className="ti-form-input" value={form.current_custodian_user_id} onChange={event => { const user = team.find((item: any) => String(item.id) === event.target.value); setForm({...form, current_custodian_user_id: event.target.value, current_custodian_name: user?.name ?? form.current_custodian_name}); }}><option value="">External or unnamed custodian</option>{team.map((user: any) => <option key={user.id} value={user.id}>{user.name}</option>)}</select></Field><Field title="Custodian name"><input className="ti-form-input" value={form.current_custodian_name} onChange={event => setForm({...form, current_custodian_name: event.target.value})} /></Field></> : null}
            {!evidence ? <div className="sm:col-span-2"><Field title={`Original evidence document${isDigital ? ' (required)' : ''}`}><select required={isDigital} className="ti-form-input" value={form.primary_document_id} onChange={event => setForm({...form, primary_document_id: event.target.value})}><option value="">No original document</option>{documents.map((document: any) => <option key={document.id} value={document.id}>{document.title} · {versionLabel(document)}</option>)}</select><p className="mt-1 text-xs text-gray-500">The active version is fixed as the original evidence version and hashed with SHA-256.</p></Field></div> : null}
            <fieldset className="sm:col-span-2 rounded-lg border p-3"><legend className="px-1 text-sm font-medium">Related existing matter documents</legend><div className="grid grid-cols-1 gap-2 sm:grid-cols-2">{documents.length ? documents.map((document: any) => <label key={document.id} className="flex items-center gap-2 text-sm"><input type="checkbox" checked={form.document_ids.includes(document.id)} onChange={event => toggleDocument(document.id, event.target.checked)} />{document.title} <span className="text-xs text-gray-500">{versionLabel(document)}</span></label>) : <span className="text-sm text-gray-500">No matter documents are available.</span>}</div></fieldset>
        </form>
    </Modal>;
}

function EvidenceActions({evidence, currentUserId, canTransfer, canManageExhibits, canVerify, token, onAction, onUpdated}: any): JSX.Element {
    const pendingTransfer = (evidence.custody_transfers ?? []).find((transfer: any) => transfer.status === 'pending_acknowledgement');
    const canAcknowledge = pendingTransfer && (canTransfer || Number(pendingTransfer.transferred_to_user_id) === Number(currentUserId));
    async function acknowledge() {
        try {
            const response = await makePostRequest(`/api/evidence/${evidence.id}/custody-transfers/${pendingTransfer.id}/acknowledge`, {}, {token});
            notify.toastSuccessMessage('Custody transfer acknowledged');
            await onUpdated(response.data?.result ?? response.data);
        } catch (error: any) { notify.toastErrorMessage(firstError(error) || 'Unable to acknowledge custody'); }
    }
    async function verify() {
        try {
            const response = await makePostRequest(`/api/evidence/${evidence.id}/verify-integrity`, {}, {token});
            const updated = response.data?.result ?? response.data;
            notify.toastSuccessMessage(updated.integrity_status === 'verified' ? 'Evidence integrity verified' : 'Integrity verification failed');
            await onUpdated(updated);
        } catch (error: any) { notify.toastErrorMessage(firstError(error) || 'Unable to verify integrity'); }
    }
    return <>
        {canManageExhibits && evidence.status !== 'archived' ? <button type="button" className="ti-btn ti-btn-light" onClick={() => onAction(evidence.exhibit ? 'exhibit_status' : 'exhibit')}>{evidence.exhibit ? 'Update exhibit' : 'Designate exhibit'}</button> : null}
        {canVerify && evidence.sha256_hash ? <button type="button" className="ti-btn ti-btn-light" onClick={verify}>Verify integrity</button> : null}
        {canAcknowledge ? <button type="button" className="ti-btn ti-btn-success" onClick={acknowledge}>Acknowledge custody</button> : null}
    </>;
}

function EvidenceDetails({evidence}: any): JSX.Element {
    const pendingTransfer = (evidence.custody_transfers ?? []).find((transfer: any) => transfer.status === 'pending_acknowledgement');
    return <div className="space-y-5">
        <div className="grid grid-cols-1 gap-4 lg:grid-cols-3"><Section title="Evidence record"><Details values={[["Reference", evidence.reference_number], ["Category", label(evidence.category)], ["Status", label(evidence.status)], ["Source", evidence.source_origin], ["Obtained", date(evidence.date_obtained)], ["Registered", dateTime(evidence.date_registered)], ["Responsible staff", evidence.responsible_user?.name], ["Description", evidence.description]]} /></Section><Section title="Custody & storage"><Details values={[["Current custodian", evidence.current_custodian?.name ?? evidence.current_custodian_name], ["Storage location", evidence.storage_location], ["Pending transfer", pendingTransfer ? pendingTransfer.transferred_to_name : null]]} /></Section><Section title="Digital integrity"><Details values={[["Status", evidence.integrity_status ? label(evidence.integrity_status) : 'Not applicable'], ["SHA-256", evidence.sha256_hash ? `${evidence.sha256_hash.slice(0, 18)}…` : null], ["Original version", evidence.original_document_version?.version], ["Last verified", dateTime(evidence.integrity_verified_at)]]} /></Section></div>
        <Section title="Related documents"><div className="divide-y">{(evidence.documents ?? []).length ? evidence.documents.map((document: any) => <div key={document.id} className="flex items-center justify-between py-2"><div><div className="font-medium">{document.title}</div><div className="text-xs text-gray-500">{label(document.document_type)} · {versionLabel(document)}</div></div><a href={`/api/documents/${document.id}/download`} target="_blank" rel="noreferrer" className="ti-btn ti-btn-soft-primary h-8 w-8 rounded-full p-0" title="View document"><i className="fa fa-eye" /></a></div>) : <Empty text="No related documents." />}</div></Section>
        <Section title="Exhibit designation">{evidence.exhibit ? <><Details values={[["Reference", evidence.exhibit.reference_number], ["Status", label(evidence.exhibit.status)], ["Classification", evidence.exhibit.classification], ["Submission date", date(evidence.exhibit.submission_date)], ["Proceeding", evidence.exhibit.proceeding?.calendar_event?.title], ["Description", evidence.exhibit.description]]} /><History items={evidence.exhibit.status_history ?? []} /></> : <Empty text="This evidence has not been designated as an exhibit." />}</Section>
        <Section title="Chain of custody"><div className="space-y-3">{(evidence.custody_transfers ?? []).length ? evidence.custody_transfers.map((transfer: any) => <div key={transfer.id} className="rounded-lg border p-3 text-sm"><div className="flex flex-wrap justify-between gap-2"><strong>{transfer.transferred_from_name} → {transfer.transferred_to_name}</strong><StatusBadge value={transfer.status} /></div><div className="mt-2 text-gray-600">{dateTime(transfer.transferred_at)} · {transfer.transfer_reason}</div><div className="mt-1 text-xs text-gray-500">{transfer.previous_storage_location || 'Unspecified location'} → {transfer.new_storage_location || 'Unchanged'}{transfer.condition_at_transfer ? ` · ${transfer.condition_at_transfer}` : ''}</div></div>) : <Empty text="No custody transfers recorded." />}</div></Section>
        <div className="grid grid-cols-1 gap-4 lg:grid-cols-2"><Section title="Evidence status history"><History items={evidence.status_history ?? []} /></Section><Section title="Integrity verification history"><div className="space-y-2">{(evidence.integrity_verifications ?? []).length ? evidence.integrity_verifications.map((entry: any) => <div key={entry.id} className="flex justify-between rounded bg-gray-50 p-2 text-sm dark:bg-bodybg"><span>{entry.verified_by?.name} · {dateTime(entry.verified_at)}</span><span className={entry.is_valid ? 'text-success' : 'text-danger'}>{entry.is_valid ? 'Passed' : 'Failed'}</span></div>) : <Empty text="No integrity verifications recorded." />}</div></Section></div>
    </div>;
}

function EvidenceActionModal({mode, evidence, proceedings, team, token, onClose, onSaved}: any): JSX.Element {
    const [submitting, setSubmitting] = useState(false);
    const [form, setForm] = useState<any>({
        status: mode === 'exhibit_status' ? evidence.exhibit?.status ?? 'proposed' : evidence.status,
        remarks: '', description: evidence.exhibit?.description ?? '', classification: evidence.exhibit?.classification ?? '',
        litigation_proceeding_id: evidence.exhibit?.litigation_proceeding_id ?? '', submission_date: dateInput(evidence.exhibit?.submission_date),
        transferred_to_user_id: '', transferred_to_name: '', transferred_at: dateTimeInput(new Date().toISOString()),
        transfer_reason: '', new_storage_location: evidence.storage_location ?? '', condition_at_transfer: '', requires_acknowledgement: true,
    });
    const titles: Record<string, string> = {status: 'Update evidence status', exhibit: 'Designate evidence as exhibit', exhibit_status: 'Update exhibit status', custody: 'Transfer evidence custody'};
    async function submit(event: FormEvent) {
        event.preventDefault(); setSubmitting(true);
        try {
            let response;
            if (mode === 'status') response = await patch(`/api/evidence/${evidence.id}/status`, {status: form.status, remarks: form.remarks}, token);
            else if (mode === 'exhibit') response = await makePostRequest(`/api/evidence/${evidence.id}/exhibit`, {description: form.description || null, classification: form.classification || null, litigation_proceeding_id: form.litigation_proceeding_id ? Number(form.litigation_proceeding_id) : null}, {token});
            else if (mode === 'exhibit_status') response = await patch(`/api/evidence/${evidence.id}/exhibit/status`, {status: form.status, remarks: form.remarks || null, submission_date: form.submission_date || null, litigation_proceeding_id: form.litigation_proceeding_id ? Number(form.litigation_proceeding_id) : null}, token);
            else response = await makePostRequest(`/api/evidence/${evidence.id}/custody-transfers`, {...form, transferred_to_user_id: form.transferred_to_user_id ? Number(form.transferred_to_user_id) : null}, {token});
            notify.toastSuccessMessage(mode === 'custody' ? 'Custody transfer recorded' : mode?.startsWith('exhibit') ? 'Exhibit updated' : 'Evidence status updated');
            onSaved(response.data?.result ?? response.data);
        } catch (error: any) { notify.toastErrorMessage(firstError(error) || 'Unable to update evidence'); }
        finally { setSubmitting(false); }
    }
    return <Modal open={true} onClose={onClose} title={titles[mode]} maxWidthClassName="max-w-2xl" footer={<><button type="button" className="ti-btn ti-btn-light" onClick={onClose}>Cancel</button><button type="submit" form="evidence-action-form" className="ti-btn ti-btn-primary" disabled={submitting}>{submitting ? 'Saving…' : 'Save'}</button></>}>
        <form id="evidence-action-form" onSubmit={submit} className="grid grid-cols-1 gap-4 sm:grid-cols-2">
            {mode === 'status' ? <><Field title="New evidence status"><select className="ti-form-input" value={form.status} onChange={event => setForm({...form, status: event.target.value})}>{evidenceStatuses.map(value => <option key={value}>{value}</option>)}</select></Field><div className="sm:col-span-2"><Field title="Remarks"><textarea className="ti-form-input" rows={3} value={form.remarks} onChange={event => setForm({...form, remarks: event.target.value})} /></Field></div></> : null}
            {mode === 'exhibit' ? <><Field title="Classification"><input className="ti-form-input" value={form.classification} onChange={event => setForm({...form, classification: event.target.value})} /></Field><Field title="Related proceeding"><ProceedingSelect value={form.litigation_proceeding_id} proceedings={proceedings} onChange={(value: string) => setForm({...form, litigation_proceeding_id: value})} /></Field><div className="sm:col-span-2"><Field title="Exhibit description"><textarea required className="ti-form-input" rows={3} value={form.description} onChange={event => setForm({...form, description: event.target.value})} /></Field></div></> : null}
            {mode === 'exhibit_status' ? <><Field title="New exhibit status"><select className="ti-form-input" value={form.status} onChange={event => setForm({...form, status: event.target.value})}>{exhibitStatuses.map(value => <option key={value}>{value}</option>)}</select></Field><Field title="Submission or presentation date"><input type="date" className="ti-form-input" value={form.submission_date} onChange={event => setForm({...form, submission_date: event.target.value})} /></Field><Field title="Related proceeding"><ProceedingSelect value={form.litigation_proceeding_id} proceedings={proceedings} onChange={(value: string) => setForm({...form, litigation_proceeding_id: value})} /></Field><div className="sm:col-span-2"><Field title="Remarks"><textarea className="ti-form-input" rows={3} value={form.remarks} onChange={event => setForm({...form, remarks: event.target.value})} /></Field></div></> : null}
            {mode === 'custody' ? <><Field title="Receiving staff"><select className="ti-form-input" value={form.transferred_to_user_id} onChange={event => { const user = team.find((item: any) => String(item.id) === event.target.value); setForm({...form, transferred_to_user_id: event.target.value, transferred_to_name: user?.name ?? form.transferred_to_name}); }}><option value="">External custodian</option>{team.map((user: any) => <option key={user.id} value={user.id}>{user.name}</option>)}</select></Field><Field title="Receiving person or entity"><input required className="ti-form-input" value={form.transferred_to_name} onChange={event => setForm({...form, transferred_to_name: event.target.value})} /></Field><Field title="Transfer date and time"><input required type="datetime-local" className="ti-form-input" value={form.transferred_at} onChange={event => setForm({...form, transferred_at: event.target.value})} /></Field><Field title="New storage location"><input className="ti-form-input" value={form.new_storage_location} onChange={event => setForm({...form, new_storage_location: event.target.value})} /></Field><div className="sm:col-span-2"><Field title="Transfer reason"><textarea required minLength={5} className="ti-form-input" rows={2} value={form.transfer_reason} onChange={event => setForm({...form, transfer_reason: event.target.value})} /></Field></div><div className="sm:col-span-2"><Field title="Condition at transfer"><textarea className="ti-form-input" rows={2} value={form.condition_at_transfer} onChange={event => setForm({...form, condition_at_transfer: event.target.value})} /></Field></div><label className="sm:col-span-2 flex items-center gap-2 text-sm"><input type="checkbox" checked={form.requires_acknowledgement} onChange={event => setForm({...form, requires_acknowledgement: event.target.checked})} />Require receiving custodian acknowledgement before completing transfer</label></> : null}
        </form>
    </Modal>;
}

function ProceedingSelect({value, proceedings, onChange}: any): JSX.Element { return <select className="ti-form-input" value={value} onChange={event => onChange(event.target.value)}><option value="">No proceeding selected</option>{proceedings.map((item: any) => <option key={item.id} value={item.id}>{item.calendar_event?.title ?? label(item.hearing_type)} · {date(item.calendar_event?.starts_at)}</option>)}</select>; }
function Field({title, children}: {title: string; children: React.ReactNode}): JSX.Element { return <label className="block"><span className="ti-form-label">{title}</span>{children}</label>; }
function Section({title, children}: {title: string; children: React.ReactNode}): 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}: {values: Array<[string, any]>}): JSX.Element { return <dl className="grid grid-cols-1 gap-3 text-sm sm:grid-cols-2">{values.map(([title, value]) => <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 History({items}: {items: any[]}): JSX.Element { return <div className="mt-3 space-y-2">{items.length ? items.map(item => <div key={item.id} className="rounded bg-gray-50 p-2 text-sm dark:bg-bodybg"><strong>{item.previous_status ? `${label(item.previous_status)} → ` : ''}{label(item.new_status)}</strong><div className="text-xs text-gray-500">{item.changed_by?.name ?? 'System'} · {dateTime(item.created_at)}</div>{item.remarks ? <div className="mt-1 text-gray-600">{item.remarks}</div> : null}</div>) : <Empty text="No status history." />}</div>; }
function Empty({text}: {text: string}): JSX.Element { return <div className="py-4 text-center text-sm text-gray-500">{text}</div>; }
function StatusBadge({value}: {value: string}): JSX.Element { const danger = ['failed', 'rejected', 'withdrawn', 'cancelled'].includes(value); const success = ['verified', 'admitted', 'completed'].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 label(value: string = ''): string { return value.replaceAll('_', ' ').replace(/\b\w/g, letter => letter.toUpperCase()); }
function date(value?: string): string { return value ? new Date(value).toLocaleDateString() : '—'; }
function dateTime(value?: string): string { return value ? new Date(value).toLocaleString() : '—'; }
function dateInput(value?: string): string { return value ? String(value).slice(0, 10) : ''; }
function dateTimeInput(value?: string): string { if (!value) return ''; const parsed = new Date(value); return new Date(parsed.getTime() - parsed.getTimezoneOffset() * 60000).toISOString().slice(0, 16); }
function versionLabel(document: any): string { const version = typeof document.current_version === 'object' ? document.current_version?.version : document.current_version; return version ? (String(version).toLowerCase().startsWith('v') ? String(version) : `v${version}`) : 'No active version'; }
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}`} : {}}); }
