import { Badge } from '@/components/ui/badge';
import { Separator } from '@/components/ui/separator';
import {
    Sheet,
    SheetContent,
    SheetHeader,
    SheetTitle,
} from '@/components/ui/sheet';
import { Skeleton } from '@/components/ui/skeleton';
import { api } from '@/lib/api';
import { parseServerDate } from '@/lib/date';
import { cn } from '@/lib/utils';
import { Link } from '@inertiajs/react';
import { useQuery } from '@tanstack/react-query';
import { format, formatDistanceToNow } from 'date-fns';
import {
    ArrowRight,
    ExternalLink,
    Globe,
    Layers,
    Tag,
    Terminal,
    User,
} from 'lucide-react';
import { useEffect, useState } from 'react';
import NoteForm, { type Note } from './NoteForm';
import { SeverityBadge } from './SeverityBadge';
import { ReviewBadge, StatusBadge, type ReviewStatus } from './StatusBadge';

interface AuditLogDetail {
    id: string;
    scope: string;
    event: string;
    category: string;
    action: string;
    status: string;
    severity: string;
    actor_type: string;
    actor_name: string | null;
    actor_role: string | null;
    auditable_type: string | null;
    auditable_id: string | null;
    ip_address: string | null;
    user_agent: string | null;
    url: string | null;
    http_method: string | null;
    review_status: ReviewStatus;
    reviewed_at: string | null;
    reviewed_by_name: string | null;
    created_at: string;
    changes: {
        field: string;
        old_value: string | null;
        new_value: string | null;
    }[];
    tags: { key: string; value: string }[];
    notes: Note[];
}

interface Props {
    logId: string | null;
    onClose: () => void;
    onReviewUpdate: (
        id: string,
        review_status: ReviewStatus,
        reviewed_at: string | null,
        reviewed_by_name: string | null,
    ) => void;
}

function Field({
    label,
    children,
}: {
    label: string;
    children: React.ReactNode;
}) {
    return (
        <div className="space-y-0.5">
            <p className="text-muted-foreground text-[10px] font-semibold tracking-wide uppercase">
                {label}
            </p>
            <div className="text-foreground text-sm">{children}</div>
        </div>
    );
}

