import { TaskStatus, type TaskResult, type TaskState } from '@/types';
import { useEffect, useState, useRef, useMemo } from 'react';
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './ui/tooltip';
import { Button } from './ui/button';
import { Loader2, CheckCircle2, XCircle, X, Trash2 } from 'lucide-react';
import { TaskProgressDrawer } from './TaskProgressDrawer';

interface TaskIndicatorProps {
    tasks: Record<string, TaskState>;
    activeTaskId: string | null;
    isConnected: boolean;
    onCancelTask: (taskId: string) => Promise<boolean>;
    onClearAllTasks: () => Promise<boolean>;
    onTaskCompleted?: () => void;
}

/** Convert a TaskState into a TaskResult (for the drawer). */
function taskStateToResult(ts: TaskState): TaskResult {
    return {
        progress: ts.progress ?? 0,
        processed: ts.processed,
        total: ts.total,
        phase: ts.phase,
        message: ts.message,
        subqueries_probed: ts.subqueries_probed,
        subqueries_initial: ts.subqueries_initial,
        estimated_results: ts.estimated_results,
        subqueries_total: ts.subqueries_total,
        subqueries_completed: ts.subqueries_completed,
        ids_collected: ts.ids_collected,
        pages_fetched: ts.pages_fetched,
        fetching_done: ts.fetching_done,
        details_fetched: ts.details_fetched,
        images_downloaded: ts.images_downloaded,
        ocr_completed: ts.ocr_completed,
        failed: ts.failed,
        elapsed_seconds: ts.elapsed_seconds,
        rate_per_second: ts.rate_per_second,
        eta_seconds: ts.eta_seconds,
        logs: ts.logs,
    };
}

function isTerminalStatus(status: string): boolean {
    return status === 'SUCCESS' || status === 'FAILURE' || status === 'REVOKED';
}

