import React, { useState, useRef, useCallback } from 'react';
import mammoth from 'mammoth';
function getNextSeq() {
  const n = parseInt(localStorage.getItem('arpm_project_seq') || '0', 10);
  return n + 1;
}
function incrementSeq() {
  const n = parseInt(localStorage.getItem('arpm_project_seq') || '0', 10);
  localStorage.setItem('arpm_project_seq', String(n + 1));
}
function generateCode() {
  try {
    const b = JSON.parse(localStorage.getItem('arpm_branding') || '{}');
    const name = b.appName || 'ARPM';
    const initials = name.split(/\s+/).map(w => w[0]).join('').toUpperCase().slice(0, 4);
    const year = new Date().getFullYear();
    return `${initials}-PRY-${year}-${String(getNextSeq()).padStart(3, '0')}`;
  } catch { return `PRY-${new Date().getFullYear()}-001`; }
}

const ACCEPTED = '.docx,.txt';

// ── Extracción de texto ───────────────────────────────────────────────────────
async function extractText(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onerror = reject;
    if (file.name.endsWith('.txt')) {
      reader.onload = e => resolve(e.target.result);
      reader.readAsText(file, 'utf-8');
    } else if (file.name.endsWith('.docx')) {
      reader.onload = async e => {
        try {
          const result = await mammoth.extractRawText({ arrayBuffer: e.target.result });
          resolve(result.value);
        } catch (err) { reject(err); }
      };
      reader.readAsArrayBuffer(file);
    } else {
      reject(new Error('Formato no soportado. Usa .docx o .txt'));
    }
  });
}

// ── Config IA ─────────────────────────────────────────────────────────────────
function getAIConfig() {
  try { return JSON.parse(localStorage.getItem('arpm_settings') || '{}'); }
  catch { return {}; }
}

// ── Prompt ────────────────────────────────────────────────────────────────────
const PROMPT = (text) => `Eres un experto certificado PMP. Tu tarea es leer el anteproyecto adjunto y generar el plan de trabajo detallado necesario para EJECUTARLO. Devuelve ÚNICAMENTE JSON válido (sin texto, sin markdown, sin \`\`\`json).

ESQUEMA EXACTO:
{"project":{"name":"","client":"","description":"","budget":0,"startDate":"YYYY-MM-DD","plannedEndDate":"YYYY-MM-DD","type":"Investigación","category":"Tecnología","methodology":"PMI","objectives":""},"phases":[{"name":"Fase 1 — Nombre","startDate":"YYYY-MM-DD","endDate":"YYYY-MM-DD","tasks":[{"title":"","wbsCode":"1.1","dueDate":"YYYY-MM-DD","estimatedHours":40,"priority":"ALTO","isCritical":true,"description":""}],"milestone":{"title":"✦ Hito: Entrega Fase 1","wbsCode":"1.0","dueDate":"YYYY-MM-DD"}}],"risks":[{"title":"","impact":"ALTO","probability":"MEDIO"}],"team":[]}

INSTRUCCIONES:
1. Extrae del documento: nombre del proyecto, cliente/entidad, presupuesto, fechas, objetivos, alcance
2. ESTIMA LA DURACIÓN del proyecto: analiza la complejidad (número de entregables, presupuesto, tipo de obra/software), busca la fecha de inicio en el documento, y calcula la fecha de fin realista. Si el documento menciona plazos ("6 meses", "2 años"), úsalos. Si no, estima según el tipo: Software pequeño=6 meses, Software mediano=12-18 meses, Construcción pequeña=8 meses, Construcción grande=24-36 meses, Investigación=12 meses. Pon startDate y plannedEndDate coherentes con esta estimación.
3. Identifica las FASES mencionadas o implícitas en el documento. Si no están explícitas, define fases lógicas según el tipo de proyecto (Inicio, Planificación, Ejecución, Control, Cierre)
4. Para cada fase, genera las tareas concretas necesarias para producir los ENTREGABLES descritos en el documento. Sé específico: "Diseñar planos estructurales del galpón de producción" no "Diseño"
5. Distribuye las fechas de las fases y tareas proporcionalmente entre startDate y plannedEndDate
6. Añade tareas de gestión transversales: actas de reunión, informes de avance mensuales, control de calidad, gestión de riesgos, comunicaciones con stakeholders
7. MÍNIMO 30 tareas en total (mín. 5 fases × mín. 6 tareas)
8. Cada fase termina con un hito de entrega (isMilestone: true, wbsCode: N.0)
9. Tipos: Construcción|Software|Producción|Consultoría|Marketing|Investigación|Otro
10. Categorías: Infraestructura|Tecnología|Entretenimiento|Producto Interno|Salud|Educación|Finanzas|Otro
11. Metodologías: PMI|Scrum|Agile|Kanban|PRINCE2|Lean|Waterfall
12. Prioridades: CRITICO|ALTO|MEDIO|BAJO — isCritical:true en ≥40% de tareas
13. estimatedHours: entre 8 y 320 por tarea

ANTEPROYECTO:
${text.slice(0, 14000)}`;

