import { useState, useRef, useCallback } from 'react';
import { fetchWithAuth } from '../fetchWithAuth';

const API_BASE_URL = import.meta.env.VITE_EFC_API_URL;

// Estados que indican que la tarea ya terminó (no hay más que esperar)
const FINAL_STATES = new Set(['SUCCESS', 'FAILURE', 'completed', 'failed', 'cancelled']);

/**
 * Polling acotado de estado de tarea.
 *
 * Uso:
 *   const { taskState, polling, poll, reset } = usePollTaskStatus({ maxAttempts: 3, intervalMs: 2500 });
 *
 *   // Después de enviar la tarea al microservicio:
 *   poll(taskId);
 *
 *   // taskState: null | { status, message, error, attempts }
 *   // polling: true mientras hay intentos pendientes
 */
export function usePollTaskStatus({ maxAttempts = 3, intervalMs = 2500 } = {}) {
  const [taskState, setTaskState] = useState(null);
  const [polling, setPolling]     = useState(false);

  const timeoutRef  = useRef(null);
  const abortedRef  = useRef(false);
  const attemptsRef = useRef(0);

  const stop = useCallback(() => {
    abortedRef.current = true;
    if (timeoutRef.current) {
      clearTimeout(timeoutRef.current);
      timeoutRef.current = null;
    }
    setPolling(false);
  }, []);

  const reset = useCallback(() => {
    stop();
    setTaskState(null);
    attemptsRef.current = 0;
  }, [stop]);

  const poll = useCallback((taskId) => {
    if (!taskId) return;

    // Reiniciar estado previo
    abortedRef.current  = false;
    attemptsRef.current = 0;
    setPolling(true);
    setTaskState({ status: 'PENDING', message: null, error: null, attempts: 0 });

    const attempt = async () => {
      if (abortedRef.current) return;

      attemptsRef.current += 1;
      const n = attemptsRef.current;

      try {
        const res = await fetchWithAuth(`${API_BASE_URL}/tasks/status/${taskId}/`);
        if (abortedRef.current) return;

        if (!res.ok) {
          setTaskState({ status: 'FAILURE', message: `Error HTTP ${res.status}`, error: true, attempts: n });
          setPolling(false);
          return;
        }

        const data = await res.json();
        if (abortedRef.current) return;

        const newState = {
          status:   data.status,
          message:  data.message || data.error || null,
          error:    data.error   || null,
          result:   data.result  || null,
          attempts: n,
        };
        setTaskState(newState);

        if (FINAL_STATES.has(data.status) || n >= maxAttempts) {
          setPolling(false);
          return;
        }

        timeoutRef.current = setTimeout(attempt, intervalMs);

      } catch (err) {
        if (abortedRef.current) return;
        setTaskState({ status: 'FAILURE', message: err.message, error: true, attempts: n });
        setPolling(false);
      }
    };

    attempt();
  }, [maxAttempts, intervalMs]);

  return { taskState, polling, poll, stop, reset };
}