export function TaskIndicator({
    tasks,
    activeTaskId,
    isConnected: _isConnected,
    onCancelTask,
    onClearAllTasks,
    onTaskCompleted,
}: TaskIndicatorProps) {
    const [isCancelling, setIsCancelling] = useState(false);
    const [isClearing, setIsClearing] = useState(false);
    const [drawerOpen, setDrawerOpen] = useState(false);
    const [selectedTaskId, setSelectedTaskId] = useState<string | null>(null);

    const onTaskCompletedRef = useRef(onTaskCompleted);
    useEffect(() => {
        onTaskCompletedRef.current = onTaskCompleted;
    }, [onTaskCompleted]);

    // Track the currently-viewed task in the drawer; default to the externally-provided activeTaskId
    useEffect(() => {
        if (activeTaskId) {
            setSelectedTaskId(activeTaskId);
        }
    }, [activeTaskId]);

    // Fire onTaskCompleted when the active task transitions to SUCCESS
    const prevStatusRef = useRef<string | null>(null);
    useEffect(() => {
        if (!activeTaskId) {
            prevStatusRef.current = null;
            return;
        }
        const task = tasks[activeTaskId];
        const currentStatus = task?.status ?? null;
        if (
            currentStatus === 'SUCCESS' &&
            prevStatusRef.current !== null &&
            prevStatusRef.current !== 'SUCCESS'
        ) {
            onTaskCompletedRef.current?.();
        }
        prevStatusRef.current = currentStatus;
    }, [activeTaskId, tasks]);

    // Derive display data from the active task
    const activeTask = activeTaskId ? tasks[activeTaskId] : undefined;
    const taskStatus = activeTask ? (activeTask.status as TaskStatus) : null;
    const taskResult = activeTask?.phase ? taskStateToResult(activeTask) : null;
    const progressPercentage = (activeTask?.progress ?? 0) * 100;
    const processed = activeTask?.processed ?? null;
    const total = activeTask?.total ?? null;

    // Count active (non-terminal) tasks
    const activeTaskCount = useMemo(() => {
        return Object.values(tasks).filter(
            (t) => !isTerminalStatus(t.status),
        ).length;
    }, [tasks]);

    const handleCancel = async () => {
        if (!activeTaskId || isCancelling) return;

        setIsCancelling(true);
        try {
            await onCancelTask(activeTaskId);
        } finally {
            setIsCancelling(false);
        }
    };

    const handleClearAll = async () => {
        if (isClearing) return;

        setIsClearing(true);
        try {
            await onClearAllTasks();
        } finally {
            setIsClearing(false);
        }
    };

    if (!activeTaskId || !taskStatus) {
        return null;
    }

    const isInProgress = !isTerminalStatus(taskStatus);

    const getStatusIcon = () => {
        if (isInProgress) {
            return <Loader2 className="h-3.5 w-3.5 animate-spin text-blue-500" />;
        }
        if (taskStatus === TaskStatus.SUCCESS) {
            return <CheckCircle2 className="h-3.5 w-3.5 text-green-500" />;
        }
        return <XCircle className="h-3.5 w-3.5 text-red-500" />;
    };

    const getProgressText = () => {
        if (processed !== null && total !== null && total > 0) {
            return `${processed} / ${total}`;
        }
        if (taskResult?.phase && taskResult.phase !== 'processing') {
            const phaseLabels: Record<string, string> = {
                splitting: 'Splitting',
                splitting_complete: 'Split done',
                fetching: 'Fetching',
            };
            return phaseLabels[taskResult.phase] ?? `${Math.round(progressPercentage)}%`;
        }
        return `${Math.round(progressPercentage)}%`;
    };

    const getTooltipContent = () => {
        if (isInProgress) {
            if (processed !== null && total !== null && total > 0) {
                return `Processing: ${processed} / ${total} listings (${Math.round(progressPercentage)}%) — click for details`;
            }
            return `Task running: ${getProgressText()} — click for details`;
        }
        if (taskStatus === TaskStatus.SUCCESS) {
            return 'Task completed successfully — click for details';
        }
        if (taskStatus === TaskStatus.REVOKED) {
            return 'Task was cancelled';
        }
        return 'Task failed';
    };

    return (
        <TooltipProvider>
            <div className="flex items-center gap-2">
                <Tooltip>
                    <TooltipTrigger asChild>
                        <div
                            className="flex items-center gap-2 cursor-pointer"
                            onClick={() => setDrawerOpen(true)}
                        >
                            {getStatusIcon()}
                            {isInProgress && (
                                <div className="flex items-center gap-2">
                                    <div className="w-24 h-1.5 bg-primary/20 rounded-full overflow-hidden hidden sm:block">
                                        <div
                                            className="h-full bg-primary transition-all duration-300 ease-out rounded-full"
                                            style={{ width: `${Math.min(progressPercentage, 100)}%` }}
                                        />
                                    </div>
                                    <span className="text-xs text-muted-foreground hidden sm:inline min-w-[60px]">
                                        {getProgressText()}
                                    </span>
                                </div>
                            )}
                            {!isInProgress && (
                                <span className="text-xs text-muted-foreground hidden sm:inline">
                                    {taskStatus}
                                </span>
                            )}
                            {activeTaskCount > 1 && (
                                <span className="inline-flex items-center justify-center h-4 min-w-[16px] rounded-full bg-blue-500 text-[10px] font-medium text-white px-1">
                                    {activeTaskCount}
                                </span>
                            )}
                        </div>
                    </TooltipTrigger>
                    <TooltipContent side="bottom">
                        <p>{getTooltipContent()}</p>
                        <p className="text-xs text-muted-foreground mt-1">ID: {activeTaskId.slice(0, 8)}...</p>
                    </TooltipContent>
                </Tooltip>
                {isInProgress && (
                    <Tooltip>
                        <TooltipTrigger asChild>
                            <Button
                                variant="ghost"
                                size="icon"
                                onClick={handleCancel}
                                disabled={isCancelling}
                                className="h-6 w-6 text-muted-foreground hover:text-destructive"
                            >
                                <X className="h-3 w-3" />
                            </Button>
                        </TooltipTrigger>
                        <TooltipContent side="bottom">
                            <p>Cancel task</p>
                        </TooltipContent>
                    </Tooltip>
                )}
                <Tooltip>
                    <TooltipTrigger asChild>
                        <Button
                            variant="ghost"
                            size="icon"
                            onClick={handleClearAll}
                            disabled={isClearing}
                            className="h-6 w-6 text-muted-foreground hover:text-destructive"
                        >
                            <Trash2 className="h-3 w-3" />
                        </Button>
                    </TooltipTrigger>
                    <TooltipContent side="bottom">
                        <p>Clear all tasks</p>
                    </TooltipContent>
                </Tooltip>
            </div>
            <TaskProgressDrawer
                open={drawerOpen}
                onOpenChange={setDrawerOpen}
                taskResult={taskResult}
                taskStatus={taskStatus}
                taskID={selectedTaskId ?? activeTaskId}
                onCancel={handleCancel}
                isCancelling={isCancelling}
                tasks={tasks}
                selectedTaskId={selectedTaskId}
                onSelectTask={setSelectedTaskId}
            />
        </TooltipProvider>
    );
}
