import { TaskStatus, type TaskPhase, type TaskResult } from '@/types';
import {
    Sheet,
    SheetContent,
    SheetHeader,
    SheetTitle,
    SheetDescription,
    SheetFooter,
} from './ui/sheet';
import { Button } from './ui/button';
import { CheckCircle2, Circle, Loader2, XCircle } from 'lucide-react';
import { useEffect, useRef } from 'react';

interface TaskProgressDrawerProps {
    open: boolean;
    onOpenChange: (open: boolean) => void;
    taskResult: TaskResult | null;
    taskStatus: TaskStatus | null;
    taskID: string | null;
    onCancel: () => void;
    isCancelling: boolean;
}

const PHASES: { key: TaskPhase; label: string }[] = [
    { key: 'splitting', label: 'Splitting queries' },
    { key: 'fetching', label: 'Fetching listings' },
    { key: 'filtering', label: 'Filtering results' },
    { key: 'processing', label: 'Processing listings' },
];

function getPhaseIndex(phase: TaskPhase | undefined): number {
    if (!phase) return -1;
    if (phase === 'splitting_complete') return 1; // splitting done, fetching is next
    if (phase === 'completed') return PHASES.length;
    return PHASES.findIndex((p) => p.key === phase);
}

function formatEta(seconds: number | undefined): string {
    if (seconds === undefined || seconds <= 0) return '';
    const mins = Math.floor(seconds / 60);
    const secs = Math.round(seconds % 60);
    if (mins > 0) {
        return `~${mins}m ${secs}s remaining`;
    }
    return `~${secs}s remaining`;
}

function StatusBadge({ status }: { status: TaskStatus | null }) {
    if (!status) return null;

    const isInProgress =
        status !== TaskStatus.SUCCESS &&
        status !== TaskStatus.FAILURE &&
        status !== TaskStatus.REVOKED;

    if (isInProgress) {
        return (
            <span className="inline-flex items-center gap-1 rounded-full bg-blue-100 px-2 py-0.5 text-xs font-medium text-blue-700">
                <Loader2 className="h-3 w-3 animate-spin" />
                Running
            </span>
        );
    }
    if (status === TaskStatus.SUCCESS) {
        return (
            <span className="inline-flex items-center gap-1 rounded-full bg-green-100 px-2 py-0.5 text-xs font-medium text-green-700">
                <CheckCircle2 className="h-3 w-3" />
                Complete
            </span>
        );
    }
    if (status === TaskStatus.REVOKED) {
        return (
            <span className="inline-flex items-center gap-1 rounded-full bg-yellow-100 px-2 py-0.5 text-xs font-medium text-yellow-700">
                <XCircle className="h-3 w-3" />
                Cancelled
            </span>
        );
    }
    return (
        <span className="inline-flex items-center gap-1 rounded-full bg-red-100 px-2 py-0.5 text-xs font-medium text-red-700">
            <XCircle className="h-3 w-3" />
            Failed
        </span>
    );
}

function PhaseTimeline({
    currentPhase,
    taskStatus,
}: {
    currentPhase: TaskPhase | undefined;
    taskStatus: TaskStatus | null;
}) {
    const isTerminal =
        taskStatus === TaskStatus.SUCCESS ||
        taskStatus === TaskStatus.FAILURE ||
        taskStatus === TaskStatus.REVOKED;
    const activeIdx = isTerminal ? PHASES.length : getPhaseIndex(currentPhase);

    return (
        <div className="flex flex-col gap-1">
            {PHASES.map((phase, idx) => {
                const isCompleted = idx < activeIdx;
                const isActive = idx === activeIdx && !isTerminal;
                const isFuture = idx > activeIdx;

                return (
                    <div key={phase.key} className="flex items-center gap-2">
                        {isCompleted && (
                            <CheckCircle2 className="h-4 w-4 text-green-500 shrink-0" />
                        )}
                        {isActive && (
                            <Loader2 className="h-4 w-4 animate-spin text-blue-500 shrink-0" />
                        )}
                        {isFuture && (
                            <Circle className="h-4 w-4 text-muted-foreground/40 shrink-0" />
                        )}
                        <span
                            className={
                                isActive
                                    ? 'text-sm font-medium text-foreground'
                                    : isCompleted
                                      ? 'text-sm text-muted-foreground'
                                      : 'text-sm text-muted-foreground/40'
                            }
                        >
                            {phase.label}
                        </span>
                    </div>
                );
            })}
        </div>
    );
}

function CounterRow({ label, value, total }: { label: string; value?: number; total?: number }) {
    if (value === undefined) return null;
    return (
        <div className="flex justify-between text-sm">
            <span className="text-muted-foreground">{label}</span>
            <span className="font-mono tabular-nums">
                {value}
                {total !== undefined && ` / ${total}`}
            </span>
        </div>
    );
}

