import React, { useState, useEffect, useRef } from 'react';
import { useNavigate, useLocation } from 'react-router-dom';
import { useTaskProgress } from '../context/TaskProgressContext';
import { useServerSentEvents } from '../hooks/useServerSentEvents';
import { fetchWithAuth } from '../fetchWithAuth';

const API_URL = import.meta.env.VITE_EFC_API_URL;

const STATUS_LABEL = {
  submitted:  'Enviando...',
  processing: 'Procesando',
  completed:  'Completado',
  failed:     'Error',
};

const BADGE_COLOR = {
  submitted:  'bg-slate-200 text-slate-700',
  processing: 'bg-blue-100  text-blue-700',
  completed:  'bg-green-100 text-green-700',
  failed:     'bg-red-100   text-red-700',
};

const AUTH_PATHS = new Set(['/', '/login', '/forgot-password', '/auth/sso']);

/** Conecta SSE para UNA tarea y actualiza el contexto. Se mantiene vivo independientemente del estado del panel. */
function TaskSSEConnector({ task }) {
  const { updateTask } = useTaskProgress();
  useServerSentEvents(
    task.status === 'completed' || task.status === 'failed' ? null : task.task_id,
    {
      onUpdate(data) {
        updateTask(task.task_id, {
          status:    data.status,
          message:   data.message,
          progress:  data.progress ?? task.progress,
          resultado: data.resultado ?? task.resultado,
        });
      },
      onCompleted(resultado) {
        updateTask(task.task_id, { status: 'completed', progress: 100, resultado });
      },
      onFailed(message) {
        updateTask(task.task_id, { status: 'failed', message });
      },
    }
  );
  return null;
}

/** Card compacta de una tarea dentro del panel expandido. */
function SingleTaskCard({ task }) {
  const { dismissTask, openTaskInAuditor } = useTaskProgress();
  const navigate = useNavigate();
  const [downloading, setDownloading] = useState(false);
  const isActive   = task.status === 'submitted' || task.status === 'processing';
  const isReport   = task.taskType === 'report';

  const handleVerResultado = () => {
    openTaskInAuditor(task.task_id);
    navigate('/auditor');
  };

  const handleDescargarReporte = async () => {
    const reportId = task.resultado?.report_id ?? task.report_id;
    if (!reportId) { navigate('/reports'); return; }
    setDownloading(true);
    try {
      const res = await fetchWithAuth(`${API_URL}/reports/report-document-download/${reportId}/`);
      if (!res.ok) { navigate('/reports'); return; }
      const blob = await res.blob();
      const disposition = res.headers.get('Content-Disposition');
      let filename = '';
      if (disposition) {
        const match = disposition.match(/filename="?([^";\s]+)"?/);
        if (match) filename = match[1];
      }
      if (!filename) filename = `reporte_${reportId}.xlsx`;
      const link = document.createElement('a');
      link.href = window.URL.createObjectURL(blob);
      link.download = filename;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      dismissTask(task.task_id);
    } catch {
      navigate('/reports');
    } finally {
      setDownloading(false);
    }
  };

  return (
    <div className="flex flex-col gap-1.5 p-2.5 rounded-lg border border-gray-100 bg-gray-50 text-xs">
      <div className="flex items-center justify-between gap-2">
        <div className="flex items-center gap-1.5 min-w-0">
          <span className="font-semibold truncate text-gray-800">{task.label}</span>
          <span className={`px-1.5 py-0.5 rounded text-xs font-medium flex-shrink-0 ${BADGE_COLOR[task.status]}`}>
            {STATUS_LABEL[task.status] ?? task.status}
          </span>
        </div>
        <button
          onClick={() => dismissTask(task.task_id)}
          aria-label="Descartar tarea"
          className="text-gray-300 hover:text-gray-500 flex-shrink-0"
        >
          <svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M6 18L18 6M6 6l12 12" />
          </svg>
        </button>
      </div>

      {task.message && (
        <p className="text-xs text-gray-400 truncate">{task.message}</p>
      )}

      {isActive && (
        <div className="w-full bg-blue-100 rounded-full h-1 overflow-hidden">
          <div
            className="bg-blue-500 h-1 rounded-full transition-all duration-500"
            style={{ width: `${task.progress ?? 0}%` }}
          />
        </div>
      )}

      {task.status === 'completed' && isReport && (
        <button
          onClick={handleDescargarReporte}
          disabled={downloading}
          className="w-full py-1 px-2 rounded bg-green-600 hover:bg-green-700 disabled:bg-green-400 text-white text-xs font-semibold transition-colors flex items-center justify-center gap-1"
        >
          {downloading ? (
            <>
              <svg className="w-3 h-3 animate-spin" fill="none" viewBox="0 0 24 24">
                <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
                <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
              </svg>
              Descargando...
            </>
          ) : (
            <>
              <svg className="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" />
              </svg>
              Descargar reporte
            </>
          )}
        </button>
      )}

      {task.status === 'completed' && !isReport && (
        <button
          onClick={handleVerResultado}
          className="w-full py-1 px-2 rounded bg-green-600 hover:bg-green-700 text-white text-xs font-semibold transition-colors"
        >
          Ver resultado en Auditoría →
        </button>
      )}

      {task.status === 'failed' && isReport && (
        <p className="text-xs text-red-500">
          Falló — revisa el historial en{' '}
          <button onClick={() => navigate('/reports')} className="underline">Reportes</button>.
        </p>
      )}

      {task.status === 'failed' && !isReport && (
        <p className="text-xs text-red-500">Falló — revisa el Panel de Auditoría.</p>
      )}
    </div>
  );
}

