import { useState, useEffect, useRef, useCallback } from 'react';

export type AIJobStatus = 'idle' | 'pending' | 'complete' | 'failed' | 'timeout';

interface JobResult {
    status: AIJobStatus;
    answer?: string;
    error?: string;
}

interface UseAIPollingProps {
    getToken: (() => Promise<string>) | null;
}

const POLL_INTERVAL_MS = 4000;     // 4초 간격 폴링
const MAX_WAIT_MS = 3 * 60 * 1000; // 3분(180초) 강제 타임아웃

export function useAIPolling({ getToken }: UseAIPollingProps) {
    const [status, setStatus] = useState<AIJobStatus>('idle');
    const [answer, setAnswer] = useState<string | null>(null);
    const [error, setError] = useState<string | null>(null);
    const [jobId, setJobId] = useState<string | null>(null);

    const pollIntervalRef = useRef<NodeJS.Timeout | null>(null);
    const timeoutRef = useRef<NodeJS.Timeout | null>(null);

    // 폴링 정리 함수
    const clearPolling = useCallback(() => {
        if (pollIntervalRef.current) {
            clearInterval(pollIntervalRef.current);
            pollIntervalRef.current = null;
        }
        if (timeoutRef.current) {
            clearTimeout(timeoutRef.current);
            timeoutRef.current = null;
        }
    }, []);

    // 컴포넌트 언마운트 시 정리
    useEffect(() => {
        return () => clearPolling();
    }, [clearPolling]);

    // 폴링 함수
    const startPolling = useCallback((id: string) => {
        clearPolling();

        // 3분 타임아웃 방어선 설정
        timeoutRef.current = setTimeout(() => {
            clearPolling();
            setStatus('timeout');
            setError('서버 응답이 너무 오래 걸립니다. 잠시 후 다시 시도해 주세요.');
        }, MAX_WAIT_MS);

        // 4초 간격으로 상태 폴링
        pollIntervalRef.current = setInterval(async () => {
            if (!getToken) return;
            try {
                const token = await getToken();
                const res = await fetch(`/api/ai/status?jobId=${id}`, {
                    headers: { 'Authorization': `Bearer ${token}` }
                });

                if (!res.ok) {
                    throw new Error('상태 조회 중 오류가 발생했습니다.');
                }

                const data: JobResult & { status: string } = await res.json();

                if (data.status === 'complete') {
                    clearPolling();
                    setStatus('complete');
                    setAnswer(data.answer || '');
                } else if (data.status === 'failed') {
                    clearPolling();
                    setStatus('failed');
                    setError(data.error || '분석 중 오류가 발생했습니다.');
                }
                // 'pending' 상태면 계속 폴링
            } catch (err: unknown) {
                console.error('Polling error:', err);
                clearPolling();
                setStatus('failed');
                const message = err instanceof Error ? err.message : String(err);
                setError(message || '네트워크 오류가 발생했습니다.');
            }
        }, POLL_INTERVAL_MS);
    }, [getToken, clearPolling]);

    // PDF 쿼리 시작 함수
    const submitQuery = useCallback(async (params: {
        question: string;
        companyId: string;
        productId: string;
    }) => {
        if (!getToken) return;

        setStatus('pending');
        setAnswer(null);
        setError(null);
        setJobId(null);
        clearPolling();

        try {
            const token = await getToken();
            const res = await fetch('/api/ai/query', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${token}`
                },
                body: JSON.stringify(params)
            });

            if (!res.ok) {
                const errData = await res.json();
                throw new Error(errData.error || 'Job 생성에 실패했습니다.');
            }

            const { jobId: newJobId } = await res.json();
            setJobId(newJobId);
            startPolling(newJobId);

        } catch (err: unknown) {
            setStatus('failed');
            const message = err instanceof Error ? err.message : String(err);
            setError(message);
        }
    }, [getToken, startPolling, clearPolling]);

    const reset = useCallback(() => {
        clearPolling();
        setStatus('idle');
        setAnswer(null);
        setError(null);
        setJobId(null);
    }, [clearPolling]);

    return { status, answer, error, jobId, submitQuery, reset };
}