function PhaseDetails({ result }: { result: TaskResult }) {
    const phase = result.phase;

    if (phase === 'splitting' || phase === 'splitting_complete') {
        return (
            <div className="rounded-md border p-3 space-y-1">
                <p className="text-xs font-medium text-muted-foreground uppercase tracking-wide mb-2">
                    Splitting
                </p>
                <CounterRow
                    label="Subqueries probed"
                    value={result.subqueries_probed}
                    total={result.subqueries_initial}
                />
                {result.subqueries_total !== undefined && (
                    <CounterRow label="Final subqueries" value={result.subqueries_total} />
                )}
                {result.estimated_results !== undefined && (
                    <CounterRow label="Estimated results" value={result.estimated_results} />
                )}
            </div>
        );
    }

    if (phase === 'fetching') {
        return (
            <div className="rounded-md border p-3 space-y-1">
                <p className="text-xs font-medium text-muted-foreground uppercase tracking-wide mb-2">
                    Fetching
                </p>
                <CounterRow
                    label="Subqueries completed"
                    value={result.subqueries_completed}
                    total={result.subqueries_total}
                />
                <CounterRow label="IDs collected" value={result.ids_collected} />
                <CounterRow label="Pages fetched" value={result.pages_fetched} />
            </div>
        );
    }

    if (phase === 'filtering') {
        return (
            <div className="rounded-md border p-3 space-y-1">
                <p className="text-xs font-medium text-muted-foreground uppercase tracking-wide mb-2">
                    Filtering
                </p>
                <CounterRow label="Total from API" value={result.total_found} />
                <CounterRow label="Already in DB" value={result.existing_in_db} />
                <CounterRow label="New to process" value={result.new_listings} />
            </div>
        );
    }

    if (phase === 'processing') {
        return (
            <div className="rounded-md border p-3 space-y-1">
                <p className="text-xs font-medium text-muted-foreground uppercase tracking-wide mb-2">
                    Processing
                </p>
                <CounterRow
                    label="Details fetched"
                    value={result.details_fetched}
                    total={result.total}
                />
                <CounterRow label="Images downloaded" value={result.images_downloaded} />
                <CounterRow label="OCR completed" value={result.ocr_completed} />
                {(result.failed ?? 0) > 0 && (
                    <div className="flex justify-between text-sm">
                        <span className="text-red-500">Failed</span>
                        <span className="font-mono tabular-nums text-red-500">{result.failed}</span>
                    </div>
                )}
            </div>
        );
    }

    return null;
}

function LogViewer({ logs }: { logs: string[] }) {
    const scrollRef = useRef<HTMLDivElement>(null);
    const isAutoScrolling = useRef(true);

    const handleScroll = () => {
        const el = scrollRef.current;
        if (!el) return;
        const atBottom = el.scrollHeight - el.scrollTop - el.clientHeight < 30;
        isAutoScrolling.current = atBottom;
    };

    useEffect(() => {
        if (isAutoScrolling.current && scrollRef.current) {
            scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
        }
    }, [logs]);

    return (
        <div
            ref={scrollRef}
            onScroll={handleScroll}
            className="rounded-md bg-zinc-950 p-3 overflow-y-auto font-mono text-[11px] leading-4 text-zinc-300 min-h-[100px] h-full"
        >
            {logs.length === 0 ? (
                <span className="text-zinc-500 italic">Waiting for logs...</span>
            ) : (
                logs.map((line, i) => (
                    <div key={i} className="whitespace-pre-wrap break-all">
                        {line}
                    </div>
                ))
            )}
        </div>
    );
}

export function TaskProgressDrawer({
    open,
    onOpenChange,
    taskResult,
    taskStatus,
    taskID,
    onCancel,
    isCancelling,
}: TaskProgressDrawerProps) {
    const isInProgress =
        taskStatus !== null &&
        taskStatus !== TaskStatus.SUCCESS &&
        taskStatus !== TaskStatus.FAILURE &&
        taskStatus !== TaskStatus.REVOKED;

    const progressPercent = taskResult
        ? Math.min((taskResult.progress ?? 0) * 100, 100)
        : 0;

    return (
        <Sheet open={open} onOpenChange={onOpenChange}>
            <SheetContent side="right" className="flex flex-col w-full sm:!max-w-lg">
                <SheetHeader>
                    <div className="flex items-center justify-between pr-6">
                        <SheetTitle>Crawl Job Progress</SheetTitle>
                        <StatusBadge status={taskStatus} />
                    </div>
                    {taskID && (
                        <SheetDescription>
                            Task ID: {taskID.slice(0, 8)}...
                        </SheetDescription>
                    )}
                </SheetHeader>

                {/* Fixed top section: timeline + counters + progress */}
                <div className="space-y-3 px-4 shrink-0">
                    <PhaseTimeline
                        currentPhase={taskResult?.phase}
                        taskStatus={taskStatus}
                    />

                    {taskResult && <PhaseDetails result={taskResult} />}

                    {taskResult && taskResult.phase === 'processing' && (
                        <div className="space-y-1">
                            <div className="w-full h-2 bg-primary/20 rounded-full overflow-hidden">
                                <div
                                    className="h-full bg-primary transition-all duration-300 ease-out rounded-full"
                                    style={{ width: `${progressPercent}%` }}
                                />
                            </div>
                            <div className="flex justify-between text-xs text-muted-foreground">
                                <span>
                                    {taskResult.processed ?? 0} / {taskResult.total ?? '?'}
                                </span>
                                <span>{formatEta(taskResult.eta_seconds)}</span>
                            </div>
                        </div>
                    )}

                    {taskResult?.message && (
                        <p className="text-sm text-muted-foreground">{taskResult.message}</p>
                    )}
                </div>

                {/* Log viewer fills remaining space */}
                <div className="flex-1 min-h-0 flex flex-col gap-1 px-4 pb-2">
                    <p className="text-xs font-medium text-muted-foreground uppercase tracking-wide shrink-0">
                        Worker Logs
                    </p>
                    <div className="flex-1 min-h-0">
                        <LogViewer logs={taskResult?.logs ?? []} />
                    </div>
                </div>

                {isInProgress && (
                    <SheetFooter>
                        <Button
                            variant="destructive"
                            onClick={onCancel}
                            disabled={isCancelling}
                            className="w-full"
                        >
                            {isCancelling ? (
                                <>
                                    <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                                    Cancelling...
                                </>
                            ) : (
                                'Cancel Job'
                            )}
                        </Button>
                    </SheetFooter>
                )}
            </SheetContent>
        </Sheet>
    );
}