/**
 * TaskProgressCard — pill minimizado en bottom-left.
 * Las conexiones SSE viven siempre; el panel es solo visual y no bloquea la UI.
 * Se auto-expande cuando una tarea pasa a completada o fallida.
 */
export default function TaskProgressCard() {
  const { visibleTasks } = useTaskProgress();
  const location = useLocation();
  const [expanded, setExpanded] = useState(false);
  const prevStatusesRef = useRef({});
  const containerRef = useRef(null);

  // Cierra el panel al hacer click fuera del componente
  useEffect(() => {
    if (!expanded) return;
    function handleClickOutside(e) {
      if (containerRef.current && !containerRef.current.contains(e.target)) {
        setExpanded(false);
      }
    }
    document.addEventListener('mousedown', handleClickOutside);
    return () => document.removeEventListener('mousedown', handleClickOutside);
  }, [expanded]);

  // Auto-expandir cuando una tarea activa pasa a estado terminal
  useEffect(() => {
    let shouldExpand = false;
    visibleTasks.forEach(t => {
      const prev = prevStatusesRef.current[t.task_id];
      if (
        (t.status === 'completed' || t.status === 'failed') &&
        prev !== undefined && prev !== 'completed' && prev !== 'failed'
      ) {
        shouldExpand = true;
      }
      prevStatusesRef.current[t.task_id] = t.status;
    });
    if (shouldExpand) setExpanded(true);
  }, [visibleTasks]);

  // Solo renderizar dentro de la app autenticada
  const isAuthPage = AUTH_PATHS.has(location.pathname)
    || location.pathname.startsWith('/user/password-reset-confirm/');

  if (isAuthPage || visibleTasks.length === 0) return null;

  const activeTasks  = visibleTasks.filter(t => t.status === 'submitted' || t.status === 'processing');
  const completedTasks = visibleTasks.filter(t => t.status === 'completed');
  const failedTasks  = visibleTasks.filter(t => t.status === 'failed');

  // Estilo y contenido del pill según estado dominante
  let pillLabel, pillClass, pillIconType;
  if (activeTasks.length > 0) {
    pillLabel     = `${activeTasks.length} tarea${activeTasks.length > 1 ? 's' : ''} en proceso`;
    pillClass     = 'bg-blue-600 text-white border-blue-700 hover:bg-blue-700';
    pillIconType  = 'spinner';
  } else if (failedTasks.length > 0 && completedTasks.length === 0) {
    pillLabel     = `${failedTasks.length} tarea${failedTasks.length > 1 ? 's' : ''} fallida${failedTasks.length > 1 ? 's' : ''}`;
    pillClass     = 'bg-red-50 text-red-700 border-red-300 hover:bg-red-100';
    pillIconType  = 'x';
  } else {
    pillLabel     = `${completedTasks.length} tarea${completedTasks.length > 1 ? 's' : ''} completada${completedTasks.length > 1 ? 's' : ''}`;
    pillClass     = 'bg-green-50 text-green-700 border-green-300 hover:bg-green-100';
    pillIconType  = 'check';
  }

  return (
    <>
      {/* Conectores SSE — siempre activos, independientes del estado del panel */}
      {visibleTasks
        .filter(t => t.status === 'processing' || t.status === 'submitted')
        .map(task => <TaskSSEConnector key={task.task_id} task={task} />)}

      {/*
        Dock flotante en top-right. El pill queda arriba y el panel se expande hacia abajo.
        items-end alinea todo a la derecha.
      */}
      <div ref={containerRef} className="fixed top-4 right-4 z-40 flex flex-col items-end gap-2">

        {/* Pill — botón de toggle siempre visible, arriba */}
        <button
          onClick={() => setExpanded(e => !e)}
          className={`flex items-center gap-1.5 pl-2.5 pr-3 py-1.5 rounded-full text-xs font-semibold shadow-md border transition-all ${pillClass}`}
        >
          {pillIconType === 'spinner' && (
            <svg className="w-3 h-3 animate-spin flex-shrink-0" fill="none" viewBox="0 0 24 24">
              <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
              <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
            </svg>
          )}
          {pillIconType === 'check' && (
            <svg className="w-3 h-3 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M5 13l4 4L19 7" />
            </svg>
          )}
          {pillIconType === 'x' && (
            <svg className="w-3 h-3 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M6 18L18 6M6 6l12 12" />
            </svg>
          )}
          <span>{pillLabel}</span>
        </button>

        {/* Panel expandido — aparece debajo del pill */}
        {expanded && (
          <div className="bg-white border border-gray-200 rounded-xl shadow-xl w-72 overflow-hidden">
            <div className="flex items-center justify-between px-3 py-2 bg-gray-50 border-b border-gray-100">
              <span className="text-xs font-semibold text-gray-500 uppercase tracking-wide">
                Tareas en segundo plano
              </span>
              <button
                onClick={() => setExpanded(false)}
                aria-label="Minimizar panel"
                className="text-gray-400 hover:text-gray-600"
              >
                <svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M5 15l7-7 7 7" />
                </svg>
              </button>
            </div>
            <div className="p-2 flex flex-col gap-1.5 max-h-72 overflow-y-auto">
              {visibleTasks.map(task => <SingleTaskCard key={task.task_id} task={task} />)}
            </div>
          </div>
        )}

      </div>
    </>
  );
}
