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 {makeDeleteRequest, makeGetRequest, makePostRequest, makePutRequest} from '@/lib/request';
import {notify} from '@/lib/notify';

const categories = ['fact', 'expert', 'character', 'other'];
const witnessStatuses = ['identified', 'contacted', 'available', 'scheduled', 'completed', 'withdrawn'];
const statementTypes = ['witness_statement', 'affidavit', 'expert_report', 'supplementary_statement', 'other'];
const statementStatuses = ['draft', 'pending_review', 'reviewed', 'approved', 'rejected'];
const appearanceStatuses = ['scheduled', 'confirmed', 'appeared', 'did_not_appear', 'cancelled'];
const examinationTypes = ['examination_in_chief', 'cross_examination', 're_examination', 'other'];
const witnessTransitions: Record<string, string[]> = {identified: ['contacted', 'withdrawn'], contacted: ['identified', 'available', 'withdrawn'], available: ['contacted', 'scheduled', 'withdrawn'], scheduled: ['available', 'completed', 'withdrawn'], completed: [], withdrawn: []};
const statementTransitions: Record<string, string[]> = {draft: ['pending_review'], pending_review: ['draft', 'reviewed', 'rejected'], reviewed: ['pending_review', 'approved', 'rejected'], approved: [], rejected: ['draft']};
const appearanceTransitions: Record<string, string[]> = {scheduled: ['confirmed', 'appeared', 'did_not_appear', 'cancelled'], confirmed: ['appeared', 'did_not_appear', 'cancelled'], appeared: [], did_not_appear: [], cancelled: []};

type Props = {record: any; documents: any[]; team: any[]; token?: string};
type DetailTab = 'profile' | 'statements' | 'schedule' | 'examinations' | 'evidence' | 'communications';
type ChildMode = 'statement' | 'statement_status' | 'availability' | 'appearance' | 'appearance_status' | 'examination' | null;