// ── Llamada a la IA ───────────────────────────────────────────────────────────
async function callAI(text, config) {
  const provider = config.aiProvider || 'ollama';
  const prompt = PROMPT(text);

  if (provider === 'ollama') {
    const base = (config.aiLocalUrl || 'http://localhost:11434').replace(/\/$/, '');
    let model = config.aiLocalModel || 'llama3';

    let res = await fetch(`${base}/api/generate`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ model, prompt, stream: false, options: { num_predict: 8192, temperature: 0.2 } }),
    });

    if (res.status === 404) {
      const tagsRes = await fetch(`${base}/api/tags`);
      if (!tagsRes.ok) throw new Error(`Ollama no responde en ${base}`);
      const tags = await tagsRes.json();
      const available = tags.models?.map(m => m.name) || [];
      if (!available.length) throw new Error('Ollama no tiene modelos instalados. Ejecuta: ollama pull llama3');
      model = available[0];
      res = await fetch(`${base}/api/generate`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ model, prompt, stream: false, options: { num_predict: 8192, temperature: 0.2 } }),
      });
    }
    if (!res.ok) throw new Error(`Ollama error ${res.status}`);
    const data = await res.json();
    return data.response;
  }

  if (provider === 'claude') {
    const res = await fetch('https://api.anthropic.com/v1/messages', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': config.claudeApiKey || '',
        'anthropic-version': '2023-06-01',
      },
      body: JSON.stringify({
        model: config.claudeModel || 'claude-haiku-4-5-20251001',
        max_tokens: 4096,
        messages: [{ role: 'user', content: prompt }],
      }),
    });
    if (!res.ok) throw new Error(`Claude API error ${res.status}`);
    const data = await res.json();
    return data.content[0].text;
  }

  if (provider === 'openai') {
    const res = await fetch('https://api.openai.com/v1/chat/completions', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${config.openaiApiKey || ''}`,
      },
      body: JSON.stringify({
        model: config.openaiModel || 'gpt-4o-mini',
        messages: [{ role: 'user', content: prompt }],
        max_tokens: 4096,
      }),
    });
    if (!res.ok) throw new Error(`OpenAI error ${res.status}`);
    const data = await res.json();
    return data.choices[0].message.content;
  }

  throw new Error('No hay IA configurada. Ve a Configuración → Inteligencia IA.');
}

function parseJSON(raw) {
  const match = raw.match(/\{[\s\S]*\}/);
  if (!match) throw new Error('La IA no devolvió JSON válido.');
  return JSON.parse(match[0]);
}

// ── Guardar en localStorage (modo demo) ──────────────────────────────────────
function saveToLocalStorage(plan) {
  const projectId = 'p' + Date.now();
  const newProject = {
    id: projectId,
    code: generateCode(),
    name: plan.project.name,
    type: plan.project.type || 'Otro',
    category: plan.project.category || 'Tecnología',
    client: plan.project.client || '',
    status: 'ACTIVO',
    methodology: plan.project.methodology || 'PMI',
    ragStatus: 'VERDE',
    progressPct: 0,
    budget: Number(plan.project.budget) || 0,
    baselineBudget: Number(plan.project.budget) || 0,
    startDate: plan.project.startDate || '',
    plannedEndDate: plan.project.plannedEndDate || '',
    baselineEndDate: plan.project.plannedEndDate || '',
    description: plan.project.description || '',
  };

  // Guardar proyecto e incrementar contador
  const storedProjects = JSON.parse(localStorage.getItem('arpm_projects') || '[]');
  storedProjects.push(newProject);
  localStorage.setItem('arpm_projects', JSON.stringify(storedProjects));
  incrementSeq();

  // Construir tareas e hitos
  const tasks = [];
  let taskCounter = 1;
  (plan.phases || []).forEach(phase => {
    (phase.tasks || []).forEach(t => {
      tasks.push({
        id: `${projectId}-t${taskCounter++}`,
        wbsCode: t.wbsCode || '',
        phase: phase.name,
        title: t.title,
        description: t.description || '',
        status: 'PENDIENTE',
        priority: t.priority || 'MEDIO',
        assignee: null,
        dueDate: t.dueDate || phase.endDate || '',
        progressPct: 0,
        predecessors: [],
        isMilestone: false,
        isCritical: t.isCritical || false,
        estimatedHours: t.estimatedHours || 8,
        actualHours: 0,
        plannedCost: Math.round((t.estimatedHours || 8) * 150),
        actualCost: 0,
        baselineStart: phase.startDate || '',
        baselineEnd: t.dueDate || phase.endDate || '',
        projectId,
      });
    });
    if (phase.milestone) {
      tasks.push({
        id: `${projectId}-t${taskCounter++}`,
        wbsCode: phase.milestone.wbsCode || '',
        phase: phase.name,
        title: phase.milestone.title,
        status: 'PENDIENTE',
        priority: 'CRITICO',
        assignee: null,
        dueDate: phase.milestone.dueDate || phase.endDate || '',
        progressPct: 0,
        predecessors: [],
        isMilestone: true,
        isCritical: true,
        estimatedHours: 0,
        actualHours: 0,
        plannedCost: 0,
        actualCost: 0,
        baselineStart: phase.milestone.dueDate || phase.endDate || '',
        baselineEnd: phase.milestone.dueDate || phase.endDate || '',
        projectId,
      });
    }
  });

  const storedTasks = JSON.parse(localStorage.getItem('arpm_tasks') || '{}');
  storedTasks[projectId] = tasks;
  localStorage.setItem('arpm_tasks', JSON.stringify(storedTasks));

  return { projectId, taskCount: tasks.length };
}

// ── Componentes visuales ──────────────────────────────────────────────────────
function PreviewField({ label, value }) {
  return (
    <div className="bg-slate-50 dark:bg-surface-700 rounded-xl px-4 py-3">
      <p className="text-xs text-slate-400 dark:text-gray-500 mb-0.5">{label}</p>
      <p className="text-sm font-medium text-slate-800 dark:text-gray-200 truncate">{value || '—'}</p>
    </div>
  );
}

// ── Modal principal ───────────────────────────────────────────────────────────
export default function AnteproyectoImportModal({ onImport, onClose }) {
  const [step, setStep]       = useState('upload');
  const [dragging, setDragging] = useState(false);
  const [fileName, setFileName] = useState('');
  const [error, setError]     = useState('');
  const [plan, setPlan]       = useState(null);
  const [activePhase, setActivePhase] = useState(0);
  const fileRef = useRef();

  const processFile = useCallback(async (file) => {
    setFileName(file.name);
    setStep('analyzing');
    setError('');
    try {
      const text = await extractText(file);
      const config = getAIConfig();
      const raw = await callAI(text, config);
      const data = parseJSON(raw);
      if (!data.project || !data.phases) throw new Error('La IA no generó un plan válido. Intenta de nuevo.');
      setPlan(data);
      setActivePhase(0);
      setStep('preview');
    } catch (err) {
      setError(err.message);
      setStep('error');
    }
  }, []);

  const onDrop = useCallback(e => {
    e.preventDefault();
    setDragging(false);
    const file = e.dataTransfer.files[0];
    if (file) processFile(file);
  }, [processFile]);

  const handleImport = () => {
    const { projectId, taskCount } = saveToLocalStorage(plan);
    onImport({ plan, projectId, taskCount });
    onClose();
  };

  const totalTasks = plan
    ? plan.phases.reduce((sum, ph) => sum + (ph.tasks?.length || 0), 0)
    : 0;
  const totalMilestones = plan ? plan.phases.filter(ph => ph.milestone).length : 0;

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/60 backdrop-blur-sm">
      <div className="bg-white dark:bg-surface-800 rounded-2xl shadow-2xl w-full max-w-3xl max-h-[90vh] flex flex-col">

        {/* Header */}
        <div className="flex items-center justify-between px-6 py-4 border-b border-slate-200 dark:border-surface-700 flex-shrink-0">
          <div className="flex items-center gap-3">
            <div className="w-8 h-8 rounded-lg bg-violet-100 dark:bg-violet-500/20 flex items-center justify-center">
              <svg className="w-4 h-4 text-violet-600 dark:text-violet-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
                <path strokeLinecap="round" strokeLinejoin="round" d="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"/>
              </svg>
            </div>
            <div>
              <h2 className="text-sm font-semibold text-slate-900 dark:text-white">Importar anteproyecto con IA</h2>
              <p className="text-xs text-slate-400 dark:text-gray-500">Genera proyecto + tareas + hitos automáticamente</p>
            </div>
          </div>
          <button onClick={onClose} className="text-slate-400 hover:text-slate-600 dark:hover:text-gray-300 transition cursor-pointer">
            <svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
              <path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12"/>
            </svg>
          </button>
        </div>

        {/* Body */}
        <div className="flex-1 overflow-y-auto p-6">

          {/* UPLOAD */}
          {step === 'upload' && (
            <div
              onDragOver={e => { e.preventDefault(); setDragging(true); }}
              onDragLeave={() => setDragging(false)}
              onDrop={onDrop}
              onClick={() => fileRef.current.click()}
              className={`border-2 border-dashed rounded-2xl p-12 text-center cursor-pointer transition-all
                ${dragging
                  ? 'border-violet-400 bg-violet-50 dark:bg-violet-500/10'
                  : 'border-slate-200 dark:border-surface-600 hover:border-violet-300 hover:bg-violet-50/50 dark:hover:bg-violet-500/5'
                }`}
            >
              <input ref={fileRef} type="file" accept={ACCEPTED} className="hidden" onChange={e => { const f = e.target.files[0]; if (f) processFile(f); }}/>
              <div className="w-14 h-14 rounded-2xl bg-violet-100 dark:bg-violet-500/20 flex items-center justify-center mx-auto mb-4">
                <svg className="w-7 h-7 text-violet-600 dark:text-violet-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
                  <path strokeLinecap="round" strokeLinejoin="round" d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"/>
                </svg>
              </div>
              <p className="text-sm font-semibold text-slate-700 dark:text-gray-300 mb-1">Arrastra el anteproyecto aquí</p>
              <p className="text-xs text-slate-400 dark:text-gray-500 mb-5">o haz clic para seleccionar · .docx o .txt</p>
              <div className="flex items-center justify-center gap-3 text-xs text-slate-400 dark:text-gray-500">
                <span className="flex items-center gap-1.5">
                  <svg className="w-3.5 h-3.5 text-violet-500" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}><path strokeLinecap="round" strokeLinejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"/></svg>
                  Genera tareas e hitos
                </span>
                <span>·</span>
                <span className="flex items-center gap-1.5">
                  <svg className="w-3.5 h-3.5 text-violet-500" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}><path strokeLinecap="round" strokeLinejoin="round" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/></svg>
                  Fechas y presupuesto
                </span>
                <span>·</span>
                <span className="flex items-center gap-1.5">
                  <svg className="w-3.5 h-3.5 text-violet-500" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}><path strokeLinecap="round" strokeLinejoin="round" d="M12 9v2m0 4h.01M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/></svg>
                  Riesgos identificados
                </span>
              </div>
            </div>
          )}

          {/* ANALYZING */}
          {step === 'analyzing' && (
            <div className="text-center py-16">
              <div className="w-14 h-14 border-2 border-violet-500 border-t-transparent rounded-full animate-spin mx-auto mb-5"/>
              <p className="text-sm font-semibold text-slate-700 dark:text-gray-300 mb-1">Analizando anteproyecto…</p>
              <p className="text-xs text-slate-400 dark:text-gray-500 mb-1">{fileName}</p>
              <p className="text-xs text-slate-400 dark:text-gray-500">La IA está generando el plan completo con tareas e hitos</p>
            </div>
          )}

          {/* ERROR */}
          {step === 'error' && (
            <div className="text-center py-12">
              <div className="w-14 h-14 rounded-full bg-red-100 dark:bg-red-500/20 flex items-center justify-center mx-auto mb-4">
                <svg className="w-7 h-7 text-red-500" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
                  <path strokeLinecap="round" strokeLinejoin="round" d="M12 9v2m0 4h.01M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/>
                </svg>
              </div>
              <p className="text-sm font-semibold text-red-600 dark:text-red-400 mb-2">Error al procesar</p>
              <p className="text-xs text-slate-500 dark:text-gray-400 mb-6 max-w-sm mx-auto">{error}</p>
              <button onClick={() => setStep('upload')}
                className="px-4 py-2 text-sm font-medium rounded-xl bg-slate-100 dark:bg-surface-700 text-slate-700 dark:text-gray-300 hover:bg-slate-200 dark:hover:bg-surface-600 transition cursor-pointer">
                Intentar con otro archivo
              </button>
            </div>
          )}

          {/* PREVIEW */}
          {step === 'preview' && plan && (
            <div className="space-y-5">

              {/* Banner resumen */}
              <div className="flex items-center gap-4 bg-emerald-50 dark:bg-emerald-500/10 border border-emerald-200 dark:border-emerald-500/20 rounded-xl px-4 py-3">
                <svg className="w-5 h-5 text-emerald-500 flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
                  <path strokeLinecap="round" strokeLinejoin="round" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
                </svg>
                <div className="flex-1 text-xs text-emerald-700 dark:text-emerald-300">
                  Plan generado desde <strong>{fileName}</strong>
                </div>
                <div className="flex items-center gap-3 text-xs font-semibold">
                  <span className="bg-emerald-100 dark:bg-emerald-500/20 text-emerald-700 dark:text-emerald-300 px-2.5 py-1 rounded-lg">
                    {plan.phases?.length} fases
                  </span>
                  <span className="bg-blue-100 dark:bg-blue-500/20 text-blue-700 dark:text-blue-300 px-2.5 py-1 rounded-lg">
                    {totalTasks} tareas
                  </span>
                  <span className="bg-violet-100 dark:bg-violet-500/20 text-violet-700 dark:text-violet-300 px-2.5 py-1 rounded-lg">
                    {totalMilestones} hitos
                  </span>
                </div>
              </div>

              {/* Info del proyecto */}
              <div>
                <p className="text-xs font-bold text-slate-400 dark:text-gray-500 uppercase tracking-widest mb-3">Datos del proyecto</p>
                <div className="grid grid-cols-3 gap-2">
                  <PreviewField label="Nombre" value={plan.project?.name}/>
                  <PreviewField label="Código" value={plan.project?.code}/>
                  <PreviewField label="Cliente" value={plan.project?.client}/>
                  <PreviewField label="Presupuesto" value={plan.project?.budget ? `$${Number(plan.project.budget).toLocaleString()}` : '—'}/>
                  <PreviewField label="Inicio" value={plan.project?.startDate}/>
                  <PreviewField label="Fin" value={plan.project?.plannedEndDate}/>
                </div>
                {plan.project?.description && (
                  <div className="mt-2 bg-slate-50 dark:bg-surface-700 rounded-xl px-4 py-3">
                    <p className="text-xs text-slate-400 dark:text-gray-500 mb-1">Descripción</p>
                    <p className="text-sm text-slate-700 dark:text-gray-300">{plan.project.description}</p>
                  </div>
                )}
              </div>

              {/* Fases y tareas */}
              <div>
                <p className="text-xs font-bold text-slate-400 dark:text-gray-500 uppercase tracking-widest mb-3">Plan de trabajo</p>

                {/* Tabs de fases */}
                <div className="flex gap-1 flex-wrap mb-3">
                  {plan.phases.map((ph, i) => (
                    <button key={i} onClick={() => setActivePhase(i)}
                      className={`px-3 py-1.5 text-xs font-medium rounded-lg transition cursor-pointer ${
                        activePhase === i
                          ? 'bg-blue-600 text-white'
                          : 'bg-slate-100 dark:bg-surface-700 text-slate-600 dark:text-gray-400 hover:bg-slate-200 dark:hover:bg-surface-600'
                      }`}>
                      {ph.name}
                    </button>
                  ))}
                </div>

                {/* Tareas de la fase activa */}
                {plan.phases[activePhase] && (
                  <div className="border border-slate-200 dark:border-surface-600 rounded-xl overflow-hidden">
                    <table className="w-full text-xs">
                      <thead className="bg-slate-50 dark:bg-surface-700">
                        <tr>
                          <th className="text-left px-3 py-2 text-slate-500 dark:text-gray-400 font-semibold w-12">WBS</th>
                          <th className="text-left px-3 py-2 text-slate-500 dark:text-gray-400 font-semibold">Tarea / Hito</th>
                          <th className="text-left px-3 py-2 text-slate-500 dark:text-gray-400 font-semibold w-24">Fecha fin</th>
                          <th className="text-right px-3 py-2 text-slate-500 dark:text-gray-400 font-semibold w-16">Horas</th>
                          <th className="text-left px-3 py-2 text-slate-500 dark:text-gray-400 font-semibold w-20">Prioridad</th>
                        </tr>
                      </thead>
                      <tbody className="divide-y divide-slate-100 dark:divide-surface-700">
                        {(plan.phases[activePhase].tasks || []).map((t, j) => (
                          <tr key={j} className="hover:bg-slate-50 dark:hover:bg-surface-700/50">
                            <td className="px-3 py-2 font-mono text-slate-400">{t.wbsCode}</td>
                            <td className="px-3 py-2">
                              <span className={t.isCritical ? 'text-red-600 dark:text-red-400 font-medium' : 'text-slate-700 dark:text-gray-300'}>
                                {t.title}
                              </span>
                              {t.isCritical && <span className="ml-1.5 text-red-400 text-xs">★</span>}
                            </td>
                            <td className="px-3 py-2 text-slate-500 dark:text-gray-400">{t.dueDate || '—'}</td>
                            <td className="px-3 py-2 text-right text-slate-600 dark:text-gray-300">{t.estimatedHours}h</td>
                            <td className="px-3 py-2">
                              <PriorityBadge p={t.priority}/>
                            </td>
                          </tr>
                        ))}
                        {plan.phases[activePhase].milestone && (
                          <tr className="bg-violet-50 dark:bg-violet-500/5">
                            <td className="px-3 py-2 font-mono text-violet-400">{plan.phases[activePhase].milestone.wbsCode}</td>
                            <td className="px-3 py-2 font-semibold text-violet-700 dark:text-violet-400" colSpan={3}>
                              {plan.phases[activePhase].milestone.title}
                            </td>
                            <td className="px-3 py-2 text-violet-500 text-xs font-bold">HITO</td>
                          </tr>
                        )}
                      </tbody>
                    </table>
                  </div>
                )}
              </div>

              {/* Riesgos */}
              {plan.risks?.length > 0 && (
                <div className="bg-amber-50 dark:bg-amber-500/10 border border-amber-200 dark:border-amber-500/20 rounded-xl p-4">
                  <p className="text-xs font-bold text-amber-600 dark:text-amber-400 uppercase tracking-widest mb-2">
                    Riesgos identificados ({plan.risks.length})
                  </p>
                  <div className="grid grid-cols-2 gap-2">
                    {plan.risks.map((r, i) => (
                      <div key={i} className="flex items-start gap-2 text-xs text-amber-700 dark:text-amber-300">
                        <span className="mt-0.5 w-1.5 h-1.5 rounded-full bg-amber-400 flex-shrink-0"/>
                        <span>{r.title || r}</span>
                      </div>
                    ))}
                  </div>
                </div>
              )}

              {/* Nota */}
              <p className="text-xs text-slate-400 dark:text-gray-500 text-center">
                ★ = Tarea en ruta crítica · Las tareas se crean en estado <strong>PENDIENTE</strong> listas para asignar
              </p>
            </div>
          )}
        </div>

        {/* Footer */}
        {step === 'preview' && (
          <div className="flex items-center justify-between px-6 py-4 border-t border-slate-200 dark:border-surface-700 flex-shrink-0">
            <button onClick={() => setStep('upload')}
              className="px-4 py-2 text-sm font-medium rounded-xl border border-slate-200 dark:border-surface-600 text-slate-600 dark:text-gray-300 hover:bg-slate-50 dark:hover:bg-surface-700 transition cursor-pointer">
              Cambiar archivo
            </button>
            <button onClick={handleImport}
              className="px-6 py-2.5 text-sm font-semibold rounded-xl bg-violet-600 hover:bg-violet-700 text-white shadow-sm transition cursor-pointer flex items-center gap-2">
              <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
                <path strokeLinecap="round" strokeLinejoin="round" d="M5 13l4 4L19 7"/>
              </svg>
              Crear proyecto + {totalTasks} tareas + {totalMilestones} hitos
            </button>
          </div>
        )}
      </div>
    </div>
  );
}

function PriorityBadge({ p }) {
  const map = {
    CRITICO: 'bg-red-100 text-red-700 dark:bg-red-500/20 dark:text-red-400',
    ALTO:    'bg-orange-100 text-orange-700 dark:bg-orange-500/20 dark:text-orange-400',
    MEDIO:   'bg-amber-100 text-amber-700 dark:bg-amber-500/20 dark:text-amber-400',
    BAJO:    'bg-slate-100 text-slate-600 dark:bg-surface-600 dark:text-gray-400',
  };
  return <span className={`px-2 py-0.5 rounded-md font-semibold text-xs ${map[p] || map.MEDIO}`}>{p}</span>;
}