export default function QuickView({ logId, onClose, onReviewUpdate }: Props) {
    const [notes, setNotes] = useState<Note[]>([]);
    const [reviewState, setReviewState] = useState<{
        status: ReviewStatus;
        at: string | null;
        by: string | null;
    }>({ status: null, at: null, by: null });

    const { data: log, isLoading } = useQuery<AuditLogDetail>({
        queryKey: ['admin.audit.show', logId],
        queryFn: () => api.get(`/admin/api/audit/${logId}`),
        enabled: logId !== null,
    });

    // Reset when switching to a different log so stale data doesn't flash
    useEffect(() => {
        setNotes([]);
        setReviewState({ status: null, at: null, by: null });
    }, [logId]);

    // Sync from query result once loaded
    useEffect(() => {
        if (log) {
            setNotes(log.notes);
            setReviewState({
                status: log.review_status,
                at: log.reviewed_at,
                by: log.reviewed_by_name,
            });
        }
    }, [log]);

    const handleNoteSuccess = (result: {
        note: Note;
        review_status: ReviewStatus;
        reviewed_at: string | null;
        reviewed_by_name: string | null;
    }) => {
        setNotes((prev) => [result.note, ...prev]);
        setReviewState({
            status: result.review_status,
            at: result.reviewed_at,
            by: result.reviewed_by_name,
        });
        if (logId) {
            onReviewUpdate(
                logId,
                result.review_status,
                result.reviewed_at,
                result.reviewed_by_name,
            );
        }
    };

    const modelName = log?.auditable_type
        ? log.auditable_type.split('\\').pop()
        : null;

    return (
        <Sheet
            open={logId !== null}
            onOpenChange={(open) => !open && onClose()}
        >
            <SheetContent
                side="right"
                className="flex w-full flex-col gap-0 p-0 sm:max-w-lg"
            >
                {/* SheetTitle must always be in the DOM — Radix Dialog a11y requirement */}
                <SheetHeader className="border-border shrink-0 border-b px-6 py-4">
                    {isLoading || !log ? (
                        <div className="space-y-2">
                            <Skeleton className="h-5 w-48" />
                            <Skeleton className="h-3 w-32" />
                            {/* Visually hidden title satisfies Radix while skeleton is shown */}
                            <SheetTitle className="sr-only">
                                Loading audit log…
                            </SheetTitle>
                        </div>
                    ) : (
                        <>
                            <div className="flex items-start gap-3">
                                <SeverityBadge
                                    severity={log.severity}
                                    dot
                                    className="mt-1.5 shrink-0"
                                />
                                <div className="min-w-0 flex-1">
                                    <SheetTitle className="text-foreground font-mono text-sm font-semibold">
                                        {log.event}
                                    </SheetTitle>
                                    <p className="text-muted-foreground mt-0.5 text-[11px]">
                                        {format(
                                            parseServerDate(log.created_at),
                                            "d MMM yyyy 'at' HH:mm:ss",
                                        )}
                                        {' · '}
                                        {formatDistanceToNow(
                                            parseServerDate(log.created_at),
                                            { addSuffix: true },
                                        )}
                                    </p>
                                </div>
                            </div>
                            <div className="flex flex-wrap gap-1.5 pt-1">
                                <SeverityBadge severity={log.severity} />
                                <StatusBadge status={log.status} />
                                <ReviewBadge status={reviewState.status} />
                                <Badge
                                    variant="outline"
                                    className="font-mono text-[10px]"
                                >
                                    {log.category}
                                </Badge>
                            </div>
                        </>
                    )}
                </SheetHeader>

                {isLoading || !log ? (
                    <div className="space-y-4 p-6">
                        <Skeleton className="h-32 w-full" />
                        <Skeleton className="h-24 w-full" />
                        <Skeleton className="h-24 w-full" />
                    </div>
                ) : (
                    <>
                        {/* Scrollable body */}
                        <div className="admin-scrollbar flex-1 space-y-5 overflow-y-auto p-6">
                            {/* Actor */}
                            <div className="border-border bg-muted/30 space-y-3 rounded-lg border p-4">
                                <div className="text-muted-foreground flex items-center gap-2 text-xs font-semibold tracking-wide uppercase">
                                    <User className="h-3.5 w-3.5" />
                                    Actor
                                </div>
                                <div className="grid grid-cols-2 gap-3">
                                    <Field label="Name">
                                        {log.actor_name ?? '—'}
                                    </Field>
                                    <Field label="Type">
                                        <span className="font-mono">
                                            {log.actor_type}
                                        </span>
                                    </Field>
                                    <Field label="Role">
                                        {log.actor_role ?? '—'}
                                    </Field>
                                    <Field label="IP Address">
                                        <span className="font-mono">
                                            {log.ip_address ?? '—'}
                                        </span>
                                    </Field>
                                </div>
                            </div>

                            {/* Request context */}
                            {(log.url || log.http_method) && (
                                <div className="border-border bg-muted/30 space-y-3 rounded-lg border p-4">
                                    <div className="text-muted-foreground flex items-center gap-2 text-xs font-semibold tracking-wide uppercase">
                                        <Globe className="h-3.5 w-3.5" />
                                        Request
                                    </div>
                                    {log.http_method && log.url && (
                                        <div className="flex items-start gap-2">
                                            <span className="bg-primary/10 text-primary shrink-0 rounded px-1.5 py-0.5 font-mono text-[10px] font-bold">
                                                {log.http_method}
                                            </span>
                                            <span className="text-foreground/80 font-mono text-xs break-all">
                                                {log.url}
                                            </span>
                                        </div>
                                    )}
                                    {log.user_agent && (
                                        <Field label="User Agent">
                                            <span className="text-muted-foreground line-clamp-2 text-[11px]">
                                                {log.user_agent}
                                            </span>
                                        </Field>
                                    )}
                                </div>
                            )}

                            {/* Affected record */}
                            {modelName && (
                                <div className="border-border bg-muted/30 space-y-1 rounded-lg border p-4">
                                    <div className="text-muted-foreground flex items-center gap-2 text-xs font-semibold tracking-wide uppercase">
                                        <Layers className="h-3.5 w-3.5" />
                                        Affected Record
                                    </div>
                                    <p className="font-mono text-sm">
                                        {modelName}{' '}
                                        <span className="text-muted-foreground">
                                            #{log.auditable_id}
                                        </span>
                                    </p>
                                </div>
                            )}

                            {/* Field changes */}
                            {log.changes.length > 0 && (
                                <div className="space-y-2">
                                    <div className="text-muted-foreground flex items-center gap-2 text-xs font-semibold tracking-wide uppercase">
                                        <Terminal className="h-3.5 w-3.5" />
                                        Changes ({log.changes.length})
                                    </div>
                                    <div className="border-border overflow-hidden rounded-lg border">
                                        {log.changes.map((c, i) => (
                                            <div
                                                key={i}
                                                className={cn(
                                                    'grid grid-cols-[1fr_auto_1fr] items-start gap-2 px-3 py-2 text-xs',
                                                    i > 0 &&
                                                        'border-border border-t',
                                                )}
                                            >
                                                <div className="min-w-0">
                                                    <p className="text-muted-foreground mb-0.5 font-mono text-[10px]">
                                                        {c.field}
                                                    </p>
                                                    <p className="truncate rounded bg-red-500/10 px-1.5 py-0.5 font-mono text-red-700 dark:text-red-400">
                                                        {c.old_value ?? (
                                                            <span className="text-muted-foreground italic">
                                                                empty
                                                            </span>
                                                        )}
                                                    </p>
                                                </div>
                                                <ArrowRight className="text-muted-foreground dark:text-muted-foreground/60 mt-5 h-3 w-3 shrink-0" />
                                                <div className="min-w-0">
                                                    <p className="text-muted-foreground mb-0.5 font-mono text-[10px] opacity-0">
                                                        x
                                                    </p>
                                                    <p className="truncate rounded bg-green-500/10 px-1.5 py-0.5 font-mono text-green-700 dark:text-green-400">
                                                        {c.new_value ?? (
                                                            <span className="text-muted-foreground italic">
                                                                empty
                                                            </span>
                                                        )}
                                                    </p>
                                                </div>
                                            </div>
                                        ))}
                                    </div>
                                </div>
                            )}

                            {/* Tags */}
                            {log.tags.length > 0 && (
                                <div className="space-y-2">
                                    <div className="text-muted-foreground flex items-center gap-2 text-xs font-semibold tracking-wide uppercase">
                                        <Tag className="h-3.5 w-3.5" />
                                        Tags
                                    </div>
                                    <div className="flex flex-wrap gap-1.5">
                                        {log.tags.map((t, i) => (
                                            <span
                                                key={i}
                                                className="border-border bg-muted/50 rounded-full border px-2 py-0.5 font-mono text-[11px]"
                                            >
                                                <span className="text-muted-foreground">
                                                    {t.key}=
                                                </span>
                                                {t.value}
                                            </span>
                                        ))}
                                    </div>
                                </div>
                            )}

                            <Separator />

                            {/* Investigation notes */}
                            <div className="space-y-3">
                                <p className="text-muted-foreground text-xs font-semibold tracking-wide uppercase">
                                    Respond
                                </p>
                                <NoteForm
                                    logId={log.id}
                                    onSuccess={handleNoteSuccess}
                                    compact
                                />
                            </div>

                            {/* Existing notes */}
                            {notes.length > 0 && (
                                <div className="space-y-2">
                                    <p className="text-muted-foreground text-xs font-semibold tracking-wide uppercase">
                                        History ({notes.length})
                                    </p>
                                    {notes.slice(0, 5).map((note) => (
                                        <NoteCard key={note.id} note={note} />
                                    ))}
                                    {notes.length > 5 && (
                                        <p className="text-muted-foreground text-center text-[11px]">
                                            +{notes.length - 5} more on the full
                                            page
                                        </p>
                                    )}
                                </div>
                            )}
                        </div>

                        {/* Footer */}
                        <div className="border-border shrink-0 border-t px-6 py-3">
                            <Link
                                href={`/admin/audit/${log.id}`}
                                className="border-border text-muted-foreground hover:bg-muted/50 hover:text-foreground flex w-full items-center justify-center gap-2 rounded-lg border py-2 text-xs font-medium transition-colors"
                            >
                                <ExternalLink className="h-3.5 w-3.5" />
                                View full details
                            </Link>
                        </div>
                    </>
                )}
            </SheetContent>
        </Sheet>
    );
}

