import { router } from '@inertiajs/react';
import { AlertTriangle, ShieldCheck } from 'lucide-react';
import { useEffect, useRef, useState } from 'react';
import { StatusBadge } from '@/components/status-badge';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Spinner } from '@/components/ui/spinner';
import { decide, search } from '@/routes/conflict-check';

export type ConflictMatch = {
    source: string;
    type: string;
    name: string;
    role: string | null;
    matter: string | null;
};

/**
 * Inline conflict-of-interest check (M02). Live-searches as the user types a
 * name and surfaces matches across clients, matter parties and opposing counsel.
 * It never blocks — a human records the decision, which is logged with them.
 */
export function ConflictCheckWidget({
    name,
    matterId,
}: {
    name: string;
    matterId?: number | null;
}) {
    const [matches, setMatches] = useState<ConflictMatch[]>([]);
    const [loading, setLoading] = useState(false);
    const [checked, setChecked] = useState(false);
    const timer = useRef<ReturnType<typeof setTimeout> | null>(null);

    useEffect(() => {
        const term = name.trim();

        if (timer.current) {
            clearTimeout(timer.current);
        }

        if (term.length < 2) {
            // Reset asynchronously so we never setState synchronously in render.
            timer.current = setTimeout(() => {
                setMatches([]);
                setChecked(false);
            }, 0);

            return () => {
                if (timer.current) {
                    clearTimeout(timer.current);
                }
            };
        }

        timer.current = setTimeout(() => {
            setLoading(true);
            const url = search({
                query: { name: term, exclude_matter: matterId ?? undefined },
            }).url;

            fetch(url, { headers: { Accept: 'application/json' } })
                .then((r) => r.json())
                .then((json) => {
                    setMatches(json.data?.matches ?? []);
                    setChecked(true);
                })
                .finally(() => setLoading(false));
        }, 350);

        return () => {
            if (timer.current) {
                clearTimeout(timer.current);
            }
        };
    }, [name, matterId]);

    const record = (decision: 'proceed' | 'declined' | 'escalated') => {
        router.post(
            decide().url,
            {
                searched_name: name.trim(),
                matter_id: matterId ?? null,
                result_count: matches.length,
                decision,
            },
            { preserveScroll: true, preserveState: true },
        );
    };

    const clear = matches.length === 0;

    return (
        <Card>
            <CardHeader>
                <CardTitle className="flex items-center gap-2 text-base">
                    {clear ? (
                        <ShieldCheck className="size-4 text-brand-success" />
                    ) : (
                        <AlertTriangle className="size-4 text-brand-warning" />
                    )}
                    Conflict check
                </CardTitle>
            </CardHeader>
            <CardContent className="space-y-3">
                {name.trim().length < 2 ? (
                    <p className="text-sm text-muted-foreground">
                        Enter a name above to check for conflicts of interest.
                    </p>
                ) : loading ? (
                    <p className="flex items-center gap-2 text-sm text-muted-foreground">
                        <Spinner /> Checking “{name.trim()}”…
                    </p>
                ) : checked && clear ? (
                    <p className="text-sm text-brand-success">
                        No conflicting records found for “{name.trim()}”.
                    </p>
                ) : (
                    <>
                        <p className="text-sm text-brand-warning">
                            {matches.length} possible{' '}
                            {matches.length === 1 ? 'match' : 'matches'} —
                            review before proceeding.
                        </p>
                        <ul className="divide-y divide-border rounded-md border border-border">
                            {matches.map((m, i) => (
                                <li
                                    key={i}
                                    className="flex items-center justify-between gap-2 px-3 py-2 text-sm"
                                >
                                    <span className="font-medium text-foreground">
                                        {m.name}
                                    </span>
                                    <span className="flex items-center gap-2 text-muted-foreground">
                                        {m.matter && <span>{m.matter}</span>}
                                        <StatusBadge tone="warning">
                                            {m.type}
                                            {m.role ? ` · ${m.role}` : ''}
                                        </StatusBadge>
                                    </span>
                                </li>
                            ))}
                        </ul>
                    </>
                )}

                {checked && (
                    <div className="flex flex-wrap gap-2 pt-1">
                        <Button
                            type="button"
                            size="sm"
                            variant="outline"
                            onClick={() => record('proceed')}
                        >
                            Log: Proceed
                        </Button>
                        <Button
                            type="button"
                            size="sm"
                            variant="outline"
                            onClick={() => record('escalated')}
                        >
                            Log: Escalate
                        </Button>
                        <Button
                            type="button"
                            size="sm"
                            variant="destructive"
                            onClick={() => record('declined')}
                        >
                            Log: Decline
                        </Button>
                    </div>
                )}
            </CardContent>
        </Card>
    );
}