export default function WitnessWorkspace({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('witness_create');
    const canUpdate = permissions.includes('witness_update');
    const canSensitive = permissions.includes('witness_view_sensitive');
    const canStatements = permissions.includes('witness_manage_statements');
    const canAvailability = permissions.includes('witness_manage_availability');
    const canAppearances = permissions.includes('witness_manage_appearances');
    const canExaminations = permissions.includes('witness_manage_examinations');
    const canFinalize = permissions.includes('witness_finalize_examinations');
    const canEvidence = permissions.includes('evidence_read');
    const canCommunications = permissions.includes('communications_read');
    const [items, setItems] = useState<any[]>([]);
    const [meta, setMeta] = useState({current_page: 1, last_page: 1, total: 0});
    const [page, setPage] = useState(1);
    const [loading, setLoading] = useState(true);
    const [search, setSearch] = useState('');
    const [category, setCategory] = useState('');
    const [status, setStatus] = useState('');
    const [hearingId, setHearingId] = useState('');
    const [lawyerId, setLawyerId] = useState('');
    const [selected, setSelected] = useState<any | null>(null);
    const [detailTab, setDetailTab] = useState<DetailTab>('profile');
    const [formOpen, setFormOpen] = useState(false);
    const [editing, setEditing] = useState<any | null>(null);
    const [statusWitness, setStatusWitness] = useState<any | null>(null);
    const [childMode, setChildMode] = useState<ChildMode>(null);
    const [childEditing, setChildEditing] = useState<any | null>(null);
    const [evidenceOptions, setEvidenceOptions] = useState<any[]>([]);

    const communications = canCommunications ? record.matter?.communications ?? [] : [];
    const proceedings = record.proceedings ?? [];

    async function load() {
        setLoading(true);
        try {
            const params = new URLSearchParams({page: String(page)});
            if (search) params.set('search', search);
            if (category) params.set('category', category);
            if (status) params.set('status', status);
            if (hearingId) params.set('hearing_id', hearingId);
            if (lawyerId) params.set('responsible_lawyer_id', lawyerId);
            const response = await makeGetRequest(`/api/litigation/${record.id}/witnesses?${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(firstError(error) || 'Unable to load witnesses'); }
        finally { setLoading(false); }
    }

    async function loadEvidence() {
        if (!canEvidence) return;
        try {
            const response = await makeGetRequest(`/api/evidence?litigation_case_id=${record.id}&per_page=200`, {token});
            const payload = response.data?.result ?? response.data ?? {};
            setEvidenceOptions(payload.data ?? []);
        } catch { setEvidenceOptions([]); }
    }

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

    async function fetchDetails(item: any) {
        try {
            const response = await makeGetRequest(`/api/litigation/${record.id}/witnesses/${item.id}`, {token});
            return response.data?.result ?? response.data;
        } catch (error: any) { notify.toastErrorMessage(firstError(error) || 'Unable to load witness details'); return null; }
    }
    async function openDetails(item: any) { const witness = await fetchDetails(item); if (witness) { setSelected(witness); setDetailTab('profile'); } }
    async function openEdit(item: any) { const witness = await fetchDetails(item); if (witness) { setEditing(witness); setFormOpen(true); } }
    function openChild(mode: ChildMode, item: any = null) { setChildMode(mode); setChildEditing(item); }
    async function updated(witness: any) { if (selected?.id === witness?.id) setSelected(witness); await load(); }

    return <>
        <div className="mb-5 flex flex-wrap items-start justify-between gap-3">
            <div><h5 className="font-semibold">Witness register</h5><p className="text-sm text-gray-500">Witness profiles, statements, availability, appearances, examinations, and related evidence.</p></div>
            {canCreate ? <button type="button" className="ti-btn ti-btn-primary" onClick={() => { setEditing(null); setFormOpen(true); }}><i className="fa fa-plus me-2" />Register witness</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 witness name or reference…" 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)} witness</option>)}</select>
            <select className="ti-form-input" value={status} onChange={event => { setPage(1); setStatus(event.target.value); }}><option value="">All statuses</option>{witnessStatuses.map(value => <option key={value}>{value}</option>)}</select>
            <select className="ti-form-input" value={hearingId} onChange={event => { setPage(1); setHearingId(event.target.value); }}><option value="">All hearings</option>{proceedings.map((item: any) => <option key={item.id} value={item.id}>{item.calendar_event?.title ?? label(item.hearing_type)}</option>)}</select>
            <select className="ti-form-input" value={lawyerId} onChange={event => { setPage(1); setLawyerId(event.target.value); }}><option value="">All responsible lawyers</option>{team.map((user: any) => <option key={user.id} value={user.id}>{user.name}</option>)}</select>
        </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>Witness</th><th>Category</th><th>Status</th><th>Responsible lawyer</th><th>Next appearance</th><th className="!text-end">Actions</th></tr></thead>
                <tbody>{loading ? <tr><td colSpan={6} className="py-8 text-center">Loading…</td></tr> : items.length === 0 ? <tr><td colSpan={6} className="py-8 text-center text-gray-500">No witnesses found.</td></tr> : items.map(item => {
                    const next = (item.appearances ?? []).find((appearance: any) => ['scheduled', 'confirmed'].includes(appearance.appearance_status));
                    return <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.profile?.full_name}</div><div className="truncate text-xs text-gray-500">{item.profile?.reference_number}</div></button></td>
                        <td>{label(item.category)} witness</td><td><StatusBadge value={item.status} /></td><td>{item.responsible_lawyer?.name ?? '—'}</td>
                        <td>{next ? <><div>{dateTime(next.expected_appearance_at)}</div><div className={`text-xs ${next.has_availability_conflict ? 'text-danger' : 'text-gray-500'}`}>{next.has_availability_conflict ? 'Availability conflict' : label(next.appearance_status)}</div></> : '—'}</td>
                        <td className="text-end"><div className="flex justify-end gap-1"><IconButton title="View witness" icon="fa-eye" color="text-blue-600 hover:bg-blue-50" onClick={() => openDetails(item)} />{canUpdate ? <><IconButton title="Edit witness" icon="fa-pencil" onClick={() => openEdit(item)} /><IconButton title="Update witness status" icon="fa-refresh" color="text-amber-600 hover:bg-amber-50" onClick={() => setStatusWitness(item)} /></> : 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 ? <WitnessForm record={record} witness={editing} documents={documents} evidence={evidenceOptions} communications={communications} team={team} canSensitive={canSensitive} token={token} onClose={() => { setFormOpen(false); setEditing(null); }} onSaved={async (witness: any) => { setFormOpen(false); setEditing(null); await updated(witness); }} /> : null}
        {statusWitness ? <StatusModal title="Update witness status" current={statusWitness.status} statuses={witnessTransitions[statusWitness.status] ?? []} field="status" endpoint={`/api/litigation/${record.id}/witnesses/${statusWitness.id}/status`} token={token} onClose={() => setStatusWitness(null)} onSaved={async (witness: any) => { setStatusWitness(null); await updated(witness); }} /> : null}
        <Modal open={selected !== null} onClose={() => { setSelected(null); setChildMode(null); }} title={selected ? `${selected.profile?.reference_number} · ${selected.profile?.full_name}` : 'Witness details'} maxWidthClassName="max-w-6xl" bodyClassName="max-h-[78vh] overflow-y-auto">
            {selected ? <WitnessDetails witness={selected} active={detailTab} setActive={setDetailTab} canSensitive={canSensitive} canStatements={canStatements} canAvailability={canAvailability} canAppearances={canAppearances} canExaminations={canExaminations} canFinalize={canFinalize} canEvidence={canEvidence} canCommunications={canCommunications} onChild={openChild} token={token} onUpdated={updated} /> : null}
        </Modal>
        {selected && childMode ? <ChildForm mode={childMode} witness={selected} editing={childEditing} proceedings={proceedings} documents={documents} evidence={evidenceOptions} team={team} token={token} onClose={() => { setChildMode(null); setChildEditing(null); }} onSaved={async (witness: any) => { setChildMode(null); setChildEditing(null); setSelected(witness); await load(); }} /> : null}
    </>;
}

function WitnessForm({record, witness, evidence, communications, team, canSensitive, token, onClose, onSaved}: any): JSX.Element {
    const profile = witness?.profile ?? {};
    const [submitting, setSubmitting] = useState(false);
    const [form, setForm] = useState<any>({
        full_name: profile.full_name ?? '', email: profile.email ?? '', phone: profile.phone ?? '', address: profile.address ?? '',
        professional_details: profile.professional_details ?? '', expertise: profile.expertise ?? '', category: witness?.category ?? 'fact',
        relationship_to_case: witness?.relationship_to_case ?? '', litigation_party_id: witness?.litigation_party_id ?? '', associated_party: witness?.associated_party ?? '',
        responsible_lawyer_id: witness?.responsible_lawyer_id ?? '', remarks: witness?.remarks ?? '',
        evidence_ids: (witness?.evidence_records ?? []).map((item: any) => item.id), communication_ids: (witness?.communications ?? []).map((item: any) => item.id),
    });
    async function submit(event: FormEvent) {
        event.preventDefault(); setSubmitting(true);
        const payload = {...form, litigation_party_id: numberOrNull(form.litigation_party_id), responsible_lawyer_id: numberOrNull(form.responsible_lawyer_id)};
        if (!canSensitive) { delete payload.email; delete payload.phone; delete payload.address; }
        try {
            const response = witness ? await makePutRequest(`/api/litigation/${record.id}/witnesses/${witness.id}`, payload, {token}) : await makePostRequest(`/api/litigation/${record.id}/witnesses`, payload, {token});
            notify.toastSuccessMessage(witness ? 'Witness updated' : 'Witness registered'); onSaved(response.data?.result ?? response.data);
        } catch (error: any) { notify.toastErrorMessage(firstError(error) || 'Unable to save witness'); }
        finally { setSubmitting(false); }
    }
    return <Modal open={true} onClose={onClose} title={witness ? 'Edit witness' : 'Register witness'} maxWidthClassName="max-w-4xl" bodyClassName="max-h-[75vh] overflow-y-auto" footer={<><button type="button" className="ti-btn ti-btn-light" onClick={onClose}>Cancel</button><button type="submit" form="witness-form" className="ti-btn ti-btn-primary" disabled={submitting}>{submitting ? 'Saving…' : witness ? 'Update witness' : 'Register witness'}</button></>}>
        <form id="witness-form" onSubmit={submit} className="grid grid-cols-1 gap-4 sm:grid-cols-2">
            <Field label="Full name"><input required className="ti-form-input" value={form.full_name} onChange={e => setForm({...form, full_name: e.target.value})} /></Field>
            <Field label="Witness category"><select required className="ti-form-input" value={form.category} onChange={e => setForm({...form, category: e.target.value})}>{categories.map(value => <option key={value} value={value}>{label(value)} witness</option>)}</select></Field>
            {canSensitive ? <><Field label="Email"><input type="email" className="ti-form-input" value={form.email} onChange={e => setForm({...form, email: e.target.value})} /></Field><Field label="Phone"><input className="ti-form-input" value={form.phone} onChange={e => setForm({...form, phone: e.target.value})} /></Field><div className="sm:col-span-2"><Field label="Address"><textarea className="ti-form-input" rows={2} value={form.address} onChange={e => setForm({...form, address: e.target.value})} /></Field></div></> : null}
            <Field label="Relationship to case"><input className="ti-form-input" value={form.relationship_to_case} onChange={e => setForm({...form, relationship_to_case: e.target.value})} /></Field>
            <Field label="Associated party"><input className="ti-form-input" value={form.associated_party} onChange={e => setForm({...form, associated_party: e.target.value})} /></Field>
            <Field label="Case party record"><select className="ti-form-input" value={form.litigation_party_id} onChange={e => setForm({...form, litigation_party_id: e.target.value})}><option value="">No structured party selected</option>{(record.parties ?? []).map((party: any) => <option key={party.id} value={party.id}>{party.name} · {label(party.role)}</option>)}</select></Field>
            <Field label="Responsible lawyer"><select className="ti-form-input" value={form.responsible_lawyer_id} onChange={e => setForm({...form, responsible_lawyer_id: e.target.value})}><option value="">Not assigned</option>{team.map((user: any) => <option key={user.id} value={user.id}>{user.name}</option>)}</select></Field>
            <div className="sm:col-span-2"><Field label="Professional details"><textarea className="ti-form-input" rows={2} value={form.professional_details} onChange={e => setForm({...form, professional_details: e.target.value})} /></Field></div>
            <div className="sm:col-span-2"><Field label="Expertise"><textarea className="ti-form-input" rows={2} value={form.expertise} onChange={e => setForm({...form, expertise: e.target.value})} /></Field></div>
            <div className="sm:col-span-2"><Field label="General remarks"><textarea className="ti-form-input" rows={3} value={form.remarks} onChange={e => setForm({...form, remarks: e.target.value})} /></Field></div>
            <Checklist label="Related evidence" items={evidence} selected={form.evidence_ids} setSelected={(ids: number[]) => setForm({...form, evidence_ids: ids})} render={(item: any) => `${item.reference_number} · ${item.title}`} />
            <Checklist label="Related matter communications" items={communications} selected={form.communication_ids} setSelected={(ids: number[]) => setForm({...form, communication_ids: ids})} render={(item: any) => `${dateTime(item.communication_date)} · ${item.subject || label(item.type)}`} />
        </form>
    </Modal>;
}

function WitnessDetails({witness, active, setActive, canSensitive, canStatements, canAvailability, canAppearances, canExaminations, canFinalize, canEvidence, canCommunications, onChild, token, onUpdated}: any): JSX.Element {
    const tabs: Array<[DetailTab, string]> = [['profile', 'Profile'], ['statements', 'Statements'], ['schedule', 'Availability & hearings'], ['examinations', 'Examinations'], ...(canEvidence ? [['evidence', 'Evidence & exhibits'] as [DetailTab, string]] : []), ...(canCommunications ? [['communications', 'Communications & follow-up'] as [DetailTab, string]] : [])];
    async function remove(kind: 'availability' | 'appearances', item: any) {
        if (!confirm(`Remove this ${kind === 'availability' ? 'availability entry' : 'hearing appearance'}?`)) return;
        try {
            const response = await makeDeleteRequest(`/api/litigation/${witness.litigation_case_id}/witnesses/${witness.id}/${kind}/${item.id}`, {token});
            notify.toastSuccessMessage('Record removed'); await onUpdated(response.data?.result ?? response.data);
        } catch (error: any) { notify.toastErrorMessage(firstError(error) || 'Unable to remove record'); }
    }
    async function finalize(item: any) {
        if (!confirm('Finalize this examination record?')) return;
        try {
            const response = await makePostRequest(`/api/litigation/${witness.litigation_case_id}/witnesses/${witness.id}/examinations/${item.id}/finalize`, {}, {token});
            notify.toastSuccessMessage('Examination finalized'); await onUpdated(response.data?.result ?? response.data);
        } catch (error: any) { notify.toastErrorMessage(firstError(error) || 'Unable to finalize examination'); }
    }
    return <div>
        <div className="mb-5 overflow-x-auto border-b"><nav className="flex min-w-max">{tabs.map(([key, title]) => <button key={key} type="button" onClick={() => setActive(key)} className={`border-b-2 px-4 py-3 text-sm font-medium ${active === key ? 'border-primary text-primary' : 'border-transparent text-gray-500'}`}>{title}</button>)}</nav></div>
        {active === 'profile' ? <div className="grid grid-cols-1 gap-4 lg:grid-cols-2"><Section title="Witness profile"><Details values={[["Reference", witness.profile?.reference_number], ["Name", witness.profile?.full_name], ["Email", canSensitive ? witness.profile?.email : 'Restricted'], ["Phone", canSensitive ? witness.profile?.phone : 'Restricted'], ["Address", canSensitive ? witness.profile?.address : 'Restricted'], ["Professional details", witness.profile?.professional_details], ["Expertise", witness.profile?.expertise]]} /></Section><Section title="Case association"><Details values={[["Category", `${label(witness.category)} witness`], ["Status", label(witness.status)], ["Relationship", witness.relationship_to_case], ["Associated party", witness.party?.name ?? witness.associated_party], ["Responsible lawyer", witness.responsible_lawyer?.name], ["Remarks", witness.remarks]]} /><History items={witness.status_history ?? []} statusKey="new_status" /></Section><Section title="Accessible associated matters"><div className="space-y-2">{(witness.profile?.litigation_associations ?? []).map((association: any) => <div key={association.id} className="rounded bg-gray-50 p-2 text-sm dark:bg-bodybg"><strong>{association.litigation_case?.case_number}</strong><div className="text-xs text-gray-500">{association.litigation_case?.case_title} · {association.litigation_case?.matter?.reference_number}</div></div>)}</div></Section></div> : null}
        {active === 'statements' ? <div><SectionHeader title="Witness statements" canAdd={canStatements} onAdd={() => onChild('statement')} /><Table empty="No witness statements recorded." headers={['Reference', 'Date', 'Type', 'Review status', 'Document', 'Evidence', 'Actions']} rows={(witness.statements ?? []).map((item: any) => [item.reference_number, date(item.statement_date), label(item.statement_type), <StatusBadge key={`ss-${item.id}`} value={item.review_status} />, item.document?.title ?? '—', (item.evidence_records ?? []).map((e: any) => e.reference_number).join(', ') || '—', canStatements ? <div key={`sa-${item.id}`} className="flex justify-end gap-1"><IconButton title="Edit statement" icon="fa-pencil" onClick={() => onChild('statement', item)} /><IconButton title="Update review status" icon="fa-refresh" color="text-amber-600 hover:bg-amber-50" onClick={() => onChild('statement_status', item)} /></div> : '—'])} /></div> : null}
        {active === 'schedule' ? <div className="space-y-5"><div><SectionHeader title="Availability" canAdd={canAvailability} onAdd={() => onChild('availability')} /><Table empty="No availability information recorded." headers={['Type', 'From', 'To', 'Remarks', 'Actions']} rows={(witness.availabilities ?? []).map((item: any) => [label(item.availability_type), dateTime(item.starts_at), dateTime(item.ends_at), item.remarks || '—', canAvailability ? <div key={`av-${item.id}`} className="flex justify-end gap-1"><IconButton title="Edit availability" icon="fa-pencil" onClick={() => onChild('availability', item)} /><IconButton title="Remove availability" icon="fa-trash" color="text-danger hover:bg-red-50" onClick={() => remove('availability', item)} /></div> : '—'])} /></div><div><SectionHeader title="Hearing appearances" canAdd={canAppearances} onAdd={() => onChild('appearance')} /><Table empty="No witness appearances scheduled." headers={['Hearing', 'Expected', 'Status', 'Participation', 'Conflict', 'Actions']} rows={(witness.appearances ?? []).map((item: any) => [item.proceeding?.calendar_event?.title ?? label(item.proceeding?.hearing_type), dateTime(item.expected_appearance_at), <StatusBadge key={`as-${item.id}`} value={item.appearance_status} />, item.participation_type || '—', item.has_availability_conflict ? <span key={`ac-${item.id}`} className="text-danger" title={item.conflict_details}>Conflict</span> : 'None', canAppearances ? <div key={`aa-${item.id}`} className="flex justify-end gap-1"><IconButton title="Edit appearance" icon="fa-pencil" onClick={() => onChild('appearance', item)} /><IconButton title="Update appearance status" icon="fa-refresh" color="text-amber-600 hover:bg-amber-50" onClick={() => onChild('appearance_status', item)} /><IconButton title="Remove appearance" icon="fa-trash" color="text-danger hover:bg-red-50" onClick={() => remove('appearances', item)} /></div> : '—'])} /></div></div> : null}
        {active === 'examinations' ? <div><SectionHeader title="Examination records" canAdd={canExaminations} onAdd={() => onChild('examination')} /><div className="space-y-3">{(witness.examinations ?? []).length ? witness.examinations.map((item: any) => <div key={item.id} className="rounded-lg border p-4"><div className="flex flex-wrap items-start justify-between gap-3"><div><h6 className="font-semibold">{label(item.examination_type)}</h6><p className="text-sm text-gray-500">{item.proceeding?.calendar_event?.title} · {dateTime(item.examination_date)} · {item.examining_lawyer?.name ?? 'Examining lawyer not recorded'}</p></div><div className="flex items-center gap-2"><StatusBadge value={item.status} />{canExaminations && (item.status !== 'finalized' || canFinalize) ? <IconButton title="Edit examination" icon="fa-pencil" onClick={() => onChild('examination', item)} /> : null}{canFinalize && item.status !== 'finalized' ? <button type="button" className="ti-btn ti-btn-success" onClick={() => finalize(item)}>Finalize</button> : null}</div></div><p className="mt-3 text-sm">{item.summary}</p>{item.observations ? <p className="mt-2 text-sm text-gray-600"><strong>Observations:</strong> {item.observations}</p> : null}<div className="mt-2 text-xs text-gray-500">Evidence: {(item.evidence_records ?? []).map((e: any) => e.reference_number).join(', ') || 'None'} · Exhibits: {(item.exhibits ?? []).map((e: any) => e.reference_number).join(', ') || 'None'} · Documents: {(item.documents ?? []).map((d: any) => d.title).join(', ') || 'None'}</div></div>) : <Empty text="No examination records." />}</div></div> : null}
        {active === 'evidence' ? <div className="grid grid-cols-1 gap-4 lg:grid-cols-2"><Section title="Witness-related evidence"><RelatedEvidence items={witness.evidence_records ?? []} /></Section><Section title="Statement and examination references"><div className="space-y-3">{(witness.statements ?? []).map((statement: any) => <div key={statement.id} className="text-sm"><strong>{statement.reference_number}</strong><div className="text-xs text-gray-500">{(statement.evidence_records ?? []).map((e: any) => e.reference_number).join(', ') || 'No evidence linked'}</div></div>)}{(witness.examinations ?? []).map((exam: any) => <div key={`exam-${exam.id}`} className="text-sm"><strong>{label(exam.examination_type)}</strong><div className="text-xs text-gray-500">{[...(exam.evidence_records ?? []).map((e: any) => e.reference_number), ...(exam.exhibits ?? []).map((e: any) => e.reference_number)].join(', ') || 'No evidence or exhibits linked'}</div></div>)}</div></Section></div> : null}
        {active === 'communications' ? <Table empty="No witness communications linked. Record interactions in Communications, then link them by editing the witness." headers={['Date', 'Type', 'Subject', 'Follow-up', 'Task']} rows={(witness.communications ?? []).map((item: any) => [dateTime(item.communication_date), label(item.type), item.subject || '—', item.follow_up_required ? `${dateTime(item.follow_up_at)} · ${item.follow_up_user?.name ?? 'Unassigned'}` : 'None', item.follow_up_task?.title ?? '—'])} /> : null}
    </div>;
}

function ChildForm({mode, witness, editing, proceedings, documents, evidence, team, token, onClose, onSaved}: any): JSX.Element {
    const [submitting, setSubmitting] = useState(false);
    const [form, setForm] = useState<any>(() => childInitial(mode, editing));
    const base = `/api/litigation/${witness.litigation_case_id}/witnesses/${witness.id}`;
    async function submit(event: FormEvent) {
        event.preventDefault(); setSubmitting(true);
        try {
            let response;
            if (mode === 'statement_status') response = await patch(`${base}/statements/${editing.id}/status`, {review_status: form.status, remarks: form.remarks || null}, token);
            else if (mode === 'appearance_status') response = await patch(`${base}/appearances/${editing.id}/status`, {appearance_status: form.status, remarks: form.remarks || null}, token);
            else {
                const resource = mode === 'statement' ? 'statements' : mode === 'availability' ? 'availability' : mode === 'appearance' ? 'appearances' : 'examinations';
                const url = `${base}/${resource}${editing ? `/${editing.id}` : ''}`;
                response = editing ? await makePutRequest(url, normalizeChild(mode, form), {token}) : await makePostRequest(url, normalizeChild(mode, form), {token});
            }
            notify.toastSuccessMessage('Witness record saved'); onSaved(response.data?.result ?? response.data);
        } catch (error: any) { notify.toastErrorMessage(firstError(error) || 'Unable to save witness record'); }
        finally { setSubmitting(false); }
    }
    const title = mode === 'statement' ? `${editing ? 'Edit' : 'Add'} witness statement` : mode === 'statement_status' ? 'Update statement review status' : mode === 'availability' ? `${editing ? 'Edit' : 'Add'} witness availability` : mode === 'appearance' ? `${editing ? 'Edit' : 'Schedule'} witness appearance` : mode === 'appearance_status' ? 'Update appearance status' : `${editing ? 'Edit' : 'Add'} examination record`;
    const exhibitOptions = evidence.map((item: any) => item.exhibit).filter(Boolean);
    return <Modal open={true} onClose={onClose} title={title} maxWidthClassName="max-w-3xl" bodyClassName="max-h-[75vh] overflow-y-auto" footer={<><button type="button" className="ti-btn ti-btn-light" onClick={onClose}>Cancel</button><button type="submit" form="witness-child-form" className="ti-btn ti-btn-primary" disabled={submitting}>{submitting ? 'Saving…' : 'Save'}</button></>}>
        <form id="witness-child-form" onSubmit={submit} className="grid grid-cols-1 gap-4 sm:grid-cols-2">
            {mode === 'statement' ? <><Field label="Statement date"><input required type="date" className="ti-form-input" value={form.statement_date} onChange={e => setForm({...form, statement_date: e.target.value})} /></Field><Field label="Statement type"><select required className="ti-form-input" value={form.statement_type} onChange={e => setForm({...form, statement_type: e.target.value})}>{statementTypes.map(v => <option key={v}>{v}</option>)}</select></Field><Field label="Responsible lawyer"><UserSelect value={form.responsible_lawyer_id} users={team} onChange={(value: string) => setForm({...form, responsible_lawyer_id: value})} /></Field><Field label="Statement document"><DocumentSelect value={form.document_id} documents={documents} onChange={(value: string) => setForm({...form, document_id: value})} /></Field><div className="sm:col-span-2"><Field label="Summary"><textarea className="ti-form-input" rows={3} value={form.summary} onChange={e => setForm({...form, summary: e.target.value})} /></Field></div><div className="sm:col-span-2"><Field label="Remarks"><textarea className="ti-form-input" rows={2} value={form.remarks} onChange={e => setForm({...form, remarks: e.target.value})} /></Field></div><Checklist label="Referenced evidence" items={evidence} selected={form.evidence_ids} setSelected={(ids: number[]) => setForm({...form, evidence_ids: ids})} render={(item: any) => `${item.reference_number} · ${item.title}`} /></> : null}
            {mode === 'statement_status' ? <><Field label="New review status"><select required className="ti-form-input" value={form.status} onChange={e => setForm({...form, status: e.target.value})}>{(statementTransitions[editing.review_status] ?? []).map(v => <option key={v}>{v}</option>)}</select></Field><div className="sm:col-span-2"><Field label="Remarks"><textarea className="ti-form-input" rows={3} value={form.remarks} onChange={e => setForm({...form, remarks: e.target.value})} /></Field></div></> : null}
            {mode === 'availability' ? <><Field label="Availability"><select required className="ti-form-input" value={form.availability_type} onChange={e => setForm({...form, availability_type: e.target.value})}><option value="available">Available</option><option value="unavailable">Unavailable</option></select></Field><Field label="Starts"><input required type="datetime-local" className="ti-form-input" value={form.starts_at} onChange={e => setForm({...form, starts_at: e.target.value})} /></Field><Field label="Ends"><input required type="datetime-local" className="ti-form-input" value={form.ends_at} onChange={e => setForm({...form, ends_at: e.target.value})} /></Field><div className="sm:col-span-2"><Field label="Remarks"><textarea className="ti-form-input" rows={3} value={form.remarks} onChange={e => setForm({...form, remarks: e.target.value})} /></Field></div></> : null}
            {mode === 'appearance' ? <><Field label="Hearing"><ProceedingSelect value={form.litigation_proceeding_id} proceedings={proceedings} onChange={(value: string) => setForm({...form, litigation_proceeding_id: value})} /></Field><Field label="Expected appearance"><input required type="datetime-local" className="ti-form-input" value={form.expected_appearance_at} onChange={e => setForm({...form, expected_appearance_at: e.target.value})} /></Field><Field label="Participation type"><input className="ti-form-input" value={form.participation_type} onChange={e => setForm({...form, participation_type: e.target.value})} /></Field><Field label="Responsible lawyer"><UserSelect value={form.responsible_lawyer_id} users={team} onChange={(value: string) => setForm({...form, responsible_lawyer_id: value})} /></Field><div className="sm:col-span-2"><Field label="Remarks"><textarea className="ti-form-input" rows={3} value={form.remarks} onChange={e => setForm({...form, remarks: e.target.value})} /></Field></div></> : null}
            {mode === 'appearance_status' ? <><Field label="New appearance status"><select required className="ti-form-input" value={form.status} onChange={e => setForm({...form, status: e.target.value})}>{(appearanceTransitions[editing.appearance_status] ?? []).map(v => <option key={v}>{v}</option>)}</select></Field><div className="sm:col-span-2"><Field label="Remarks"><textarea className="ti-form-input" rows={3} value={form.remarks} onChange={e => setForm({...form, remarks: e.target.value})} /></Field></div></> : null}
            {mode === 'examination' ? <><Field label="Hearing"><ProceedingSelect value={form.litigation_proceeding_id} proceedings={proceedings} onChange={(value: string) => setForm({...form, litigation_proceeding_id: value})} /></Field><Field label="Examination type"><select required className="ti-form-input" value={form.examination_type} onChange={e => setForm({...form, examination_type: e.target.value})}>{examinationTypes.map(v => <option key={v}>{v}</option>)}</select></Field><Field label="Examination date"><input required type="datetime-local" className="ti-form-input" value={form.examination_date} onChange={e => setForm({...form, examination_date: e.target.value})} /></Field><Field label="Examining lawyer"><UserSelect value={form.examining_lawyer_id} users={team} onChange={(value: string) => setForm({...form, examining_lawyer_id: value})} /></Field><div className="sm:col-span-2"><Field label="Summary"><textarea required className="ti-form-input" rows={4} value={form.summary} onChange={e => setForm({...form, summary: e.target.value})} /></Field></div><div className="sm:col-span-2"><Field label="Observations"><textarea className="ti-form-input" rows={3} value={form.observations} onChange={e => setForm({...form, observations: e.target.value})} /></Field></div><Checklist label="Referenced evidence" items={evidence} selected={form.evidence_ids} setSelected={(ids: number[]) => setForm({...form, evidence_ids: ids})} render={(item: any) => `${item.reference_number} · ${item.title}`} /><Checklist label="Referenced exhibits" items={exhibitOptions} selected={form.exhibit_ids} setSelected={(ids: number[]) => setForm({...form, exhibit_ids: ids})} render={(item: any) => `${item.reference_number} · ${label(item.status)}`} /><Checklist label="Supporting documents" items={documents} selected={form.document_ids} setSelected={(ids: number[]) => setForm({...form, document_ids: ids})} render={(item: any) => item.title} /></> : null}
        </form>
    </Modal>;
}

function StatusModal({title, current, statuses, field, endpoint, token, onClose, onSaved}: any): JSX.Element {
    const [status, setStatus] = useState(statuses[0] ?? current); const [remarks, setRemarks] = useState(''); const [submitting, setSubmitting] = useState(false);
    async function submit(event: FormEvent) { event.preventDefault(); setSubmitting(true); try { const response = await patch(endpoint, {[field]: status, remarks: remarks || null}, token); notify.toastSuccessMessage('Status updated'); onSaved(response.data?.result ?? response.data); } catch (error: any) { notify.toastErrorMessage(firstError(error) || 'Unable to update status'); } finally { setSubmitting(false); } }
    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="status-form" className="ti-btn ti-btn-primary" disabled={submitting}>{submitting ? 'Saving…' : 'Update status'}</button></>}><form id="status-form" onSubmit={submit} className="space-y-4"><Field label="New status"><select required className="ti-form-input" value={status} onChange={e => setStatus(e.target.value)}>{statuses.map((value: string) => <option key={value}>{value}</option>)}</select></Field><Field label="Remarks"><textarea className="ti-form-input" rows={3} value={remarks} onChange={e => setRemarks(e.target.value)} /></Field></form></Modal>;
}

function childInitial(mode: ChildMode, item: any): any {
    if (mode === 'statement') return {statement_date: dateInput(item?.statement_date), statement_type: item?.statement_type ?? 'witness_statement', summary: item?.summary ?? '', responsible_lawyer_id: item?.responsible_lawyer_id ?? '', document_id: item?.document_id ?? '', remarks: item?.remarks ?? '', evidence_ids: (item?.evidence_records ?? []).map((e: any) => e.id)};
    if (mode === 'availability') return {availability_type: item?.availability_type ?? 'available', starts_at: dateTimeInput(item?.starts_at), ends_at: dateTimeInput(item?.ends_at), remarks: item?.remarks ?? ''};
    if (mode === 'appearance') return {litigation_proceeding_id: item?.litigation_proceeding_id ?? '', expected_appearance_at: dateTimeInput(item?.expected_appearance_at), participation_type: item?.participation_type ?? '', responsible_lawyer_id: item?.responsible_lawyer_id ?? '', remarks: item?.remarks ?? ''};
    if (mode === 'examination') return {litigation_proceeding_id: item?.litigation_proceeding_id ?? '', examination_type: item?.examination_type ?? 'examination_in_chief', examination_date: dateTimeInput(item?.examination_date), examining_lawyer_id: item?.examining_lawyer_id ?? '', summary: item?.summary ?? '', observations: item?.observations ?? '', evidence_ids: (item?.evidence_records ?? []).map((e: any) => e.id), exhibit_ids: (item?.exhibits ?? []).map((e: any) => e.id), document_ids: (item?.documents ?? []).map((d: any) => d.id)};
    const statuses = mode === 'statement_status' ? statementTransitions[item?.review_status] ?? [] : appearanceTransitions[item?.appearance_status] ?? [];
    return {status: statuses[0] ?? '', remarks: ''};
}
function normalizeChild(mode: ChildMode, form: any): any { const data = {...form}; for (const key of ['responsible_lawyer_id', 'document_id', 'litigation_proceeding_id', 'examining_lawyer_id']) if (key in data) data[key] = numberOrNull(data[key]); return data; }
function Checklist({label: title, items, selected, setSelected, render}: any): JSX.Element { const toggle = (id: number, checked: boolean) => setSelected(checked ? [...selected, id] : selected.filter((value: number) => value !== id)); return <fieldset className="sm:col-span-2 rounded-lg border p-3"><legend className="px-1 text-sm font-medium">{title}</legend><div className="grid grid-cols-1 gap-2 sm:grid-cols-2">{items.length ? items.map((item: any) => <label key={item.id} className="flex items-start gap-2 text-sm"><input type="checkbox" className="mt-1" checked={selected.includes(item.id)} onChange={e => toggle(item.id, e.target.checked)} /><span>{render(item)}</span></label>) : <span className="text-sm text-gray-500">No records available.</span>}</div></fieldset>; }
function ProceedingSelect({value, proceedings, onChange}: any): JSX.Element { return <select required className="ti-form-input" value={value} onChange={e => onChange(e.target.value)}><option value="">Select hearing</option>{proceedings.map((item: any) => <option key={item.id} value={item.id}>{item.calendar_event?.title ?? label(item.hearing_type)} · {dateTime(item.calendar_event?.starts_at)}</option>)}</select>; }
function UserSelect({value, users, onChange}: any): JSX.Element { return <select className="ti-form-input" value={value} onChange={e => onChange(e.target.value)}><option value="">Not assigned</option>{users.map((user: any) => <option key={user.id} value={user.id}>{user.name}</option>)}</select>; }
function DocumentSelect({value, documents, onChange}: any): JSX.Element { return <select className="ti-form-input" value={value} onChange={e => onChange(e.target.value)}><option value="">No document selected</option>{documents.map((item: any) => <option key={item.id} value={item.id}>{item.title}</option>)}</select>; }
function RelatedEvidence({items}: {items: any[]}): JSX.Element { return <div className="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.reference_number}</strong> · {item.title}{item.exhibit ? <div className="text-xs text-gray-500">Exhibit {item.exhibit.reference_number} · {label(item.exhibit.status)}</div> : null}</div>) : <Empty text="No witness-related evidence." />}</div>; }
function SectionHeader({title, canAdd, onAdd}: any): JSX.Element { return <div className="mb-3 flex items-center justify-between"><h5 className="font-semibold">{title}</h5>{canAdd ? <button type="button" className="ti-btn ti-btn-primary" onClick={onAdd}><i className="fa fa-plus me-2" />Add record</button> : null}</div>; }
function IconButton({title, icon, color = 'text-gray-500 hover:bg-gray-100', onClick}: any): JSX.Element { return <button type="button" className={`inline-flex h-8 w-8 items-center justify-center rounded-md ${color}`} title={title} aria-label={title} onClick={event => { event.stopPropagation(); onClick(); }}><i className={`fa ${icon}`} /></button>; }
function Table({headers, rows, empty}: {headers: string[]; rows: React.ReactNode[][]; empty: string}): JSX.Element { return <div className="overflow-auto"><table className="ti-custom-table ti-custom-table-head whitespace-nowrap w-full"><thead className="bg-gray-100 dark:bg-bodybg"><tr>{headers.map(header => <th key={header} className={header === 'Actions' ? '!text-end' : ''}>{header}</th>)}</tr></thead><tbody>{rows.length ? rows.map((row, index) => <tr key={index}>{row.map((cell, cellIndex) => <td key={cellIndex} className={headers[cellIndex] === 'Actions' ? 'text-end' : ''}>{cell}</td>)}</tr>) : <tr><td colSpan={headers.length} className="py-8 text-center text-gray-500">{empty}</td></tr>}</tbody></table></div>; }
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, statusKey}: any): JSX.Element { return <div className="mt-4 space-y-2">{items.length ? items.map((item: any) => <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[statusKey])}</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 Field({label: title, children}: {label: string; children: React.ReactNode}): JSX.Element { return <label className="block"><span className="ti-form-label">{title}</span>{children}</label>; }
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 = ['rejected', 'withdrawn', 'did_not_appear', 'cancelled'].includes(value); const success = ['available', 'completed', 'approved', 'appeared', 'finalized'].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 numberOrNull(value: any): number | null { return value === '' || value === null || value === undefined ? null : Number(value); }
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}`} : {}}); }