function NoteCard({ note }: { note: Note }) {
    const NOTE_COLORS: Record<string, string> = {
        note: 'bg-muted/50 border-border',
        reviewed: 'bg-green-500/5 border-green-500/20',
        escalated: 'bg-red-500/5 border-red-500/20',
        resolved: 'bg-blue-500/5 border-blue-500/20',
        false_positive: 'bg-muted/30 border-border',
    };
    const NOTE_LABELS: Record<string, string> = {
        note: 'Note',
        reviewed: 'Marked Reviewed',
        escalated: 'Escalated',
        resolved: 'Resolved',
        false_positive: 'False Positive',
    };

    return (
        <div
            className={cn(
                'space-y-1.5 rounded-lg border p-3',
                NOTE_COLORS[note.type] ?? 'bg-muted/50 border-border',
            )}
        >
            <div className="flex items-center justify-between gap-2">
                <span className="text-foreground text-xs font-semibold">
                    {note.admin_name}
                </span>
                <span className="text-muted-foreground text-[10px] font-medium">
                    {NOTE_LABELS[note.type]} ·{' '}
                    {formatDistanceToNow(parseServerDate(note.created_at), {
                        addSuffix: true,
                    })}
                </span>
            </div>
            {note.body && (
                <p className="text-foreground/80 text-xs">{note.body}</p>
            )}
        </div>
    );
}
