import { useForm } from '@inertiajs/react';
import { CalendarPlus, Gavel, Plus } from 'lucide-react';
import { useState } from 'react';
import { EmptyState } from '@/components/empty-state';
import { StatusBadge  } from '@/components/status-badge';
import type {StatusTone} from '@/components/status-badge';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import {
    Dialog,
    DialogContent,
    DialogFooter,
    DialogHeader,
    DialogTitle,
    DialogTrigger,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';
import { Textarea } from '@/components/ui/textarea';
import { store as hearingStore, outcome as recordOutcome } from '@/routes/hearings';
import { store as testimonyStore } from '@/routes/testimonies';
import { store as witnessStore } from '@/routes/witnesses';

type Option = { value: number | string; label: string };

export type Hearing = {
    id: string;
    hearing_date: string;
    hearing_time: string | null;
    type_label: string;
    purpose: string | null;
    court: string | null;
    status: string;
    status_label: string;
    status_tone: StatusTone;
    outcome: string | null;
    proceedings: string | null;
};

export type Witness = {
    id: number;
    name: string;
    side: string | null;
    phone: string | null;
    status: string;
    status_label: string;
    testimonies: { id: number; testified_on: string; testimony: string; cross_examination: string | null }[];
};

type Options = {
    courts: Option[];
    hearingTypes: Option[];
    hearingOutcomes: Option[];
};

function ScheduleHearing({ matterId, options }: { matterId: string; options: Options }) {
    const [open, setOpen] = useState(false);
    const form = useForm({ hearing_date: '', hearing_time: '', type: 'mention', court_id: '' as string, purpose: '' });

    const submit = (e: React.FormEvent) => {
        e.preventDefault();
        form.transform((d) => ({ ...d, court_id: d.court_id || null }));
        form.post(hearingStore(matterId).url, {
            preserveScroll: true,
            onSuccess: () => {
                form.reset();
                setOpen(false);
            },
        });
    };

    return (
        <Dialog open={open} onOpenChange={setOpen}>
            <DialogTrigger asChild>
                <Button size="sm">
                    <CalendarPlus /> Schedule hearing
                </Button>
            </DialogTrigger>
            <DialogContent>
                <DialogHeader>
                    <DialogTitle>Schedule a hearing</DialogTitle>
                </DialogHeader>
                <form onSubmit={submit} className="grid gap-4">
                    <div className="grid gap-2 sm:grid-cols-2">
                        <div className="grid gap-2">
                            <Label htmlFor="hearing_date">Date</Label>
                            <Input id="hearing_date" type="date" value={form.data.hearing_date} onChange={(e) => form.setData('hearing_date', e.target.value)} required />
                        </div>
                        <div className="grid gap-2">
                            <Label htmlFor="hearing_time">Time (optional)</Label>
                            <Input id="hearing_time" type="time" value={form.data.hearing_time} onChange={(e) => form.setData('hearing_time', e.target.value)} />
                        </div>
                    </div>
                    <div className="grid gap-2 sm:grid-cols-2">
                        <div className="grid gap-2">
                            <Label htmlFor="type">Type</Label>
                            <Select value={form.data.type} onValueChange={(v) => form.setData('type', v)}>
                                <SelectTrigger id="type"><SelectValue /></SelectTrigger>
                                <SelectContent>
                                    {options.hearingTypes.map((o) => (
                                        <SelectItem key={o.value} value={String(o.value)}>{o.label}</SelectItem>
                                    ))}
                                </SelectContent>
                            </Select>
                        </div>
                        <div className="grid gap-2">
                            <Label htmlFor="court_id">Court (optional)</Label>
                            <Select value={form.data.court_id || 'none'} onValueChange={(v) => form.setData('court_id', v === 'none' ? '' : v)}>
                                <SelectTrigger id="court_id"><SelectValue placeholder="None" /></SelectTrigger>
                                <SelectContent>
                                    <SelectItem value="none">None</SelectItem>
                                    {options.courts.map((o) => (
                                        <SelectItem key={o.value} value={String(o.value)}>{o.label}</SelectItem>
                                    ))}
                                </SelectContent>
                            </Select>
                        </div>
                    </div>
                    <div className="grid gap-2">
                        <Label htmlFor="purpose">Purpose (optional)</Label>
                        <Input id="purpose" value={form.data.purpose} onChange={(e) => form.setData('purpose', e.target.value)} />
                    </div>
                    <DialogFooter>
                        <Button type="submit" disabled={form.processing}>Schedule</Button>
                    </DialogFooter>
                </form>
            </DialogContent>
        </Dialog>
    );
}

function RecordOutcome({ hearing, options }: { hearing: Hearing; options: Options }) {
    const [open, setOpen] = useState(false);
    const form = useForm({ outcome: 'held', proceedings: '', remarks: '', next_adjourned_date: '', next_purpose: '' });

    const submit = (e: React.FormEvent) => {
        e.preventDefault();
        form.post(recordOutcome(hearing.id).url, {
            preserveScroll: true,
            onSuccess: () => setOpen(false),
        });
    };

    return (
        <Dialog open={open} onOpenChange={setOpen}>
            <DialogTrigger asChild>
                <Button size="xs" variant="secondary">Record outcome</Button>
            </DialogTrigger>
            <DialogContent>
                <DialogHeader>
                    <DialogTitle>Record hearing outcome</DialogTitle>
                </DialogHeader>
                <form onSubmit={submit} className="grid gap-4">
                    <div className="grid gap-2">
                        <Label htmlFor="outcome">Outcome</Label>
                        <Select value={form.data.outcome} onValueChange={(v) => form.setData('outcome', v)}>
                            <SelectTrigger id="outcome"><SelectValue /></SelectTrigger>
                            <SelectContent>
                                {options.hearingOutcomes.map((o) => (
                                    <SelectItem key={o.value} value={String(o.value)}>{o.label}</SelectItem>
                                ))}
                            </SelectContent>
                        </Select>
                    </div>
                    <div className="grid gap-2">
                        <Label htmlFor="proceedings">Proceedings</Label>
                        <Textarea id="proceedings" value={form.data.proceedings} onChange={(e) => form.setData('proceedings', e.target.value)} />
                    </div>
                    <div className="grid gap-2">
                        <Label htmlFor="remarks">Private remarks (never shown to clients)</Label>
                        <Textarea id="remarks" value={form.data.remarks} onChange={(e) => form.setData('remarks', e.target.value)} />
                    </div>
                    <div className="grid gap-2 sm:grid-cols-2">
                        <div className="grid gap-2">
                            <Label htmlFor="next_adjourned_date">Next date (if adjourned)</Label>
                            <Input id="next_adjourned_date" type="date" value={form.data.next_adjourned_date} onChange={(e) => form.setData('next_adjourned_date', e.target.value)} />
                            {form.errors.next_adjourned_date && (
                                <p className="text-xs text-destructive">{form.errors.next_adjourned_date}</p>
                            )}
                        </div>
                        <div className="grid gap-2">
                            <Label htmlFor="next_purpose">Next purpose</Label>
                            <Input id="next_purpose" value={form.data.next_purpose} onChange={(e) => form.setData('next_purpose', e.target.value)} />
                        </div>
                    </div>
                    <DialogFooter>
                        <Button type="submit" disabled={form.processing}>Record outcome</Button>
                    </DialogFooter>
                </form>
            </DialogContent>
        </Dialog>
    );
}

function Witnesses({ matterId, witnesses, canManage }: { matterId: string; witnesses: Witness[]; canManage: boolean }) {
    const witnessForm = useForm({ name: '', side: 'plaintiff' });

    const addWitness = (e: React.FormEvent) => {
        e.preventDefault();
        witnessForm.post(witnessStore(matterId).url, { preserveScroll: true, onSuccess: () => witnessForm.reset() });
    };

    return (
        <Card>
            <CardHeader>
                <CardTitle>Witnesses</CardTitle>
            </CardHeader>
            <CardContent className="space-y-4">
                {witnesses.length === 0 && <p className="text-sm text-muted-foreground">No witnesses recorded.</p>}
                {witnesses.map((w) => (
                    <div key={w.id} className="rounded-lg border border-border p-3">
                        <div className="flex items-center justify-between">
                            <div>
                                <span className="font-medium text-foreground">{w.name}</span>
                                {w.side && <span className="ml-2 text-xs text-muted-foreground">({w.side})</span>}
                            </div>
                            <StatusBadge tone={w.status === 'testified' ? 'success' : 'neutral'}>{w.status_label}</StatusBadge>
                        </div>
                        {w.testimonies.map((t) => (
                            <div key={t.id} className="mt-2 border-l-2 border-border pl-3 text-sm">
                                <p className="text-xs text-muted-foreground">{t.testified_on}</p>
                                <p className="text-foreground">{t.testimony}</p>
                            </div>
                        ))}
                        {canManage && <RecordTestimony witnessId={w.id} />}
                    </div>
                ))}
                {canManage && (
                    <form onSubmit={addWitness} className="flex flex-wrap items-end gap-2 border-t border-border pt-4">
                        <div className="grid flex-1 gap-2">
                            <Label>Witness name</Label>
                            <Input value={witnessForm.data.name} onChange={(e) => witnessForm.setData('name', e.target.value)} required />
                        </div>
                        <div className="grid w-40 gap-2">
                            <Label>Side</Label>
                            <Select value={witnessForm.data.side} onValueChange={(v) => witnessForm.setData('side', v)}>
                                <SelectTrigger><SelectValue /></SelectTrigger>
                                <SelectContent>
                                    <SelectItem value="plaintiff">Plaintiff</SelectItem>
                                    <SelectItem value="defence">Defence</SelectItem>
                                    <SelectItem value="court">Court</SelectItem>
                                </SelectContent>
                            </Select>
                        </div>
                        <Button type="submit"><Plus /> Add witness</Button>
                    </form>
                )}
            </CardContent>
        </Card>
    );
}

function RecordTestimony({ witnessId }: { witnessId: number }) {
    const [open, setOpen] = useState(false);
    const form = useForm({ testified_on: '', testimony: '', cross_examination: '' });

    const submit = (e: React.FormEvent) => {
        e.preventDefault();
        form.post(testimonyStore(witnessId).url, { preserveScroll: true, onSuccess: () => setOpen(false) });
    };

    return (
        <Dialog open={open} onOpenChange={setOpen}>
            <DialogTrigger asChild>
                <Button size="xs" variant="ghost" className="mt-2">Record testimony</Button>
            </DialogTrigger>
            <DialogContent>
                <DialogHeader>
                    <DialogTitle>Record testimony</DialogTitle>
                </DialogHeader>
                <form onSubmit={submit} className="grid gap-4">
                    <div className="grid gap-2">
                        <Label htmlFor="testified_on">Date</Label>
                        <Input id="testified_on" type="date" value={form.data.testified_on} onChange={(e) => form.setData('testified_on', e.target.value)} required />
                    </div>
                    <div className="grid gap-2">
                        <Label htmlFor="testimony">Testimony</Label>
                        <Textarea id="testimony" value={form.data.testimony} onChange={(e) => form.setData('testimony', e.target.value)} required />
                    </div>
                    <div className="grid gap-2">
                        <Label htmlFor="cross">Cross-examination (optional)</Label>
                        <Textarea id="cross" value={form.data.cross_examination} onChange={(e) => form.setData('cross_examination', e.target.value)} />
                    </div>
                    <DialogFooter>
                        <Button type="submit" disabled={form.processing}>Save</Button>
                    </DialogFooter>
                </form>
            </DialogContent>
        </Dialog>
    );
}

export function MatterHearingsTab({
    matterId,
    hearings,
    witnesses,
    options,
    can,
}: {
    matterId: string;
    hearings: Hearing[];
    witnesses: Witness[];
    options: Options;
    can: { manageHearings: boolean; recordOutcome: boolean };
}) {
    return (
        <div className="flex flex-col gap-6">
            <Card>
                <CardHeader className="flex flex-row items-center justify-between">
                    <CardTitle>Hearings</CardTitle>
                    {can.manageHearings && <ScheduleHearing matterId={matterId} options={options} />}
                </CardHeader>
                <CardContent className="space-y-3">
                    {hearings.length === 0 ? (
                        <EmptyState icon={Gavel} title="No hearings scheduled" description="Schedule the first court date for this matter." />
                    ) : (
                        hearings.map((h) => (
                            <div key={h.id} className="flex flex-wrap items-start justify-between gap-3 rounded-lg border border-border p-3">
                                <div>
                                    <div className="flex items-center gap-2">
                                        <span className="font-medium text-foreground">{h.hearing_date}</span>
                                        {h.hearing_time && <span className="text-sm text-muted-foreground">{h.hearing_time}</span>}
                                        <StatusBadge tone={h.status_tone}>{h.status_label}</StatusBadge>
                                    </div>
                                    <p className="text-sm text-muted-foreground">
                                        {h.type_label}
                                        {h.purpose ? ` · ${h.purpose}` : ''}
                                        {h.court ? ` · ${h.court}` : ''}
                                    </p>
                                    {h.outcome && <p className="mt-1 text-sm text-foreground">Outcome: {h.outcome}</p>}
                                </div>
                                {can.recordOutcome && h.status === 'scheduled' && (
                                    <RecordOutcome hearing={h} options={options} />
                                )}
                            </div>
                        ))
                    )}
                </CardContent>
            </Card>

            <Witnesses matterId={matterId} witnesses={witnesses} canManage={can.recordOutcome} />
        </div>
    );
}
