import { getUser } from '@/auth/authService';
import type { User } from 'oidc-client-ts';
import React, { useEffect, useState } from 'react';
import { HoverCard, HoverCardContent, HoverCardTrigger } from './ui/hover-card';
import { Progress } from './ui/progress';

interface ModalProps {
    taskID: string | null;
}

const fetchTaskStatus = async (user: User, taskID: string) => {
    const accessToken = user?.access_token;
    const response = await fetch(`/api/task_status?task_id=${taskID}`, {
        method: 'GET',
        headers: {
            'Authorization': `Bearer ${accessToken}`, // Pass the token
            'Content-Type': 'application/json',
        },
    });

    if (!response.ok) {
        throw new Error(`Failed to fetch task status: ${response.status}`);
    }

    const data =
        await response.json();
    return data;
};

enum TaskStatus {
    QUEUED = 'queued',
    PROCESSING = 'processing',
    COMPLETED = 'completed',
    FAILED = 'failed',
}

const taskStatusToProgress = (taskStatus: TaskStatus): number => {
    switch (taskStatus) {
        case TaskStatus.QUEUED:
            return 0.33; // Queued status
        case TaskStatus.PROCESSING:
            return 0.66; // Processing status
        case TaskStatus.COMPLETED:
            return 1.0; // Completed status
        default:
            throw new Error('Unknown task status: ' + status);
    }
}

const getTaskStatus = (status: string): TaskStatus => {
    switch (status.toLowerCase()) {
        case 'queued':
            return TaskStatus.QUEUED;
        case 'processing':
            return TaskStatus.PROCESSING;
        case 'completed':
            return TaskStatus.COMPLETED;
        case 'failed':
            return TaskStatus.FAILED;
        default:
            throw new Error('Unknown task status: ' + status);
    }
};

const ActiveQuery: React.FC<ModalProps> = ({
    taskID
}) => {
    const [user, setUser] = useState<User | null>(null);
    useEffect(() => {
        getUser().then(setUser);
    }, []);

    const [progressPercentage, setProgressPercentage] = useState<number>(0);
    const [taskStatus, setTaskStatus] = useState<TaskStatus | null>(TaskStatus.QUEUED);
    const [lastUpdateTime, setLastUpdateTime] = useState<Date>(new Date());

    // fetch status periodically
    // maybe move to ws one day
    useEffect(() => {
        const interval = setInterval
            (async () => {
                if (!user || !taskID) {
                    return;
                }
                let data = null
                try {
                    data = await fetchTaskStatus(user, taskID);
                } catch (error: any) {
                    clearInterval(interval);
                    setTaskStatus(TaskStatus.FAILED)
                    alert(error)
                }
                if (!data) {
                    clearInterval(interval);
                    return;
                }
                setLastUpdateTime(new Date());
                const taskStatus = getTaskStatus(data.status);
                if (taskStatus === TaskStatus.FAILED) {
                    clearInterval(interval);
                    throw new Error('Task failed');
                }
                setTaskStatus(taskStatus);
                const progress = taskStatusToProgress(taskStatus);
                setProgressPercentage(progress * 100);
                if (taskStatus === TaskStatus.COMPLETED) {
                    clearInterval(interval);
                    return;
                }
            }, 5000); // every 5 seconds
        return () => clearInterval(interval);
    }, [taskID]);

    if (!taskID) {
        return null;
    }

    return (
        <>
            <div>
                <HoverCard>
                    <HoverCardTrigger>
                        {taskStatus && <p>Task status: {taskStatus} </p>}
                        <Progress value={progressPercentage} />
                    </HoverCardTrigger>
                    <HoverCardContent>
                        Task ID: {taskID}
                        <br />
                        Last updated: {lastUpdateTime.toLocaleString()}
                    </HoverCardContent>
                </HoverCard>
            </div>

        </>
    )
};

export default ActiveQuery;
