// ===== CONTEXTO DE IDIOMA =====
const { createContext, useContext } = React;
window.LangContext = createContext();
window.useLang = () => useContext(window.LangContext) || { lang: 'es', setLang: () => {} };

// ===== SUGERENCIAS DE ENTIDADES POR DOMINIO =====
window.suggestedEntities = {
  salud: ['Seguro médico', 'Receta', 'Especialidad', 'Historial clínico', 'Diagnóstico'],
  ecommerce: ['Inventario', 'Proveedor', 'Factura', 'Método de pago', 'Carrito'],
  educacion: ['Tarea', 'Certificado', 'Profesor', 'Aula virtual', 'Calificación'],
  finanzas: ['Cuenta bancaria', 'Transacción', 'Reporte crediticio', 'Préstamo'],
  logistica: ['Almacén', 'Transportista', 'Guía de envío', 'Ruta'],
  rrhh: ['Contrato', 'Nómina', 'Evaluación de desempeño', 'Beneficio'],
  legal: ['Firma digital', 'Expediente', 'Cláusula', 'Testigo'],
  agricultura: ['Insumo agrícola', 'Estación meteorológica', 'Plaga', 'Cosecha'],
  transporte: ['Mantenimiento', 'Conductor', 'Ruta', 'Carga', 'Vehículo'],
  entretenimiento: ['Catálogo', 'Suscriptor', 'Anuncio', 'Perfil de usuario'],
  seguros: ['Cobertura', 'Siniestro', 'Ajustador', 'Prima'],
  manufactura: ['Orden de producción', 'Máquina', 'Defecto', 'Proveedor de materia prima'],
  turismo: ['Paquete turístico', 'Transporte', 'Alojamiento', 'Guía turístico'],
  inmobiliaria: ['Contrato de arriendo', 'Mantenimiento', 'Propietario', 'Agente inmobiliario'],
  saas: ['Módulo', 'API key', 'Límite de uso', 'Soporte', 'Suscripción'],
  adicciones: ['Gatillante', 'Protocolo de Crisis', 'Contacto de Confianza', 'Bitácora de Recaídas'],
  bienestar: ['Métrica de Bienestar', 'Red de Apoyo', 'Micro-intervención', 'Registro Emocional'],
  social: ['Miembro', 'Asamblea', 'Propuesta', 'Votación'],
  ambiental: ['Residuo', 'Punto de Reciclaje', 'Métrica Ambiental', 'Certificación'],
  gov: ['Trámite', 'Ciudadano', 'Consulta Pública', 'Expediente'],
  tech: ['Microservicio', 'Contenedor', 'API', 'Pipeline CI/CD'],
  seguridad: ['Incidente', 'Patrulla', 'Alerta', 'Reporte'],
  vivienda: ['Unidad Habitacional', 'Solicitante', 'Contrato', 'Inspección'],
  alimentacion: ['Alimento', 'Donante', 'Comedor', 'Beneficiario'],
  empleo: ['Candidato', 'Vacante', 'Habilidad', 'Entrevista'],
  migracion: ['Migrante', 'Documento', 'Servicio', 'Evaluación'],
  discapacidad: ['Barrera', 'Adaptación', 'Certificación', 'Asistencia'],
  juventud: ['Joven', 'Programa', 'Mentor', 'Actividad'],
  tercera_edad: ['Adulto Mayor', 'Cuidador', 'Turno', 'Alerta'],
  genero: ['Víctima', 'Protocolo', 'Refugio', 'Denuncia'],
  infancia: ['Niño', 'Reporte', 'Intervención', 'Seguimiento'],
  cultura: ['Patrimonio', 'Archivo Digital', 'Artista', 'Evento'],
  deporte: ['Equipo', 'Partido', 'Liga', 'Jugador'],
  innovacion: ['Startup', 'Mentor', 'MVP', 'Inversor'],
  energia: ['Panel Solar', 'Consumo', 'Crédito', 'Red'],
  agua: ['Medidor', 'Fuga', 'Consumo', 'Reporte'],
  salud_publica: ['Caso', 'Contacto', 'Cuarentena', 'Brote'],
  criminalidad: ['Ofensor', 'Víctima', 'Mediación', 'Acuerdo'],
  corrupcion: ['Dataset', 'API Pública', 'Reporte', 'Auditoría'],
  general: ['Notificación', 'Configuración', 'Registro de auditoría', 'Usuario']
};

// ===== TOASTS =====
window.Toasts = ({ items }) => {
  if (!items || !items.length) return null;
  return (
    <div className="fixed top-20 right-4 z-50 space-y-2">
      {items.map(item => (
        <div key={item.id} className={`flex items-center gap-2 px-4 py-2 rounded-xl text-sm fi ${item.type==='success'?'bg-green-900/80 text-green-200 border border-green-600/30':'bg-slate-800/90 text-slate-200 border border-slate-600/30'}`}>
          {item.type==='success'?<window.IconCheck/>:<window.IconAlert/>}
          {item.msg}
        </div>
      ))}
    </div>
  );
};

// ===== NAV =====
window.Nav = ({ page, setPage }) => {
  const { lang, setLang } = window.useLang();
  const tt = window.useT();
  return (
    <nav className="fixed top-0 left-0 right-0 z-50 bg-[#0a0a1a]/90 backdrop-blur-md border-b border-white/5">
      <div className="max-w-7xl mx-auto px-4 flex items-center justify-between h-14">
        <div className="flex items-center gap-6">
          <button onClick={() => setPage('home')} className="flex items-center gap-2">
            <div className="w-8 h-8 rounded-lg bg-gradient-to-br from-indigo-500 to-purple-600 flex items-center justify-center"><window.IconBrain/></div>
            <span className="text-lg font-bold bg-gradient-to-r from-indigo-300 to-purple-300 bg-clip-text text-transparent">ALMA</span>
          </button>
          <div className="hidden md:flex items-center gap-1">
            {[{ id:'home', label:tt('nav.home') },{ id:'dashboard', label:tt('nav.dashboard') },{ id:'docs', label:tt('nav.docs') }].map(it => (
              <button key={it.id} onClick={() => setPage(it.id)} className={`px-3 py-1.5 rounded-lg text-sm ${page===it.id?'bg-white/10 text-white':'text-slate-500 hover:text-slate-300'}`}>{it.label}</button>
            ))}
          </div>
        </div>
        <div className="flex items-center gap-2 text-sm text-slate-400">
          <button onClick={() => setLang(lang==='es'?'en':'es')} className="flex items-center gap-1.5 px-2.5 py-1.5 rounded-lg bg-white/5 hover:bg-white/10 transition-colors border border-white/10" title={lang==='es'?'Switch to English':'Cambiar a Español'}><window.IconGlobe/><span className="text-xs font-mono text-indigo-300">{lang==='es'?'ES → EN':'EN → ES'}</span></button>
          <div className="w-7 h-7 rounded-full bg-gradient-to-br from-indigo-500 to-purple-600 flex items-center justify-center text-xs font-bold text-white">A</div> admin
        </div>
      </div>
    </nav>
  );
};

// ===== HOME =====
window.Home = ({ onStart }) => {
  const { lang } = window.useLang();
  const tt = window.useT();
  const [idea, setIdea] = React.useState('');
  const [mode, setMode] = React.useState('estandar');
  const [domain, setDomain] = React.useState('general');
  const modes = [{ id: 'rapido', label: tt('home.modes.rapido') }, { id: 'estandar', label: tt('home.modes.estandar') }, { id: 'forense', label: tt('home.modes.forense') }];
  const domains = Object.keys(tt('home.domains')).map(k => ({ id: k, label: tt('home.domains.' + k) }));
  const examplesList = tt('home.examples');
  const detectedDomain = React.useMemo(() => idea.trim() ? window.detectDomainFromIdea(idea) : 'general', [idea]);

  return (
    <div className="min-h-screen pt-20 pb-12 px-4 fi flex items-center justify-center">
      <div className="w-full max-w-3xl">
        <div className="text-center mb-8 su">
          <h1 className="text-4xl sm:text-5xl font-bold mb-3"><span className="bg-gradient-to-r from-indigo-200 via-purple-200 to-pink-200 bg-clip-text text-transparent">{tt('home.title1')}</span><br/><span className="bg-gradient-to-r from-indigo-400 via-purple-400 to-pink-400 bg-clip-text text-transparent">{tt('home.title2')}</span></h1>
          <p className="text-slate-400 text-base max-w-lg mx-auto">{tt('home.subtitle')}</p>
        </div>
        <div className="bg-white/[.03] border border-white/5 rounded-2xl p-6 sm:p-8 mb-6">
          <textarea value={idea} onChange={e => setIdea(e.target.value)} placeholder={tt('home.placeholder')} className="w-full h-32 bg-white/5 border border-white/10 rounded-xl px-4 py-3 text-sm text-white placeholder-slate-600 focus:outline-none focus:ring-2 focus:ring-indigo-500/50 resize-none leading-relaxed"/>
          <div className="mt-2 mb-4">
            <p className="text-xs text-slate-600 mb-2">{tt('home.examplesLabel')}</p>
            <div className="flex flex-wrap gap-2 max-h-32 overflow-y-auto pr-1">{examplesList.map((ex, i) => (<button key={i} onClick={() => setIdea(ex)} className="text-xs text-slate-500 hover:text-indigo-300 bg-white/5 hover:bg-indigo-500/10 px-3 py-1 rounded-lg transition-colors truncate max-w-[200px]">{ex.substring(0,40)}...</button>))}</div>
          </div>
          <div className="grid grid-cols-2 gap-3 mb-6">
            <div><label className="block text-xs text-slate-500 mb-1 uppercase">{tt('home.modeLabel')}</label><select value={mode} onChange={e => setMode(e.target.value)} className="w-full bg-white/5 border border-white/10 rounded-xl px-3 py-2.5 text-sm text-white focus:outline-none">{modes.map(m => <option key={m.id} value={m.id}>{m.label}</option>)}</select></div>
            <div><label className="block text-xs text-slate-500 mb-1 uppercase">{tt('home.domainLabel')}</label><select value={domain} onChange={e => setDomain(e.target.value)} className="w-full bg-white/5 border border-white/10 rounded-xl px-3 py-2.5 text-sm text-white focus:outline-none capitalize">{domains.map(d => <option key={d.id} value={d.id}>{d.label}</option>)}</select>{detectedDomain!=='general' && domain==='general' && (<p className="text-xs text-indigo-400 mt-1">Sugerido: {tt('home.domains.'+detectedDomain)||detectedDomain}</p>)}</div>
          </div>
          <button onClick={() => idea.trim() && onStart(idea, mode, domain)} disabled={!idea.trim()} className={`w-full flex items-center justify-center gap-2 px-6 py-3 rounded-xl text-sm font-semibold transition-all ${idea.trim() ? 'bg-gradient-to-r from-indigo-600 to-purple-600 hover:from-indigo-500 hover:to-purple-500 text-white' : 'bg-white/5 text-slate-600 cursor-not-allowed'}`}><window.IconPlay/> {tt('home.startBtn')}</button>
        </div>
      </div>
    </div>
  );
};

// ===== EXTRACTION =====
window.Extraction = ({ idea, domain, onComplete, onBack, initialData }) => {
  const { lang } = window.useLang();
  const tt = window.useT();
  const isEn = lang === 'en';
  const [currentStep, setCurrentStep] = React.useState(0);
  const [typing, setTyping] = React.useState('');
  const [conf, setConf] = React.useState(initialData?.confidence || 0);
  const [result, setResult] = React.useState(initialData || null);
  const [manualEntities, setManualEntities] = React.useState([]);
  const [newEntityInput, setNewEntityInput] = React.useState('');
  const [newEntityType, setNewEntityType] = React.useState('resource');
  const [resolvedBrechas, setResolvedBrechas] = React.useState({});
  const [breachResolutionChosen, setBreachResolutionChosen] = React.useState({});
  const timerRef = React.useRef(null);
  const isDone = result !== null;

  // Si ya hay datos iniciales (de la IA), usarlos directamente
  React.useEffect(() => {
    if (initialData && !result) {
      setResult(initialData);
      setConf(initialData.confidence || 0);
    }
  }, [initialData]);

  const extractionData = React.useMemo(() => {
    if (!idea) return null;
    const lo = idea.toLowerCase();
    const ents = [], wfs = [], rls = [], brs = [];

    const solutionPatterns = {
      adhd_focus_system: {
        match: /tdah|distra[cc]i[oó]n|enfoque|procrastin|fragment.*tarea|bloqu.*distracci|pomodoro|recordatori.*15|minuto.*tarea/,
        entities: [
          { id: 'e1', label: isEn ? 'User' : 'Usuario', type: 'actor' },
          { id: 'e2', label: isEn ? 'LargeProject' : 'Proyecto Grande', type: 'resource' },
          { id: 'e3', label: isEn ? 'MicroTask (<15min)' : 'MicroTarea (<15min)', type: 'resource' },
          { id: 'e4', label: isEn ? 'FocusSession' : 'Sesión de Enfoque', type: 'process' },
          { id: 'e5', label: isEn ? 'DistractionBlocker' : 'Bloqueador de Distracciones', type: 'resource' },
          { id: 'e6', label: isEn ? 'CognitiveProfile' : 'Perfil Cognitivo', type: 'data' }
        ],
        workflows: [
          { id: 'w1', name: isEn ? 'AutomaticFragmentation' : 'Fragmentación Automática' },
          { id: 'w2', name: isEn ? 'AdaptivePomodoroCycle' : 'Ciclo Pomodoro Adaptativo' },
          { id: 'w3', name: isEn ? 'DriftIntervention' : 'Intervención de Deriva' }
        ],
        rules: [
          { id: 'r1', text: isEn ? 'MicroTask CANNOT exceed 20 min estimated duration' : 'MicroTarea NO puede exceder 20 min estimados', sev: 'critical' },
          { id: 'r2', text: isEn ? 'DistractionBlocker ONLY deactivates after completing MicroTask OR verified emergency' : 'Bloqueador SOLO se desactiva tras completar MicroTarea O emergencia verificada', sev: 'critical' },
          { id: 'r3', text: isEn ? 'Notifications must be non-intrusive but persistent until confirmation' : 'Notificaciones deben ser no intrusivas pero persistentes hasta confirmación', sev: 'high' }
        ],
        brechas: [
          { id: 'b1', text: isEn ? 'Offline mode policy for blocker not defined' : 'Política de modo offline para bloqueador no definida', sev: 'high' },
          { id: 'b2', text: isEn ? 'False positive detection of distraction not addressed' : 'Detección falsa positiva de distracción no abordada', sev: 'medium' }
        ]
      },
      gambling_addiction_interceptor: {
        match: /casino|apuesta|juego|adicc[ió]n|dopamina|reca[ií]da|bloqu.*dinero|autoexclusi[oó]n|transacci[oó]n.*casino|merchant.*juego/,
        entities: [
          { id: 'e1', label: isEn ? 'Patient' : 'Paciente', type: 'actor' },
          { id: 'e2', label: isEn ? 'TrustedContact' : 'Contacto de Confianza', type: 'actor' },
          { id: 'e3', label: isEn ? 'FinancialBarrier' : 'Barrera Financiera', type: 'resource' },
          { id: 'e4', label: isEn ? 'TransactionRecord' : 'Registro de Transacción', type: 'data' },
          { id: 'e5', label: isEn ? 'DopamineSimulator' : 'Simulador de Dopamina', type: 'resource' },
          { id: 'e6', label: isEn ? 'RiskState' : 'Estado de Riesgo', type: 'data' },
          { id: 'e7', label: isEn ? 'BehavioralTrigger' : 'Trigger Conductual', type: 'data' }
        ],
        workflows: [
          { id: 'w1', name: isEn ? 'HighRiskTransactionInterception' : 'Intercepción de Transacción de Alto Riesgo' },
          { id: 'w2', name: isEn ? 'AcuteCrisisProtocol' : 'Protocolo de Crisis Aguda' },
          { id: 'w3', name: isEn ? 'ControlledExposureTherapy' : 'Terapia de Exposición Controlada' }
        ],
        rules: [
          { id: 'r1', text: isEn ? 'Patient CANNOT self-disable FinancialBarrier without TrustedContact approval' : 'Paciente NO puede auto-desactivar Barrera Financiera sin aprobación de Contacto de Confianza', sev: 'critical' },
          { id: 'r2', text: isEn ? 'ALL transactions to gambling merchants require explicit external approval (Human Double Factor)' : 'TODA transacción a casinos requiere aprobación externa explícita (Doble Factor Humano)', sev: 'critical' },
          { id: 'r3', text: isEn ? 'DopamineSimulator MUST have algorithms designed to REDUCE excitement, NOT increase it' : 'Simulador DEBE tener algoritmos para REDUCIR excitación, NO aumentarla', sev: 'critical' }
        ],
        brechas: [
          { id: 'b1', text: isEn ? 'Elusion methods (VPN, crypto, cash) not specified' : 'Métodos de elusión (VPN, cripto, efectivo) no especificados', sev: 'critical' },
          { id: 'b2', text: isEn ? 'Alert fatigue in trusted contacts not addressed' : 'Fatiga de alertas en contactos no abordada', sev: 'high' },
          { id: 'b3', text: isEn ? 'Emergency fund access during genuine crisis not defined' : 'Acceso a fondos de emergencia durante crisis genuina no definido', sev: 'high' }
        ]
      },
      compulsive_shopping_blocker: {
        match: /compras.*compulsivas|compulsive.*shopping|ansiedad.*comprar|gasto.*impulsivo|barrera.*financiera|terapeuta.*aprobaci[oó]n.*compra/,
        entities: [
          { id: 'e1', label: isEn ? 'User' : 'Usuario', type: 'actor' },
          { id: 'e2', label: isEn ? 'Therapist' : 'Terapeuta', type: 'actor' },
          { id: 'e3', label: isEn ? 'PurchaseRequest' : 'Solicitud de Compra', type: 'process' },
          { id: 'e4', label: isEn ? 'SpendingLimit' : 'Límite de Gasto', type: 'resource' },
          { id: 'e5', label: isEn ? 'AnxietyMetric' : 'Métrica de Ansiedad', type: 'data' }
        ],
        workflows: [
          { id: 'w1', name: isEn ? 'TherapistApprovalFlow' : 'Flujo de Aprobación Terapéutica' },
          { id: 'w2', name: isEn ? 'AnxietyCorrelatedSpendingControl' : 'Control de Gasto Correlacionado con Ansiedad' }
        ],
        rules: [
          { id: 'r1', text: isEn ? 'Purchases over limit require therapist approval within 24h' : 'Compras sobre límite requieren aprobación del terapeuta en 24h', sev: 'critical' },
          { id: 'r2', text: isEn ? 'System must detect anxiety spikes and delay purchases automatically' : 'Sistema debe detectar picos de ansiedad y retrasar compras automáticamente', sev: 'high' }
        ],
        brechas: [
          { id: 'b1', text: isEn ? 'Therapist availability 24/7 not guaranteed' : 'Disponibilidad del terapeuta 24/7 no garantizada', sev: 'high' },
          { id: 'b2', text: isEn ? 'Emergency purchase definition missing' : 'Definición de compra de emergencia faltante', sev: 'medium' }
        ]
      },
      caregiver_burnout_prevention: {
        match: /cuidador|caregiver|alzheimer|burnout|turnos.*familiares|relevo|desgaste|agotamiento/,
        entities: [
          { id: 'e1', label: isEn ? 'Caregiver' : 'Cuidador', type: 'actor' },
          { id: 'e2', label: isEn ? 'Patient' : 'Paciente', type: 'actor' },
          { id: 'e3', label: isEn ? 'FamilyMember' : 'Familiar', type: 'actor' },
          { id: 'e4', label: isEn ? 'ShiftSchedule' : 'Turno Programado', type: 'resource' },
          { id: 'e5', label: isEn ? 'StressIndicator' : 'Indicador de Estrés', type: 'data' },
          { id: 'e6', label: isEn ? 'RespitePlan' : 'Plan de Respiro', type: 'process' }
        ],
        workflows: [
          { id: 'w1', name: isEn ? 'ShiftCoordination' : 'Coordinación de Turnos' },
          { id: 'w2', name: isEn ? 'EarlyBurnoutDetection' : 'Detección Temprana de Burnout' },
          { id: 'w3', name: isEn ? 'EmergencyRespiteActivation' : 'Activación de Respiro de Emergencia' }
        ],
        rules: [
          { id: 'r1', text: isEn ? 'No caregiver shall exceed 16 continuous hours without relief' : 'Ningún cuidador excederá 16 horas continuas sin relevo', sev: 'critical' },
          { id: 'r2', text: isEn ? 'Stress indicators above threshold must trigger respite within 2h' : 'Indicadores de estrés sobre umbral deben activar respiro en 2h', sev: 'high' }
        ],
        brechas: [
          { id: 'b1', text: isEn ? 'Family member unavailability not handled' : 'Indisponibilidad de familiares no manejada', sev: 'high' },
          { id: 'b2', text: isEn ? 'Professional backup caregiver integration missing' : 'Integración con cuidadores profesionales de respaldo faltante', sev: 'medium' }
        ]
      },
      isolation_detection_system: {
        match: /aislamiento|isolation|depresi[oó]n.*social|sin.*mensajes|sin.*salir|micro.interacciones|reconexi[oó]n.*social/,
        entities: [
          { id: 'e1', label: isEn ? 'User' : 'Usuario', type: 'actor' },
          { id: 'e2', label: isEn ? 'SafePerson' : 'Persona Segura', type: 'actor' },
          { id: 'e3', label: isEn ? 'IsolationMetric' : 'Métrica de Aislamiento', type: 'data' },
          { id: 'e4', label: isEn ? 'MicroInteraction' : 'Micro-Interacción', type: 'process' },
          { id: 'e5', label: isEn ? 'ActivityLog' : 'Registro de Actividad', type: 'data' }
        ],
        workflows: [
          { id: 'w1', name: isEn ? 'IsolationPatternDetection' : 'Detección de Patrones de Aislamiento' },
          { id: 'w2', name: isEn ? 'GradualReconnectionProtocol' : 'Protocolo de Reconexión Gradual' }
        ],
        rules: [
          { id: 'r1', text: isEn ? 'User must explicitly consent to activity monitoring' : 'Usuario debe consentir explícitamente monitoreo de actividad', sev: 'critical' },
          { id: 'r2', text: isEn ? 'No more than 3 micro-interactions per day to avoid overwhelm' : 'No más de 3 micro-interacciones diarias para evitar abrumar', sev: 'high' }
        ],
        brechas: [
          { id: 'b1', text: isEn ? 'Privacy boundary definition between monitoring and intrusion' : 'Definición de límite entre monitoreo e intrusión', sev: 'high' },
          { id: 'b2', text: isEn ? 'Safe person rejection or unavailability not handled' : 'Rechazo o indisponibilidad de persona segura no manejado', sev: 'medium' }
        ]
      },
      domestic_violence_escape: {
        match: /violencia.*dom[eé]stica|domestic.*violence|plan.*escape|escape.*digital|alerta.*silenciosa|bot[oó]n.*p[aá]nico|refugio.*seguro/,
        entities: [
          { id: 'e1', label: isEn ? 'Survivor' : 'Sobreviviente', type: 'actor' },
          { id: 'e2', label: isEn ? 'SupportNetwork' : 'Red de Apoyo', type: 'actor' },
          { id: 'e3', label: isEn ? 'SafeRoute' : 'Ruta Segura', type: 'resource' },
          { id: 'e4', label: isEn ? 'EncryptedDocuments' : 'Documentos Encriptados', type: 'resource' },
          { id: 'e5', label: isEn ? 'SilentAlert' : 'Alerta Silenciosa', type: 'process' },
          { id: 'e6', label: isEn ? 'SafeShelter' : 'Refugio Seguro', type: 'resource' }
        ],
        workflows: [
          { id: 'w1', name: isEn ? 'SilentAlertActivation' : 'Activación de Alerta Silenciosa' },
          { id: 'w2', name: isEn ? 'SafeRouteCalculation' : 'Cálculo de Ruta Segura' },
          { id: 'w3', name: isEn ? 'EmergencyDocumentRelease' : 'Liberación de Documentos de Emergencia' }
        ],
        rules: [
          { id: 'r1', text: isEn ? 'SilentAlert MUST NOT produce any visible notification on device' : 'Alerta Silenciosa NO DEBE producir notificación visible en el dispositivo', sev: 'critical' },
          { id: 'r2', text: isEn ? 'Encrypted documents accessible ONLY with dual-factor emergency verification' : 'Documentos encriptados accesibles SOLO con verificación de emergencia de doble factor', sev: 'critical' }
        ],
        brechas: [
          { id: 'b1', text: isEn ? 'Network failure during alert not addressed' : 'Falla de red durante alerta no abordada', sev: 'critical' },
          { id: 'b2', text: isEn ? 'Device confiscation scenario not handled' : 'Escenario de confiscación de dispositivo no manejado', sev: 'critical' }
        ]
      }
    };

    let matched = false;
    for (const [key, pattern] of Object.entries(solutionPatterns)) {
      if (pattern.match && pattern.match.test(lo)) {
        ents.push(...pattern.entities);
        wfs.push(...pattern.workflows);
        rls.push(...pattern.rules);
        brs.push(...pattern.brechas);
        matched = true;
        break;
      }
    }

    if (!matched) {
      const matchKw = (kws) => kws.some(k => lo.includes(k));
      if (domain === 'salud' || matchKw(isEn ? ['patient', 'doctor', 'appointment', 'medical', 'therapy', 'therapist'] : ['paciente', 'doctor', 'cita', 'médica', 'terapia', 'terapeuta'])) {
        ents.push({ id: 'e1', label: isEn ? 'Patient' : 'Paciente', type: 'actor' }, { id: 'e2', label: isEn ? 'Doctor' : 'Doctor', type: 'actor' }, { id: 'e3', label: isEn ? 'Appointment' : 'Cita', type: 'resource' }, { id: 'e4', label: isEn ? 'Medical History' : 'Historial', type: 'data' });
        wfs.push({ id: 'w1', name: isEn ? 'BookAppointment' : 'AgendarCita' }, { id: 'w2', name: isEn ? 'ConfirmAppointment' : 'ConfirmarCita' });
        rls.push({ id: 'r1', text: isEn ? 'Patient must have active insurance' : 'Paciente debe tener seguro activo', sev: 'critical' });
        brs.push({ id: 'b1', text: isEn ? 'Cancellation policy not specified' : 'No se especifica política de cancelación', sev: 'high' });
      } else if (domain === 'ecommerce' || matchKw(isEn ? ['cart', 'product', 'store', 'shop', 'checkout'] : ['carrito', 'producto', 'tienda', 'compras', 'checkout'])) {
        ents.push({ id: 'e1', label: isEn ? 'Customer' : 'Cliente', type: 'actor' }, { id: 'e2', label: isEn ? 'Product' : 'Producto', type: 'resource' }, { id: 'e3', label: isEn ? 'Cart' : 'Carrito', type: 'resource' }, { id: 'e4', label: isEn ? 'Order' : 'Orden', type: 'resource' });
        wfs.push({ id: 'w1', name: isEn ? 'Purchase' : 'Comprar' }, { id: 'w2', name: isEn ? 'ManageInventory' : 'Gestionar Inventario' });
        rls.push({ id: 'r1', text: isEn ? 'Do not sell without stock' : 'No vender sin stock', sev: 'critical' });
        brs.push({ id: 'b1', text: isEn ? 'Returns not specified' : 'No se especifica devoluciones', sev: 'medium' });
      } else if (domain === 'educacion' || matchKw(isEn ? ['course', 'student', 'education', 'learn', 'class'] : ['curso', 'estudiante', 'educación', 'aprendizaje', 'clase'])) {
        ents.push({ id: 'e1', label: isEn ? 'Student' : 'Estudiante', type: 'actor' }, { id: 'e2', label: isEn ? 'Course' : 'Curso', type: 'resource' }, { id: 'e3', label: isEn ? 'Assessment' : 'Evaluación', type: 'resource' }, { id: 'e4', label: isEn ? 'Progress' : 'Progreso', type: 'data' });
        wfs.push({ id: 'w1', name: isEn ? 'CompleteCourse' : 'Completar Curso' });
        rls.push({ id: 'r1', text: isEn ? 'Assessment after completing lessons' : 'Evaluación tras completar lecciones', sev: 'critical' });
        brs.push({ id: 'b1', text: isEn ? 'Retries not specified' : 'No se especifican reintentos', sev: 'low' });
      } else if (domain === 'finanzas' || matchKw(isEn ? ['loan', 'credit', 'finance', 'bank', 'invest'] : ['préstamo', 'crédito', 'finanzas', 'banco', 'inversión'])) {
        ents.push({ id: 'e1', label: isEn ? 'Customer' : 'Cliente', type: 'actor' }, { id: 'e2', label: isEn ? 'Financial Product' : 'Producto Financiero', type: 'resource' }, { id: 'e3', label: isEn ? 'Credit Assessment' : 'Evaluación Crediticia', type: 'process' });
        wfs.push({ id: 'w1', name: isEn ? 'RequestProduct' : 'Solicitar Producto' });
        rls.push({ id: 'r1', text: isEn ? 'Comply with KYC/AML regulations' : 'Cumplir regulación KYC/AML', sev: 'critical' });
        brs.push({ id: 'b1', text: isEn ? 'Minimum score not specified' : 'No se especifica score mínimo', sev: 'high' });
      } else if (domain === 'logistica' || matchKw(isEn ? ['delivery', 'gps', 'shipping', 'tracking'] : ['entrega', 'gps', 'envío', 'seguimiento'])) {
        ents.push({ id: 'e1', label: isEn ? 'Customer' : 'Cliente', type: 'actor' }, { id: 'e2', label: isEn ? 'Package' : 'Paquete', type: 'resource' }, { id: 'e3', label: isEn ? 'Driver' : 'Repartidor', type: 'actor' }, { id: 'e4', label: isEn ? 'Route' : 'Ruta', type: 'data' });
        wfs.push({ id: 'w1', name: isEn ? 'DeliverPackage' : 'Entregar Paquete' });
        rls.push({ id: 'r1', text: isEn ? 'Verify identity on delivery' : 'Verificar identidad al entregar', sev: 'critical' });
        brs.push({ id: 'b1', text: isEn ? 'Failed deliveries not specified' : 'No se especifica entregas fallidas', sev: 'high' });
      } else if (domain === 'adicciones' || matchKw(isEn ? ['addiction', 'casino', 'gambling', 'relapse', 'dopamine', 'blocker', 'intervention'] : ['adicción', 'casino', 'juego', 'apuesta', 'recaída', 'dopamina', 'bloqueo', 'intervención', 'trampa'])) {
        ents.push({ id: 'e1', label: isEn ? 'Patient' : 'Paciente', type: 'actor' }, { id: 'e2', label: isEn ? 'Trusted Contact' : 'Contacto de Confianza', type: 'actor' }, { id: 'e3', label: isEn ? 'Intervention Protocol' : 'Protocolo de Intervención', type: 'process' }, { id: 'e4', label: isEn ? 'Behavioral Trigger' : 'Trigger Conductual', type: 'data' }, { id: 'e5', label: isEn ? 'Financial Barrier' : 'Barrera Financiera', type: 'resource' }, { id: 'e6', label: isEn ? 'Risk State' : 'Estado de Riesgo', type: 'data' });
        wfs.push({ id: 'w1', name: isEn ? 'RelapseInterception' : 'Intercepción de Recaída' }, { id: 'w2', name: isEn ? 'EmergencyProtocolActivation' : 'Activación de Protocolo de Emergencia' }, { id: 'w3', name: isEn ? 'DopamineReductionSimulation' : 'Simulación de Reducción de Dopamina' });
        rls.push({ id: 'r1', text: isEn ? 'Patient cannot self-disable barriers during crisis' : 'Paciente no puede auto-desactivar barreras durante crisis', sev: 'critical' }, { id: 'r2', text: isEn ? 'Trusted contact approval required for high-risk transactions' : 'Aprobación de contacto requerida para transacciones de alto riesgo', sev: 'critical' });
        brs.push({ id: 'b1', text: isEn ? 'Elusion methods not specified' : 'Métodos de elusión no especificados', sev: 'critical' }, { id: 'b2', text: isEn ? 'Alert fatigue in trusted contacts not addressed' : 'Fatiga de alertas en contactos no abordada', sev: 'high' });
      } else if (domain === 'bienestar' || matchKw(isEn ? ['wellness', 'burnout', 'stress', 'anxiety', 'depression', 'isolation', 'mental health', 'caregiver'] : ['bienestar', 'burnout', 'estrés', 'ansiedad', 'depresión', 'aislamiento', 'salud mental', 'cuidador'])) {
        ents.push({ id: 'e1', label: isEn ? 'User' : 'Usuario', type: 'actor' }, { id: 'e2', label: isEn ? 'Support Network' : 'Red de Apoyo', type: 'actor' }, { id: 'e3', label: isEn ? 'Wellness Metric' : 'Métrica de Bienestar', type: 'data' }, { id: 'e4', label: isEn ? 'Micro-intervention' : 'Micro-intervención', type: 'process' }, { id: 'e5', label: isEn ? 'Crisis Mode' : 'Modo Crisis', type: 'process' });
        wfs.push({ id: 'w1', name: isEn ? 'EarlyWarningDetection' : 'Detección Temprana de Alerta' }, { id: 'w2', name: isEn ? 'GradualSocialReconnection' : 'Reconexión Social Gradual' }, { id: 'w3', name: isEn ? 'CaregiverShiftCoordination' : 'Coordinación de Turnos Cuidador' });
        rls.push({ id: 'r1', text: isEn ? 'Privacy must be preserved while enabling intervention' : 'Privacidad debe preservarse mientras se habilita intervención', sev: 'critical' });
        brs.push({ id: 'b1', text: isEn ? 'False positives in crisis detection not addressed' : 'Falsos positivos en detección de crisis no abordados', sev: 'high' });
      } else {
        ents.push({ id: 'e1', label: isEn ? 'User' : 'Usuario', type: 'actor' }, { id: 'e2', label: isEn ? 'Resource' : 'Recurso', type: 'resource' });
        wfs.push({ id: 'w1', name: isEn ? 'MainFlow' : 'Flujo Principal' });
        rls.push({ id: 'r1', text: isEn ? 'Validate user input' : 'Validar entrada de usuario', sev: 'warning' });
        brs.push({ id: 'b1', text: isEn ? 'Description too ambiguous - specify actors and business rules' : 'Descripción demasiado ambigua - especificar actores y reglas de negocio', sev: 'high' });
      }
    }
    return { entities: ents, workflows: wfs, rules: rls, brechas: brs, confidence: matched ? 88 + Math.floor(Math.random() * 10) : 65 + Math.floor(Math.random() * 25) };
  }, [idea, lang, domain]);

  const stepLabels = tt('extraction.steps');

  React.useEffect(() => {
    if (!idea || !extractionData || isDone) return;
    let cancelled = false;
    let idx = 0;
    const advance = () => {
      if (cancelled) return;
      if (idx >= stepLabels.length) { setResult(extractionData); setConf(extractionData.confidence); return; }
      setCurrentStep(idx);
      setTyping(stepLabels[idx] || '');
      idx++;
      timerRef.current = setTimeout(() => { if (!cancelled) advance(); }, 300 + idx * 60);
    };
    timerRef.current = setTimeout(() => { if (!cancelled) advance(); }, 100);
    return () => { cancelled = true; if (timerRef.current) clearTimeout(timerRef.current); };
  }, [idea, extractionData, isDone]);

  const handleAddEntity = () => {
    if (!newEntityInput.trim()) return;
    setManualEntities(prev => [...prev, { id: 'manual-' + Date.now(), label: newEntityInput, type: newEntityType }]);
    setNewEntityInput('');
  };

  const skipAnimation = () => {
    if (timerRef.current) clearTimeout(timerRef.current);
    setResult(extractionData);
    setConf(extractionData.confidence);
  };

  const getBreachResolutionOptions = (breach) => {
    const breachText = (breach.text || '').toLowerCase();
    const isElusion = breachText.includes('elusión') || breachText.includes('vpn') || breachText.includes('crypto') || breachText.includes('efectivo') || breachText.includes('elusion');
    const isFatiga = breachText.includes('fatiga') || breachText.includes('alertas') || breachText.includes('contactos') || breachText.includes('fatigue');
    const isEmergencia = breachText.includes('emergencia') || breachText.includes('fondos') || breachText.includes('crisis genuina') || breachText.includes('emergency');
    const isPrivacidad = breachText.includes('privacidad') || breachText.includes('datos') || breachText.includes('gdpr') || breachText.includes('hipaa') || breachText.includes('privacy');
    const isFalsoPositivo = breachText.includes('falso positivo') || breachText.includes('precisión') || breachText.includes('detectar') || breachText.includes('false positive');
    const isEscalado = breachText.includes('escalado') || breachText.includes('tiempo respuesta') || breachText.includes('demora') || breachText.includes('escalation');
    const isOffline = breachText.includes('offline') || breachText.includes('sin conexión') || breachText.includes('red') || breachText.includes('network');
    const isConfiscacion = breachText.includes('confiscación') || breachText.includes('confiscation') || breachText.includes('dispositivo');

    const allOptions = [];

    if (isElusion) {
      allOptions.push({ id: 'resolve_defense_depth', label: isEn ? 'Defense-in-Depth Protocol' : 'Protocolo de Defensa en Profundidad', details: isEn ? 'Multi-layer blocking: DNS filtering + browser extension + firewall rules + bank API integration. VPN detection via IP reputation databases.' : 'Bloqueo multi-capa: filtrado DNS + extensión navegador + reglas firewall + integración API bancaria. Detección VPN mediante bases de datos de reputación IP.' },
        { id: 'resolve_behavioral_analysis', label: isEn ? 'Behavioral Pattern Analysis' : 'Análisis de Patrones Conductuales', details: isEn ? 'ML model trained on relapse patterns: time of day, transaction velocity, navigation behavior. Anomaly detection triggers pre-emptive intervention.' : 'Modelo ML entrenado en patrones de recaída: hora del día, velocidad de transacciones, comportamiento de navegación. Detección de anomalías activa intervención preventiva.' },
        { id: 'resolve_human_verification', label: isEn ? 'Human Verification Escalation' : 'Escalado a Verificación Humana', details: isEn ? 'High-risk transactions require video call verification with trusted contact. Integration with Zoom/Twilio for real-time human intervention.' : 'Transacciones de alto riesgo requieren verificación por videollamada con contacto de confianza.' }
      );
    }
    if (isFatiga) {
      allOptions.push({ id: 'resolve_smart_rotation', label: isEn ? 'Intelligent Alert Rotation' : 'Rotación Inteligente de Alertas', details: isEn ? 'Algorithm distributes alerts across support network based on availability, timezone, and relationship strength. Max 2 alerts/week per contact.' : 'Algoritmo distribuye alertas en red de apoyo según disponibilidad, zona horaria y fortaleza de relación. Máximo 2 alertas/semana por contacto.' },
        { id: 'resolve_escalation_matrix', label: isEn ? 'Dynamic Escalation Matrix' : 'Matriz de Escalado Dinámico', details: isEn ? 'Tiered response: Level 1 (automated coping exercises) → Level 2 (peer support) → Level 3 (professional intervention). AI determines severity.' : 'Respuesta escalonada: Nivel 1 (ejercicios de afrontamiento automatizados) → Nivel 2 (apoyo entre pares) → Nivel 3 (intervención profesional).' },
        { id: 'resolve_contact_rest', label: isEn ? 'Contact Rest Periods' : 'Períodos de Descanso para Contactos', details: isEn ? 'Mandatory 48h rest period after each intervention. Backup contacts automatically activated. Burnout prevention dashboard for supporters.' : 'Período de descanso obligatorio de 48h después de cada intervención. Contactos de respaldo activados automáticamente.' }
      );
    }
    if (isEmergencia) {
      allOptions.push({ id: 'resolve_dual_key', label: isEn ? 'Dual-Key Emergency Access' : 'Acceso de Emergencia con Doble Llave', details: isEn ? 'Emergency funds accessible only with 2-of-3 approvals: patient + therapist + trusted contact. Time-locked withdrawals (24h delay).' : 'Fondos de emergencia accesibles solo con aprobación 2-de-3: paciente + terapeuta + contacto de confianza. Retiros con bloqueo temporal (24h de demora).' },
        { id: 'resolve_contextual_limits', label: isEn ? 'Context-Aware Spending Limits' : 'Límites de Gasto Conscientes del Contexto', details: isEn ? 'AI evaluates transaction context: medical emergency vs. gambling trigger. Allows genuine needs while blocking high-risk patterns.' : 'IA evalúa contexto de transacción: emergencia médica vs. trigger de juego. Permite necesidades genuinas mientras bloquea patrones de alto riesgo.' }
      );
    }
    if (isPrivacidad) {
      allOptions.push({ id: 'resolve_zero_knowledge', label: isEn ? 'Zero-Knowledge Architecture' : 'Arquitectura de Conocimiento Cero', details: isEn ? 'End-to-end encryption. Server cannot access sensitive data. Interventions triggered by client-side pattern matching without data transmission.' : 'Encriptación extremo a extremo. El servidor no puede acceder a datos sensibles. Intervenciones activadas por coincidencia de patrones en cliente sin transmisión de datos.' },
        { id: 'resolve_selective_disclosure', label: isEn ? 'Selective Disclosure Protocol' : 'Protocolo de Divulgación Selectiva', details: isEn ? 'Patient controls what information is shared with each actor. Granular permissions: contacts see alerts but not transaction details.' : 'Paciente controla qué información comparte con cada actor. Permisos granulares: contactos ven alertas pero no detalles de transacciones.' }
      );
    }
    if (isFalsoPositivo) {
      allOptions.push({ id: 'resolve_confidence_threshold', label: isEn ? 'Adaptive Confidence Thresholds' : 'Umbrales de Confianza Adaptativos', details: isEn ? 'System learns from false positives. Patient can mark interventions as "unnecessary" to refine algorithm. Threshold adjusts per user.' : 'Sistema aprende de falsos positivos. Paciente puede marcar intervenciones como "innecesarias" para refinar algoritmo.' },
        { id: 'resolve_multi_signal', label: isEn ? 'Multi-Signal Correlation' : 'Correlación Multi-Señal', details: isEn ? 'Requires 3+ concurrent signals before intervention: location + time + browsing pattern + biometric (if available). Reduces false positives by 87%.' : 'Requiere 3+ señales concurrentes antes de intervenir: ubicación + hora + patrón de navegación + biométrico (si disponible).' },
        { id: 'resolve_grace_period', label: isEn ? 'Grace Period with Soft Warnings' : 'Período de Gracia con Advertencias Suaves', details: isEn ? 'First detection triggers gentle reminder, not full intervention. Escalating response curve allows patient to self-correct.' : 'Primera detección activa recordatorio suave, no intervención completa. Curva de respuesta escalonada permite al paciente autocorregirse.' }
      );
    }
    if (isOffline) {
      allOptions.push({ id: 'resolve_offline_cache', label: isEn ? 'Offline-First with Sync' : 'Offline Primero con Sincronización', details: isEn ? 'Local-first architecture with IndexedDB/AsyncStorage. Queues interventions during offline and syncs when connection restored. Cryptographic integrity verification.' : 'Arquitectura local-first con IndexedDB/AsyncStorage. Encola intervenciones durante offline y sincroniza al restaurar conexión.' },
        { id: 'resolve_sms_fallback', label: isEn ? 'SMS Fallback Channel' : 'Canal de Respaldo SMS', details: isEn ? 'When data network fails, critical alerts route through SMS with pre-shared encryption keys. Works on any signal, not just data.' : 'Cuando la red de datos falla, alertas críticas se enrutan por SMS con claves de encriptación pre-compartidas.' }
      );
    }
    if (isConfiscacion) {
      allOptions.push({ id: 'resolve_duress_code', label: isEn ? 'Duress Code System' : 'Sistema de Código de Coerción', details: isEn ? 'Secondary password that appears to unlock device but silently triggers emergency protocol. Deletes sensitive data while appearing compliant.' : 'Contraseña secundaria que aparenta desbloquear el dispositivo pero activa silenciosamente el protocolo de emergencia.' },
        { id: 'resolve_remote_wipe', label: isEn ? 'Remote Wipe with Decoy' : 'Borrado Remoto con Señuelo', details: isEn ? 'Cloud-triggered remote wipe that installs decoy OS. Real data encrypted and hidden in steganographic partition.' : 'Borrado remoto activado desde la nube que instala SO señuelo. Datos reales encriptados en partición esteganográfica.' }
      );
    }
    if (isEscalado || allOptions.length === 0) {
      allOptions.push({ id: 'resolve_priority_queue', label: isEn ? 'Risk-Based Priority Queue' : 'Cola de Prioridad Basada en Riesgo', details: isEn ? 'Critical crises bypass queue. AI triage system assigns priority scores in real-time.' : 'Crisis críticas omiten cola. Sistema de triaje IA asigna puntajes de prioridad en tiempo real.' },
        { id: 'resolve_parallel_routing', label: isEn ? 'Parallel Contact Routing' : 'Enrutamiento Paralelo de Contactos', details: isEn ? 'Alert sent to all available contacts simultaneously. First responder claims case.' : 'Alerta enviada a todos los contactos disponibles simultáneamente. Primer respondedor reclama caso.' },
        { id: 'resolve_professional_backup', label: isEn ? 'Professional Backup Network' : 'Red de Respaldo Profesional', details: isEn ? 'Integration with crisis hotlines and teletherapy platforms.' : 'Integración con líneas de crisis y plataformas de teleterapia.' }
      );
    }
    return allOptions.slice(0, 5);
  };

  const progressPct = Math.min(100, Math.round((currentStep / stepLabels.length) * 100));
  if (!idea || !extractionData) return (<div className="min-h-screen pt-16 pb-12 px-4 fi flex items-center justify-center"><div className="text-slate-500">{tt('loading')}</div></div>);

  return (
    <div className="min-h-screen pt-16 pb-12 px-4 fi">
      <div className="max-w-5xl mx-auto">
        <div className="flex items-center justify-between mb-6">
          <div className="flex items-center gap-3">
            <button onClick={onBack} className="p-2 rounded-lg hover:bg-white/5 text-slate-400"><window.IconBack/></button>
            <div><h1 className="text-base font-semibold text-white">{tt('extraction.title')}</h1><p className="text-xs text-slate-500 truncate max-w-xs">{idea}</p></div>
          </div>
          <span className={`px-2 py-1 rounded-full text-xs border ${domain==='salud'?'bg-blue-500/10 text-blue-300 border-blue-500/30':domain==='ecommerce'?'bg-green-500/10 text-green-300 border-green-500/30':'bg-slate-500/10 text-slate-300 border-slate-500/30'}`}>{tt('home.domains.'+domain)||domain}</span>
        </div>
        <div className="flex items-center gap-1 mb-6 overflow-x-auto pb-2">
          {stepLabels.map((label,i) => (<div key={i} className={`flex items-center gap-1 px-2 py-1.5 rounded-lg text-xs flex-shrink-0 ${i<currentStep?'bg-indigo-500/20 text-indigo-300':i===currentStep&&!isDone?'bg-indigo-600 text-white':isDone?'bg-green-500/20 text-green-300':'text-slate-600'}`}>{i<currentStep||isDone?<window.IconCheck/>:i+1} {label}</div>))}
        </div>
        <div className="bg-white/[.02] border border-white/5 rounded-xl p-4 mb-4">
          <div className="flex items-center gap-2 mb-2"><div className={`w-2 h-2 rounded-full ${isDone?'bg-green-400':'bg-indigo-400 animate-pulse'}`}/><span className="text-xs text-slate-400 font-mono">{typing||'Initializing...'}</span></div>
          <div className="flex items-center gap-3"><span className="text-xs text-slate-500">{tt('extraction.confidence')}</span><div className="flex-1 h-1.5 bg-white/5 rounded-full overflow-hidden"><div className="h-full bg-gradient-to-r from-indigo-500 to-purple-500 rounded-full transition-all duration-500" style={{width:progressPct+'%'}}/></div><span className="text-xs text-indigo-300 font-mono">{progressPct}%</span></div>
        </div>
        {!isDone && (
          <div className="flex flex-col items-center justify-center py-16 gap-4">
            <div className="spinner"/>
            <button onClick={skipAnimation} className="text-xs text-indigo-400 hover:text-indigo-300 underline">{tt('extraction.skipAnimation')}</button>
          </div>
        )}
        {isDone && result && (
          <div className="space-y-4 su">
            {result.entities.length > 0 && (
              <div className="bg-white/[.02] border border-white/5 rounded-xl p-4">
                <p className="text-xs text-slate-500 uppercase mb-2">{tt('extraction.entities')} ({result.entities.length+manualEntities.length})</p>
                <div className="flex flex-wrap gap-2">{[...result.entities, ...manualEntities].map(e => (<span key={e.id} className="flex items-center gap-1.5 px-2.5 py-1 rounded bg-white/[.03] border border-white/5 text-xs text-slate-300"><span className="w-2 h-2 rounded-full bg-indigo-400"/>{e.label}</span>))}</div>
              </div>
            )}
            {result.workflows.length > 0 && (
              <div className="bg-white/[.02] border border-white/5 rounded-xl p-4"><p className="text-xs text-slate-500 uppercase mb-2">{tt('extraction.workflows')} ({result.workflows.length})</p>{result.workflows.map(w => (<div key={w.id} className="text-xs text-indigo-300 mb-1">{w.name}</div>))}</div>
            )}
            {result.brechas.length > 0 && (
              <div className="bg-red-500/[.05] border border-red-500/20 rounded-xl p-4">
                <p className="text-xs text-red-400 uppercase mb-2 flex items-center gap-1"><window.IconAlert/> {tt('extraction.breaches')} ({result.brechas.length})</p>
                {result.brechas.map(b => {
                  const isRes = resolvedBrechas[b.id];
                  const chosenRes = breachResolutionChosen[b.id] || [];
                  const options = getBreachResolutionOptions(b);
                  return (
                    <div key={b.id} className={`p-3 rounded border mb-2 ${isRes ? 'bg-green-500/10 border-green-500/30' : 'bg-red-500/10 border-red-500/30'}`}>
                      <div className="flex items-start gap-2">
                        <span className={`w-2 h-2 rounded-full mt-1.5 ${b.sev==='critical'?'bg-red-500':b.sev==='high'?'bg-red-400':'bg-orange-400'}`}/>
                        <div className="flex-1">
                          <p className="text-sm text-white">{b.text}</p>
                          <span className={`text-xs px-1.5 py-0.5 rounded ${b.sev==='high'||b.sev==='critical'?'bg-red-500/10 text-red-300':'bg-orange-500/10 text-orange-300'}`}>{b.sev}</span>
                        </div>
                        {isRes ? <span className="text-green-400 text-xs flex items-center gap-1"><window.IconCheck/> {tt('extraction.resolved')}</span> : null}
                      </div>
                      {!isRes && options.length > 0 && (
                        <div className="mt-2 space-y-1.5">
                          <p className="text-xs text-slate-400 font-medium">{tt('extraction.resolutionOptions')}</p>
                          {options.map(opt => {
                            const toggled = chosenRes.includes(opt.id);
                            return (
                              <label key={opt.id} className={`flex items-start gap-2 text-xs cursor-pointer p-2 rounded border ${toggled?'bg-green-500/10 border-green-500/30':'bg-white/5 border-white/5 hover:border-indigo-500/30'}`}>
                                <input type="checkbox" checked={toggled} onChange={() => {
                                  setBreachResolutionChosen(prev => {
                                    const cur = prev[b.id] || [];
                                    const next = cur.includes(opt.id) ? cur.filter(id => id !== opt.id) : [...cur, opt.id];
                                    return {...prev, [b.id]: next};
                                  });
                                  if (!toggled) setResolvedBrechas(p => ({...p, [b.id]: true}));
                                }} className="accent-green-500 mt-0.5" />
                                <div>
                                  <p className="text-slate-200 font-medium">{opt.label}</p>
                                  <p className="text-slate-400 mt-0.5 leading-relaxed">{opt.details}</p>
                                </div>
                              </label>
                            );
                          })}
                        </div>
                      )}
                    </div>
                  );
                })}
              </div>
            )}
            <div className="bg-white/[.02] border border-white/5 rounded-xl p-4">
              <p className="text-xs text-slate-500 uppercase mb-2">{tt('extraction.addEntity')}</p>
              <div className="flex gap-2">
                <input value={newEntityInput} onChange={e => setNewEntityInput(e.target.value)} placeholder={tt('extraction.newEntityLabel')} className="flex-1 bg-white/5 border border-white/10 rounded-lg px-3 py-2 text-sm text-white placeholder-slate-600 focus:outline-none"/>
                <select value={newEntityType} onChange={e => setNewEntityType(e.target.value)} className="bg-white/5 border border-white/10 rounded-lg px-3 py-2 text-sm text-slate-300"><option value="actor">{tt('blueprint.entityTypes.actor')}</option><option value="resource">{tt('blueprint.entityTypes.resource')}</option><option value="data">{tt('blueprint.entityTypes.data')}</option></select>
                <button onClick={handleAddEntity} className="px-4 py-2 bg-indigo-600 hover:bg-indigo-500 text-white rounded-lg text-sm font-medium flex items-center gap-1"><window.IconPlus/> {tt('extraction.add')}</button>
              </div>
              {window.suggestedEntities[domain] && window.suggestedEntities[domain].length > 0 && (
                <div className="mt-2">
                  <p className="text-xs text-slate-500 mb-1">{tt('extraction.suggestedEntitiesLabel')}</p>
                  {window.suggestedEntities[domain].map((ent, i) => {
                    const alreadyAdded = manualEntities.some(e => e.label === ent) || (result?.entities||[]).some(e => e.label === ent);
                    return (
                      <label key={i} className="flex items-center gap-2 text-xs text-slate-300 cursor-pointer">
                        <input type="checkbox" checked={alreadyAdded} onChange={(e) => {
                          if (e.target.checked) {
                            setManualEntities(prev => [...prev, {id: 'sug-'+Date.now()+i, label: ent, type:'resource'}]);
                          } else {
                            setManualEntities(prev => prev.filter(e => e.label !== ent));
                          }
                        }} className="accent-indigo-500" />
                        {ent}
                      </label>
                    );
                  })}
                </div>
              )}
            </div>
            <div className="flex justify-center pt-4">
              <button onClick={() => onComplete({ ...result, entities: [...result.entities, ...manualEntities], resolvedBrechas, breachResolutionChosen })} className="flex items-center gap-2 px-8 py-3 rounded-xl bg-gradient-to-r from-indigo-600 to-purple-600 hover:from-indigo-500 hover:to-purple-500 text-white text-sm font-semibold">{tt('extraction.continue')} <window.IconRight/></button>
            </div>
          </div>
        )}
      </div>
    </div>
  );
};

// ===== BLUEPRINT =====
window.Blueprint = ({ extraction, session, onComplete, onBack }) => {
  const { lang } = window.useLang();
  const tt = window.useT();
  const isEn = lang === 'en';
  const [step, setStep] = React.useState(0);
  const [selectedOpts, setSelectedOpts] = React.useState({});
  const [expandedOpt, setExpandedOpt] = React.useState(null);
  const [entityToggles, setEntityToggles] = React.useState({});
  const [resolvedBrechas, setResolvedBrechas] = React.useState(extraction?.resolvedBrechas || {});
  const [waivers, setWaivers] = React.useState([]);
  const [showWaiver, setShowWaiver] = React.useState(null);
  const [waiverJust, setWaiverJust] = React.useState('');
  const [mitigationChoices, setMitigationChoices] = React.useState({});
  const [breachResolutionChosen, setBreachResolutionChosen] = React.useState(extraction?.breachResolutionChosen || {});
  const [targetPlatform, setTargetPlatform] = React.useState('');
  const [generatedArtifact, setGeneratedArtifact] = React.useState(null);

  const entities = extraction?.entities || [];
  const brechas = extraction?.brechas || [];
  const confidence = extraction?.confidence || 75;
  const domain = session?.domain || 'general';
  const catalog = React.useMemo(() => window.getCatalog(domain, lang), [domain, lang]);

  React.useEffect(() => {
    const init = {};
    catalog.forEach(w => { init[w.id] = w.options[0]?.id; });
    setSelectedOpts(init);
  }, [catalog]);

  React.useEffect(() => {
    const similar = window.findSimilarSession(session?.idea, domain);
    if (similar) {
      if (similar.selectedOpts) setSelectedOpts(similar.selectedOpts);
      if (similar.mitigationChoices) setMitigationChoices(similar.mitigationChoices);
      if (similar.breachResolutionChosen && Object.keys(extraction?.breachResolutionChosen || {}).length === 0) {
        setBreachResolutionChosen(similar.breachResolutionChosen);
        const resolved = {};
        Object.keys(similar.breachResolutionChosen).forEach(id => resolved[id] = true);
        setResolvedBrechas(resolved);
      }
      if (similar.waivers) setWaivers(similar.waivers);
    }
  }, [session]);

  const getSelected = (wfId) => catalog.find(w => w.id === wfId)?.options.find(o => o.id === selectedOpts[wfId]) || catalog.find(w => w.id === wfId)?.options[0];
  const resolvedCount = brechas.filter(b => resolvedBrechas[b.id] || waivers.some(w => w.brechaId === b.id)).length;
  const maturity = Math.min(100, Math.round((confidence * 0.4) + (resolvedCount / Math.max(brechas.length, 1) * 30) + (Object.keys(selectedOpts).length * 5)));

  const toggleMitigation = (wfId, optId, conIdx, mitId) => {
    setMitigationChoices(prev => {
      const key = `${optId}_${conIdx}`;
      const cur = prev[key] || [];
      const next = cur.includes(mitId) ? cur.filter(id => id !== mitId) : [...cur, mitId];
      return { ...prev, [key]: next };
    });
  };

  const getBreachResolutionOptions = (breach) => {
    const breachText = (breach.text || '').toLowerCase();
    const isElusion = breachText.includes('elusión') || breachText.includes('vpn') || breachText.includes('crypto') || breachText.includes('efectivo') || breachText.includes('elusion');
    const isFatiga = breachText.includes('fatiga') || breachText.includes('alertas') || breachText.includes('contactos') || breachText.includes('fatigue');
    const isEmergencia = breachText.includes('emergencia') || breachText.includes('fondos') || breachText.includes('crisis genuina') || breachText.includes('emergency');
    const isPrivacidad = breachText.includes('privacidad') || breachText.includes('datos') || breachText.includes('gdpr') || breachText.includes('hipaa') || breachText.includes('privacy');
    const isFalsoPositivo = breachText.includes('falso positivo') || breachText.includes('precisión') || breachText.includes('detectar') || breachText.includes('false positive');
    const allOptions = [];
    if (isElusion) allOptions.push({ id: 'resolve_defense_depth', label: isEn ? 'Defense-in-Depth Protocol' : 'Protocolo de Defensa en Profundidad', details: isEn ? 'Multi-layer blocking: DNS + extension + firewall + bank API.' : 'Bloqueo multi-capa: DNS + extensión + firewall + API bancaria.' }, { id: 'resolve_behavioral', label: isEn ? 'Behavioral Analysis' : 'Análisis Conductual', details: isEn ? 'ML model on relapse patterns with anomaly detection.' : 'Modelo ML en patrones de recaída.' });
    if (isFatiga) allOptions.push({ id: 'resolve_rotation', label: isEn ? 'Alert Rotation' : 'Rotación de Alertas', details: isEn ? 'Distribute alerts across network, max 2/week per contact.' : 'Distribuir alertas en red, máx 2/semana por contacto.' }, { id: 'resolve_escalation', label: isEn ? 'Escalation Matrix' : 'Matriz de Escalado', details: isEn ? 'Tiered: automated → peer → professional.' : 'Escalonado: automatizado → pares → profesional.' });
    if (isEmergencia) allOptions.push({ id: 'resolve_dual_key', label: isEn ? 'Dual-Key Access' : 'Acceso con Doble Llave', details: isEn ? '2-of-3 approval required with time-lock.' : 'Aprobación 2-de-3 requerida con bloqueo temporal.' });
    if (isPrivacidad) allOptions.push({ id: 'resolve_zero_knowledge', label: isEn ? 'Zero-Knowledge Architecture' : 'Arquitectura de Conocimiento Cero', details: isEn ? 'E2E encryption, client-side processing.' : 'Encriptación E2E, procesamiento en cliente.' });
    if (isFalsoPositivo) allOptions.push({ id: 'resolve_threshold', label: isEn ? 'Adaptive Thresholds' : 'Umbrales Adaptativos', details: isEn ? 'System learns from corrections, adjusts per user.' : 'Sistema aprende de correcciones, ajusta por usuario.' }, { id: 'resolve_multisignal', label: isEn ? 'Multi-Signal Required' : 'Multi-Señal Requerida', details: isEn ? '3+ concurrent signals before intervention.' : '3+ señales concurrentes antes de intervenir.' });
    if (allOptions.length === 0) allOptions.push({ id: 'resolve_policy', label: isEn ? 'Define Policy' : 'Definir Política', details: isEn ? 'Formal rule with enforcement.' : 'Regla formal con aplicación.' }, { id: 'resolve_manual', label: isEn ? 'Manual Review' : 'Revisión Manual', details: isEn ? 'Human oversight with audit trail.' : 'Supervisión humana con auditoría.' }, { id: 'resolve_insurance', label: isEn ? 'Risk Transfer' : 'Transferencia de Riesgo', details: isEn ? 'Insurance to cover losses.' : 'Seguro para cubrir pérdidas.' });
    return allOptions.slice(0, 4);
  };

  const platforms = [
    { id: 'make', label: tt('blueprint.platforms.make'), icon: '⚡' },
    { id: 'n8n', label: tt('blueprint.platforms.n8n'), icon: '🔄' },
    { id: 'lovable', label: tt('blueprint.platforms.lovable'), icon: '🛠️' },
    { id: 'bubble', label: tt('blueprint.platforms.bubble'), icon: '🫧' },
    { id: 'bolt', label: 'Bolt.new', icon: '⚡' },
    { id: 'base44', label: 'Base44', icon: '🔷' },
    { id: 'hostinger', label: 'Hostinger', icon: '🟣' },
    { id: 'emergent', label: 'Emergent.sh', icon: '🌱' },
    { id: 'replit', label: 'Replit', icon: '📝' },
    { id: 'v0', label: 'Vercel v0', icon: '▲' },
    { id: 'flutterflow', label: 'FlutterFlow', icon: '📱' },
    { id: 'webflow', label: 'Webflow', icon: '🎨' },
    { id: 'generic', label: tt('blueprint.platforms.generic'), icon: '📄' }
  ];

  const generateForPlatform = (platform) => {
    const ir = {
      name: session?.idea?.substring(0, 50) || 'Proyecto',
      domain: session?.domain,
      entities: entities.filter(e => !entityToggles[e.id]),
      workflows: catalog.map(wf => { const sel = getSelected(wf.id); return { ...wf, selectedVariant: sel, mitigations: mitigationChoices }; }),
      breaches: brechas.map(b => ({ ...b, resolved: !!resolvedBrechas[b.id], waiver: waivers.find(w => w.brechaId === b.id)?.justification, resolutions: breachResolutionChosen[b.id] || {} })),
      businessRules: extraction?.rules || [],
      maturity
    };
    const architecturalBlueprint = {
      metadata: { projectName: ir.name, domain: ir.domain, generatedAt: new Date().toISOString(), version: '1.0.0', targetPlatform: platform, maturityScore: ir.maturity },
      dataModel: {
        schema: ir.entities.map(e => ({ entity: e.label, type: e.type, attributes: [{ name: 'id', type: 'UUID', constraints: ['PRIMARY KEY', 'NOT NULL'] }, { name: 'created_at', type: 'TIMESTAMP', constraints: ['DEFAULT NOW()'] }, { name: 'updated_at', type: 'TIMESTAMP', constraints: ['DEFAULT NOW()'] }], relationships: [] })),
        migrations: ir.entities.map(e => `CREATE TABLE ${e.label.toLowerCase().replace(/\s+/g,'_')} (\n  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n);`)
      },
      stateMachine: ir.workflows.map(wf => { const variant = wf.selectedVariant; return { workflow: wf.name, variant: variant?.label || 'default', states: variant?.steps.map((step, i) => ({ id: `state_${i}`, name: step, type: i === 0 ? 'TRIGGER' : i === variant.steps.length - 1 ? 'TERMINAL' : 'PROCESS', transitions: [{ to: `state_${i+1}`, condition: 'success' }] })) || [], events: variant?.steps.map((step, i) => ({ event: `on_${step.toLowerCase().replace(/\s+/g,'_')}`, handler: `handle${step.replace(/\s+/g,'')}`, payload: { step: i, timestamp: '{{now}}' } })) || [] }; }),
      apiContract: { openapi: '3.0.0', info: { title: ir.name, version: '1.0.0' }, paths: ir.entities.reduce((acc, e) => { const path = `/${e.label.toLowerCase().replace(/\s+/g,'_')}`; acc[path] = { get: { summary: `Listar ${e.label}`, responses: { '200': { description: 'OK' } } }, post: { summary: `Crear ${e.label}`, responses: { '201': { description: 'Created' } } } }; acc[`${path}/{id}`] = { get: { summary: `Obtener ${e.label}`, parameters: [{ name: 'id', in: 'path', required: true }], responses: { '200': { description: 'OK' } } }, put: { summary: `Actualizar ${e.label}`, responses: { '200': { description: 'OK' } } }, delete: { summary: `Eliminar ${e.label}`, responses: { '204': { description: 'No Content' } } } }; return acc; }, {}) },
      integrityRules: ir.businessRules.map((rule, i) => ({ id: `rule_${i}`, description: rule, type: 'INVARIANT', enforcement: 'BEFORE_COMMIT', action: 'REJECT' })),
      riskMitigation: ir.breaches.map(b => ({ brecha: b.text, severity: b.sev || 'medium', status: b.resolved ? 'RESOLVED' : 'OPEN', resolution: Object.keys(b.resolutions || {}).join(',') || 'PENDING', waiver: b.waiver || null })),
      platformSpec: generatePlatformSpecific(platform, ir)
    };
    setGeneratedArtifact(JSON.stringify(architecturalBlueprint, null, 2));
    setTargetPlatform(platform);
  };

  const generatePlatformSpecific = (platform, ir) => {
    const base = { platform, components: ir.entities.map(e => ({ name: e.label, type: 'RESOURCE' })), workflows: ir.workflows.map(w => ({ name: w.name, variant: w.selectedVariant?.label })) };
    if (platform === 'bolt') return { ...base, bolt: { projectType: 'fullstack-react', structure: { frontend: { framework: 'React + Vite', ui: 'TailwindCSS + shadcn/ui', state: 'Zustand' }, backend: { runtime: 'Node.js', framework: 'Express', database: 'Supabase' }, deployment: 'Netlify/Vercel' }, files: [{ path: 'src/App.tsx', type: 'component' }, { path: 'src/components/', type: 'directory' }, { path: 'server/index.js', type: 'backend' }], commands: ['npm create vite@latest', 'npm install', 'npm run dev'] } };
    if (platform === 'base44') return { ...base, base44: { applicationType: 'enterprise', modules: ir.entities.map(e => ({ name: e.label, type: 'data_module' })), roles: ['admin', 'user', 'viewer'] } };
    if (platform === 'hostinger') return { ...base, hostinger: { builderType: 'ai_website_builder', pages: ['home', 'dashboard'], features: ['responsive_design', 'ssl_certificate'] } };
    if (platform === 'emergent') return { ...base, emergent: { developmentMode: 'ai_assisted', stack: { frontend: 'React', backend: 'Python/FastAPI', database: 'PostgreSQL' } } };
    if (platform === 'replit') return { ...base, replit: { language: 'nodejs', template: 'react-express', database: 'replit_db' } };
    if (platform === 'v0') return { ...base, v0: { uiFramework: 'Next.js + TailwindCSS', components: ir.entities.flatMap(e => [{ name: `${e.label}Card`, type: 'display' }, { name: `${e.label}Form`, type: 'input' }]), deployment: 'vercel_edge' } };
    if (platform === 'flutterflow') return { ...base, flutterflow: { platform: 'mobile_web', framework: 'Flutter', screens: ir.entities.map(e => ({ name: `${e.label}Screen` })), database: 'firebase_firestore', deployment: ['ios', 'android', 'web'] } };
    if (platform === 'webflow') return { ...base, webflow: { cmsCollections: ir.entities.map(e => ({ name: e.label })), pages: ['home', 'collection', 'item-detail'], hosting: 'webflow_hosting' } };
    if (platform === 'make') return { ...base, scenario: { trigger: { type: 'webhook' }, modules: ir.workflows.flatMap(wf => wf.selectedVariant?.steps.map((step, i) => ({ id: i + 1, action: 'util:TextAggregator', name: step })) || []) } };
    if (platform === 'n8n') return { ...base, workflow: { nodes: ir.workflows.flatMap(wf => wf.selectedVariant?.steps.map((step, i) => ({ name: step, type: 'n8n-nodes-base.httpRequest', position: [250 * i, 300] })) || []), connections: [] } };
    if (platform === 'bubble') return { ...base, bubble: { dataTypes: ir.entities.map(e => ({ name: e.label })), pages: ['index', 'dashboard'], plugins: ['API Connector'] } };
    if (platform === 'lovable') return { ...base, lovable: { components: ir.entities.flatMap(e => [{ name: `${e.label}List`, type: 'LIST' }]), supabase: { tables: ir.entities.map(e => e.label.toLowerCase().replace(/\s+/g, '_')) } } };
    return { ...base, generic: { architecture: 'MICROSERVICES', deployment: 'DOCKER_KUBERNETES', database: 'POSTGRESQL', api: 'REST_OPENAPI', auth: 'JWT_OIDC' } };
  };

  // PASO 4: PLATAFORMA DE EXPORTACIÓN
  if (step === 4) {
    return (
      <div className="min-h-screen pt-16 pb-12 px-4 fi"><div className="max-w-4xl mx-auto">
        <div className="flex items-center gap-3 mb-6"><button onClick={() => setStep(3)} className="p-2 rounded-lg hover:bg-white/5 text-slate-400"><window.IconBack/></button><h1 className="text-base font-semibold text-white">{tt('blueprint.platformTitle')}</h1></div>
        <p className="text-sm text-slate-400 mb-4">{tt('blueprint.platformDesc')}</p>
        <div className="grid grid-cols-2 sm:grid-cols-3 gap-3 mb-6">{platforms.map(p => (<button key={p.id} onClick={() => generateForPlatform(p.id)} className={`p-4 rounded-xl border text-left transition-all ${targetPlatform===p.id?'bg-indigo-500/10 border-indigo-500/40':'bg-white/[.02] border-white/5 hover:border-indigo-500/30'}`}><div className="text-xl mb-1">{p.icon}</div><div className="text-sm font-medium text-white">{p.label}</div></button>))}</div>
        {generatedArtifact && (
          <div className="bg-white/[.03] border border-white/5 rounded-xl p-4 mb-6">
            <div className="flex items-center justify-between mb-3">
              <h3 className="text-sm font-medium text-indigo-300">{tt('blueprint.exportReady')} {targetPlatform}</h3>
              <button onClick={() => { const blob = new Blob([generatedArtifact],{type:'application/json'}); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `alma_${targetPlatform}_${Date.now()}.json`; a.click(); }} className="flex items-center gap-1.5 px-3 py-1.5 bg-indigo-600 hover:bg-indigo-500 text-white text-xs rounded"><window.IconExport/> {tt('blueprint.download')}</button>
            </div>
            <p className="text-xs text-slate-500 mb-2">{tt('blueprint.fullArchitecture')} - {entities.length} entidades, {catalog.length} workflows, {brechas.length} reglas de integridad</p>
            <pre className="text-xs text-slate-400 font-mono whitespace-pre overflow-auto max-h-96 bg-black/20 rounded p-3">{generatedArtifact.substring(0,3000)}{generatedArtifact.length>3000?'\n... (truncado, descarga para ver completo)':''}</pre>
          </div>
        )}
        <div className="flex justify-between"><button onClick={() => setStep(3)} className="flex items-center gap-2 px-5 py-2.5 rounded-xl bg-white/5 hover:bg-white/10 text-slate-300 text-sm"><window.IconBack/> {tt('blueprint.previous')}</button><button onClick={() => { window.saveSessionToMemory({ idea: session?.idea, domain, selectedOpts, mitigationChoices, breachResolutionChosen, waivers }); onComplete({ entities, catalog, brechas, resolvedCount, maturity, confidence }); }} className="flex items-center gap-2 px-6 py-2.5 rounded-xl bg-gradient-to-r from-green-600 to-emerald-600 hover:from-green-500 hover:to-emerald-500 text-white text-sm font-semibold">{tt('blueprint.compile')} <window.IconCheck/></button></div>
      </div></div>
    );
  }

  // PASO 3: COMPILADO
  if (step === 3) {
    const safeEntities = entities || [];
    const safeCatalog = catalog || [];
    const safeBrechas = brechas || [];
    const safeResolvedCount = resolvedCount || 0;
    const safeMaturity = maturity || 0;
    return (
      <div className="min-h-screen pt-16 pb-12 px-4 fi"><div className="max-w-4xl mx-auto">
        <div className="text-center mb-8"><div className="w-16 h-16 rounded-full bg-gradient-to-br from-green-500 to-emerald-600 flex items-center justify-center mx-auto mb-4"><svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="white" strokeWidth="2"><path d="M20 6 9 17l-5-5"/></svg></div><h1 className="text-2xl font-bold text-white mb-2">{tt('blueprint.compiledTitle')}</h1><p className="text-slate-400 text-sm">{tt('blueprint.compiledSubtitle')}</p></div>
        <div className="grid grid-cols-2 sm:grid-cols-4 gap-3 mb-6">
          {[{v:safeEntities.length,l:tt('extraction.entities')},{v:safeCatalog.length,l:tt('extraction.workflows')},{v:safeResolvedCount+'/'+safeBrechas.length,l:tt('extraction.breaches')},{v:safeMaturity,l:tt('blueprint.maturityLabel')}].map((s,i)=>(<div key={i} className="bg-white/[.03] border border-white/5 rounded-xl p-3 text-center"><div className="text-2xl font-bold text-indigo-300">{s.v}</div><div className="text-xs text-slate-500 mt-1">{s.l}</div></div>))}
        </div>
        <div className="bg-white/[.03] border border-white/5 rounded-xl p-4 mb-6"><h3 className="text-sm font-medium text-slate-300 mb-3">{tt('blueprint.workflowSelected')}</h3><div className="space-y-3">{safeCatalog.map(wf => { const sel = getSelected(wf.id); if (!sel) return null; return (<div key={wf.id} className="bg-white/[.03] rounded-lg p-3 border border-white/5"><div className="flex items-center gap-2 mb-2"><span>{wf.icon}</span><span className="text-sm font-medium text-white">{wf.name}</span><span className="text-xs text-indigo-300 ml-auto">{sel.label}</span></div><div className="flex items-center gap-1 flex-wrap">{sel.steps.map((s,i)=>(<span key={i} className="px-2 py-0.5 bg-indigo-500/10 rounded text-xs text-indigo-300">{i+1}. {s}</span>))}</div></div>); })}</div></div>
        <div className="flex justify-between"><button onClick={() => setStep(2)} className="flex items-center gap-2 px-5 py-2.5 rounded-xl bg-white/5 hover:bg-white/10 text-slate-300 text-sm"><window.IconBack/> {tt('blueprint.previous')}</button><button onClick={() => setStep(4)} className="flex items-center gap-2 px-6 py-2.5 rounded-xl bg-gradient-to-r from-indigo-600 to-purple-600 hover:from-indigo-500 hover:to-purple-500 text-white text-sm font-semibold">{tt('blueprint.next')}: {tt('blueprint.stepLabels.4')||'Motor de Ejecución'} <window.IconRight/></button></div>
      </div></div>
    );
  }

  // PASO 0: ENTIDADES
  if (step === 0) {
    return (
      <div className="min-h-screen pt-16 pb-12 px-4 fi"><div className="max-w-4xl mx-auto">
        <div className="flex items-center gap-3 mb-6"><button onClick={onBack} className="p-2 rounded-lg hover:bg-white/5 text-slate-400"><window.IconBack/></button><div><h1 className="text-base font-semibold text-white">{tt('blueprint.entitiesTitle')}</h1><p className="text-xs text-slate-500">{tt('home.domainLabel')}: {tt('home.domains.'+domain)||domain}</p></div></div>
        <div className="bg-white/[.03] border border-white/5 rounded-xl p-5 mb-4"><p className="text-sm text-slate-400 mb-4">{tt('blueprint.entitiesDesc')}</p><div className="grid grid-cols-2 sm:grid-cols-3 gap-3">{entities.map(e => { const on = !entityToggles[e.id]; return (<button key={e.id} onClick={()=>setEntityToggles(p=>({...p,[e.id]:!p[e.id]}))} className={`p-3 rounded-xl border text-left transition-all ${on?'bg-indigo-500/5 border-indigo-500/30':'bg-white/[.02] border-white/5 opacity-50'}`}><div className="flex items-center gap-2 mb-1"><span className="w-2.5 h-2.5 rounded-full bg-indigo-400"/><span className="text-sm font-medium text-white">{e.label}</span></div><span className="text-xs text-slate-500">{e.type}</span></button>); })}</div></div>
        <div className="flex justify-end"><button onClick={()=>setStep(1)} className="flex items-center gap-2 px-6 py-2.5 rounded-xl bg-indigo-600 hover:bg-indigo-500 text-white text-sm font-medium">{tt('blueprint.next')} <window.IconRight/></button></div>
      </div></div>
    );
  }

  // PASO 1: WORKFLOWS
  if (step === 1) {
    return (
      <div className="min-h-screen pt-16 pb-12 px-4 fi"><div className="max-w-5xl mx-auto">
        <div className="flex items-center gap-3 mb-6"><button onClick={()=>setStep(0)} className="p-2 rounded-lg hover:bg-white/5 text-slate-400"><window.IconBack/></button><div><h1 className="text-base font-semibold text-white">{tt('blueprint.workflowsTitle')}</h1><p className="text-xs text-slate-500">{tt('home.domainLabel')}: <span className="text-indigo-300">{tt('home.domains.'+domain)||domain}</span></p></div></div>
        <div className="space-y-6">
          {catalog.map(wf => {
            const sel = getSelected(wf.id);
            return (<div key={wf.id} className="bg-white/[.03] border border-white/5 rounded-xl overflow-hidden"><div className="p-4 border-b border-white/5 bg-white/[.02]"><div className="flex items-center gap-2"><span className="text-xl">{wf.icon}</span><div><h3 className="text-sm font-semibold text-white">{wf.name}</h3><p className="text-xs text-slate-500">{wf.desc}</p></div></div></div>
              <div className="p-4"><p className="text-xs text-slate-500 uppercase mb-3">{tt('blueprint.optionsLabel')}</p><div className="grid grid-cols-1 lg:grid-cols-2 gap-3 mb-4">{wf.options.map(opt => { const isSel = opt.id === selectedOpts[wf.id]; return (<button key={opt.id} onClick={()=>setSelectedOpts(p=>({...p,[wf.id]:opt.id}))} className={`text-left p-3 rounded-xl border transition-all ${isSel?'bg-indigo-500/10 border-indigo-500/40':'bg-white/[.02] border-white/5 hover:border-indigo-500/20'}`}><div className="flex items-start gap-2"><div className={`w-4 h-4 rounded-full border-2 flex items-center justify-center mt-0.5 ${isSel?'border-indigo-400':'border-slate-600'}`}>{isSel&&<div className="w-2 h-2 rounded-full bg-indigo-400"/>}</div><div><div className="flex items-center gap-1.5"><span className={`text-sm font-medium ${isSel?'text-white':'text-slate-300'}`}>{opt.label}</span>{opt.tag&&<span className="text-[10px] px-1 py-0.5 rounded bg-indigo-500/20 text-indigo-300">{opt.tag}</span>}</div><p className="text-xs text-slate-500">{opt.desc}</p></div></div></button>); })}</div>
                {sel && (<div className="pt-3 border-t border-white/5"><p className="text-xs text-slate-500 uppercase mb-2">{tt('blueprint.stepsLabel')} {sel.label}</p><div className="flex items-center gap-1 flex-wrap mb-3">{sel.steps.map((s,i)=>(<span key={i} className="flex items-center gap-1 px-2 py-0.5 bg-indigo-500/10 rounded text-xs text-indigo-300 border border-indigo-500/20"><span className="w-3.5 h-3.5 rounded-full bg-indigo-500/30 text-[9px] flex items-center justify-center text-indigo-200 font-bold">{i+1}</span>{s}</span>))}</div>
                  <button onClick={()=>setExpandedOpt(expandedOpt===wf.id?null:wf.id)} className="text-xs text-indigo-400 hover:text-indigo-300">{expandedOpt===wf.id?tt('blueprint.hideProsCons'):tt('blueprint.prosConsLabel')}</button>
                  {expandedOpt===wf.id && (<div className="mt-2 grid grid-cols-1 md:grid-cols-2 gap-3 text-xs"><div className="p-2 bg-green-500/5 rounded border border-green-500/10"><span className="text-green-400 font-medium">{tt('blueprint.advantages')}</span><ul className="mt-1 space-y-0.5 text-slate-400">{sel.pros?.map((p,i)=>(<li key={i}>• {p}</li>))}</ul></div><div className="p-2 bg-red-500/5 rounded border border-red-500/10"><span className="text-red-400 font-medium">{tt('blueprint.disadvantages')}</span><ul className="mt-1 space-y-0.5 text-slate-400">{sel.cons?.map((c,i)=>(<li key={i}>• {c}</li>))}</ul></div>
                    {sel.mitigations && sel.mitigations.length > 0 && (<div className="col-span-full p-3 bg-white/[.02] rounded border border-white/5"><p className="text-xs text-slate-400 font-medium mb-2">{tt('blueprint.mitigationLabel')}</p>{sel.mitigations.map((mit, idx) => (<div key={idx} className="mb-2"><p className="text-xs text-red-300/80 mb-1">{mit.con}</p><div className="flex flex-wrap gap-2">{mit.options.map(mopt => { const key = `${sel.id}_${idx}`; const checked = (mitigationChoices[key] || []).includes(mopt.id); return (<label key={mopt.id} className="flex items-center gap-1 text-xs text-slate-400 cursor-pointer"><input type="checkbox" checked={checked} onChange={() => toggleMitigation(wf.id, sel.id, idx, mopt.id)} className="accent-indigo-500"/>{mopt.label}</label>); })}</div></div>))}</div>)}
                  </div>)}</div>)}
              </div></div>);
          })}
        </div>
        <div className="flex justify-between mt-6"><button onClick={()=>setStep(0)} className="flex items-center gap-2 px-5 py-2.5 rounded-xl bg-white/5 hover:bg-white/10 text-slate-300 text-sm"><window.IconBack/> {tt('blueprint.previous')}</button><button onClick={()=>setStep(2)} className="flex items-center gap-2 px-5 py-2.5 rounded-xl bg-indigo-600 hover:bg-indigo-500 text-white text-sm font-medium">{tt('blueprint.next')} <window.IconRight/></button></div>
      </div></div>
    );
  }

  // PASO 2: BRECHAS
  if (step === 2) {
    return (
      <div className="min-h-screen pt-16 pb-12 px-4 fi"><div className="max-w-4xl mx-auto">
        <div className="flex items-center gap-3 mb-6"><button onClick={()=>setStep(1)} className="p-2 rounded-lg hover:bg-white/5 text-slate-400"><window.IconBack/></button><div><h1 className="text-base font-semibold text-white">{tt('blueprint.breachesTitle')}</h1><p className="text-xs text-slate-500">{resolvedCount}/{brechas.length} {tt('blueprint.resolvedLabel')}</p></div></div>
        <div className="w-full h-2 bg-white/5 rounded-full overflow-hidden mb-6"><div className="h-full bg-gradient-to-r from-orange-500 to-green-500 rounded-full transition-all" style={{width:(resolvedCount/Math.max(brechas.length,1)*100)+'%'}}/></div>
        <div className="space-y-3 mb-6">
          {brechas.map(b => {
            const isRes = resolvedBrechas[b.id];
            const hasW = waivers.some(w => w.brechaId === b.id);
            const chosenRes = breachResolutionChosen[b.id] || [];
            const options = getBreachResolutionOptions(b);
            return (<div key={b.id} className={`p-4 rounded-xl border ${isRes?'bg-green-500/5 border-green-500/30':hasW?'bg-yellow-500/5 border-yellow-500/30':'bg-red-500/5 border-red-500/20'}`}>
              <div className="flex items-start gap-3 mb-2"><span className={`mt-1 w-2 h-2 rounded-full ${b.sev==='critical'?'bg-red-500':b.sev==='high'?'bg-red-400':'bg-orange-400'}`}/><div className="flex-1"><p className="text-sm text-white">{b.text}</p><span className={`text-xs px-1.5 py-0.5 rounded ${b.sev==='high'||b.sev==='critical'?'bg-red-500/10 text-red-300':'bg-orange-500/10 text-orange-300'}`}>{b.sev}</span></div>{isRes?<span className="text-green-400 text-xs flex items-center gap-1"><window.IconCheck/> {isEn?'Resolved':'Resuelto'}</span>:null}{hasW?<span className="text-yellow-400 text-xs flex items-center gap-1"><window.IconShield/> {tt('blueprint.waiver')}</span>:null}</div>
              {!isRes && !hasW && (<div className="space-y-3"><p className="text-xs text-slate-400 font-medium">{tt('blueprint.resolutionOptions')}</p>{options.map(opt => { const toggled = chosenRes.includes(opt.id); return (<div key={opt.id} className={`p-3 rounded-lg border ${toggled?'bg-green-500/10 border-green-500/30':'bg-white/5 border-white/10'} hover:border-indigo-500/30 transition-all cursor-pointer`} onClick={()=>{ setBreachResolutionChosen(prev => { const cur = prev[b.id] || []; const next = cur.includes(opt.id) ? cur.filter(id => id !== opt.id) : [...cur, opt.id]; return {...prev, [b.id]: next}; }); if (!toggled) setResolvedBrechas(p => ({...p, [b.id]: true})); }}><label className="flex items-start gap-3 cursor-pointer"><input type="checkbox" checked={toggled} onChange={()=>{}} className="accent-green-500 mt-0.5"/><div className="flex-1"><p className="text-sm text-white font-medium">{opt.label}</p>{opt.details && <p className="text-xs text-slate-400 mt-1 leading-relaxed">{opt.details}</p>}</div></label></div>); })}<div className="flex gap-2 mt-3"><button onClick={()=>{ setResolvedBrechas(p=>({...p,[b.id]:true})); setBreachResolutionChosen(prev => ({...prev, [b.id]: prev[b.id] || ['resolve_policy']})); }} className="px-4 py-2 bg-green-500/10 hover:bg-green-500/20 text-green-300 text-xs rounded-lg border border-green-500/20 font-medium">{tt('blueprint.resolve')}</button><button onClick={()=>{setShowWaiver(b);setWaiverJust('');}} className="px-4 py-2 bg-yellow-500/10 hover:bg-yellow-500/20 text-yellow-300 text-xs rounded-lg border border-yellow-500/20 font-medium">{tt('blueprint.waiver')}</button></div></div>)}
            </div>);
          })}
        </div>
        {showWaiver && (<div className="bg-yellow-500/5 border border-yellow-500/20 rounded-xl p-4 mb-6"><div className="flex items-center justify-between mb-2"><h3 className="text-sm font-medium text-yellow-300">{tt('blueprint.waiverTitle')} {showWaiver.text}</h3><button onClick={()=>setShowWaiver(null)} className="text-slate-400 hover:text-white"><window.IconX/></button></div><textarea value={waiverJust} onChange={e=>setWaiverJust(e.target.value)} placeholder={tt('blueprint.waiverPlaceholder')} className="w-full h-20 bg-white/5 border border-white/10 rounded-lg px-3 py-2 text-sm text-white placeholder-slate-600 focus:outline-none focus:ring-1 focus:ring-yellow-500/50 resize-none"/><div className="flex items-center justify-between mt-2"><span className={`text-xs ${waiverJust.length<50?'text-red-400':'text-green-400'}`}>{waiverJust.length}/50</span><button onClick={()=>{if(waiverJust.length>=50){setWaivers(p=>[...p,{brechaId:showWaiver.id,justification:waiverJust}]);setWaiverJust('');setShowWaiver(null);}}} disabled={waiverJust.length<50} className={`px-4 py-1.5 rounded text-xs font-medium ${waiverJust.length>=50?'bg-yellow-600 hover:bg-yellow-500 text-white':'bg-white/5 text-slate-500'}`}>{tt('blueprint.applyWaiver')}</button></div></div>)}
        <div className="flex justify-between"><button onClick={()=>setStep(1)} className="flex items-center gap-2 px-5 py-2.5 rounded-xl bg-white/5 hover:bg-white/10 text-slate-300 text-sm"><window.IconBack/> {tt('blueprint.previous')}</button><button onClick={()=>setStep(3)} className="flex items-center gap-2 px-5 py-2.5 rounded-xl bg-gradient-to-r from-indigo-600 to-purple-600 hover:from-indigo-500 hover:to-purple-500 text-white text-sm font-semibold">{tt('blueprint.compile')} <window.IconRight/></button></div>
      </div></div>
    );
  }
  return null;
};

// ===== FORENSIC =====
window.Forensic = ({ session, onComplete, onBack }) => {
  const { lang } = window.useLang();
  const tt = window.useT();
  const isEn = lang === 'en';
  const [step, setStep] = React.useState(0);
  const [answers, setAnswers] = React.useState([]);
  const scenarios = [
    { q: isEn ? 'A critical entity disappears from the schema. How does the system react?' : 'Una entidad crítica desaparece del esquema. ¿Cómo reacciona el sistema?', options: [isEn ? 'Rejects all operations' : 'Rechaza todas las operaciones', isEn ? 'Continues with partial data' : 'Continúa con datos parciales', isEn ? 'Triggers alert + fallback' : 'Activa alerta + fallback'], correct: 2 },
    { q: isEn ? 'Payment gateway returns timeout during checkout.' : 'La pasarela de pago devuelve timeout durante el checkout.', options: [isEn ? 'Cancel order immediately' : 'Cancelar orden inmediatamente', isEn ? 'Retry 3 times + queue for manual review' : 'Reintentar 3 veces + cola para revisión manual', isEn ? 'Ask user to try again later' : 'Pedir al usuario que intente más tarde'], correct: 1 },
    { q: isEn ? 'Two users try to book the same time slot simultaneously.' : 'Dos usuarios intentan reservar el mismo horario simultáneamente.', options: [isEn ? 'First-come-first-served with transaction lock' : 'Primero en llegar con bloqueo de transacción', isEn ? 'Both succeed and resolve later' : 'Ambos tienen éxito y se resuelve después', isEn ? 'Random selection' : 'Selección aleatoria'], correct: 0 },
  ];
  const handleAnswer = (idx) => { const newAnswers = [...answers]; newAnswers[step] = idx; setAnswers(newAnswers); if (step < scenarios.length - 1) setTimeout(() => setStep(step + 1), 250); else setTimeout(onComplete, 400); };
  const score = answers.reduce((acc, a, i) => acc + (a === scenarios[i].correct ? 1 : 0), 0);
  const resilienceScore = Math.round((score / scenarios.length) * 100);
  if (step >= scenarios.length) return (
    <div className="min-h-screen pt-16 pb-12 px-4 fi"><div className="max-w-2xl mx-auto text-center"><div className="w-20 h-20 rounded-full bg-gradient-to-br from-indigo-500 to-purple-600 flex items-center justify-center mx-auto mb-4"><span className="text-3xl font-bold text-white">{resilienceScore}%</span></div><h1 className="text-2xl font-bold text-white mb-2">{tt('forensic.resilienceTitle')}</h1><p className="text-slate-400 text-sm mb-6">{scenarios.length} {tt('forensic.scenariosEvaluated')}</p><div className="bg-white/[.03] border border-white/5 rounded-xl p-4 mb-6 text-left">{scenarios.map((s,i)=>(<div key={i} className="mb-3 pb-3 border-b border-white/5 last:border-0"><p className="text-xs text-slate-400 mb-1">{i+1}. {s.q}</p><p className="text-sm text-white">{s.options[answers[i]]}</p><p className={`text-xs mt-1 ${answers[i]===s.correct?'text-green-400':'text-red-400'}`}>{answers[i]===s.correct?'✓':'✗'} {isEn?'Correct':'Correcto'}</p></div>))}</div><button onClick={onComplete} className="px-6 py-2.5 rounded-xl bg-indigo-600 hover:bg-indigo-500 text-white text-sm font-medium">{tt('forensic.continue')}</button></div></div>);
  return (
    <div className="min-h-screen pt-16 pb-12 px-4 fi"><div className="max-w-2xl mx-auto"><div className="flex items-center gap-3 mb-6"><button onClick={onBack} className="p-2 rounded-lg hover:bg-white/5 text-slate-400"><window.IconBack/></button><h1 className="text-base font-semibold text-white">{tt('forensic.title')}</h1></div><div className="w-full h-1.5 bg-white/5 rounded-full overflow-hidden mb-6"><div className="h-full bg-gradient-to-r from-indigo-500 to-purple-500 rounded-full transition-all" style={{width:((step+1)/scenarios.length*100)+'%'}}/></div><div className="bg-white/[.03] border border-white/5 rounded-xl p-6 mb-6"><p className="text-sm text-slate-300 mb-4">{scenarios[step].q}</p><div className="space-y-2">{scenarios[step].options.map((opt,i)=>(<button key={i} onClick={()=>handleAnswer(i)} className="w-full text-left p-3 rounded-lg bg-white/5 hover:bg-indigo-500/10 text-slate-300 hover:text-white text-sm transition-colors border border-white/5 hover:border-indigo-500/30">{opt}</button>))}</div></div><div className="flex justify-between text-xs text-slate-500"><span>{tt('forensic.answerLabel')}</span><span>{step+1}/{scenarios.length}</span></div></div></div>);
};

// ===== DASHBOARD =====
window.Dashboard = ({ blueprints, onView, onNew, onDelete }) => {
  const { lang } = window.useLang();
  const tt = window.useT();
  const [search, setSearch] = React.useState('');
  const [sort, setSort] = React.useState(0);
  const filtered = blueprints.filter(bp => bp.name.toLowerCase().includes(search.toLowerCase()) || bp.domain.toLowerCase().includes(search.toLowerCase())).sort((a, b) => { if (sort === 0) return new Date(b.date) - new Date(a.date); if (sort === 1) return b.score - a.score; return a.name.localeCompare(b.name); });
  return (
    <div className="min-h-screen pt-16 pb-12 px-4 fi"><div className="max-w-6xl mx-auto"><div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4 mb-6"><div><h1 className="text-2xl font-bold text-white">{tt('dashboard.title')}</h1><p className="text-sm text-slate-500">{blueprints.length} {tt('dashboard.sessions')}</p></div><button onClick={onNew} className="flex items-center gap-2 px-4 py-2 rounded-xl bg-indigo-600 hover:bg-indigo-500 text-white text-sm font-medium"><span>+</span> {tt('dashboard.newSession')}</button></div><div className="flex flex-col sm:flex-row gap-3 mb-6"><div className="flex-1 relative"><input type="text" value={search} onChange={(e)=>setSearch(e.target.value)} placeholder={tt('dashboard.searchPlaceholder')} className="w-full px-4 py-2.5 rounded-xl bg-white/[.03] border border-white/5 text-white placeholder-slate-500 focus:outline-none focus:ring-1 focus:ring-indigo-500/50"/><svg className="absolute right-3 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/></svg></div><select value={sort} onChange={(e)=>setSort(Number(e.target.value))} className="px-4 py-2.5 rounded-xl bg-white/[.03] border border-white/5 text-white text-sm focus:outline-none">{tt('dashboard.sortOptions').map((opt,i)=>(<option key={i} value={i}>{opt}</option>))}</select></div>{filtered.length===0?(<div className="text-center py-16"><div className="w-16 h-16 rounded-full bg-white/[.03] border border-white/5 flex items-center justify-center mx-auto mb-4"><svg className="w-8 h-8 text-slate-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/></svg></div><h3 className="text-lg font-semibold text-white mb-1">{tt('dashboard.noBlueprints')}</h3><p className="text-sm text-slate-500 mb-4">{tt('dashboard.noBlueprintsDesc')}</p><button onClick={onNew} className="px-4 py-2 rounded-xl bg-indigo-600 hover:bg-indigo-500 text-white text-sm font-medium">{tt('dashboard.createFirst')}</button></div>):(<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">{filtered.map(bp=>(<div key={bp.id} className="bg-white/[.03] border border-white/5 rounded-xl p-4 hover:border-indigo-500/30 transition-colors"><div className="flex items-start justify-between mb-3"><div className="flex-1"><h3 className="text-sm font-semibold text-white mb-1 line-clamp-2">{bp.name}</h3><p className="text-xs text-slate-500">{bp.date}</p></div><span className={`text-xs px-2 py-1 rounded font-medium ${bp.score>=85?'bg-green-500/10 text-green-400':bp.score>=70?'bg-yellow-500/10 text-yellow-400':'bg-red-500/10 text-red-400'}`}>{bp.score}</span></div><div className="flex items-center gap-2 mb-3 text-xs text-slate-500"><span className="px-2 py-0.5 rounded bg-white/5">{tt('home.domains.'+bp.domain)||bp.domain}</span><span>{bp.entities} ent.</span><span>{bp.workflows} wf.</span></div><div className="flex items-center gap-2"><button onClick={()=>onView(bp)} className="flex-1 flex items-center justify-center gap-1 px-3 py-1.5 rounded-lg bg-white/5 hover:bg-indigo-500/10 text-slate-300 hover:text-indigo-300 text-xs transition-colors"><window.IconEye/> {tt('dashboard.view')}</button><button onClick={()=>onDelete(bp.id)} className="p-1.5 rounded-lg bg-white/5 hover:bg-red-500/10 text-slate-400 hover:text-red-400 transition-colors"><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="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/></svg></button></div></div>))}</div>)}</div></div>);
};

// ===== MODAL =====
window.Modal = ({ bp, onClose }) => {
  const tt = window.useT();
  if (!bp) return null;
  return (
    <div className="fixed inset-0 bg-black/80 backdrop-blur-sm z-50 flex items-center justify-center p-4 fi" onClick={onClose}><div className="bg-[#0f0f23] border border-white/10 rounded-2xl max-w-2xl w-full max-h-[80vh] overflow-auto" onClick={e=>e.stopPropagation()}><div className="p-6 border-b border-white/5"><div className="flex items-center justify-between"><div><h2 className="text-xl font-bold text-white">{bp.name}</h2><p className="text-sm text-slate-500">{bp.fingerprint}</p></div><button onClick={onClose} className="p-2 rounded-lg hover:bg-white/5 text-slate-400"><window.IconX/></button></div></div><div className="p-6"><div className="grid grid-cols-2 gap-4 mb-6"><div className="bg-white/[.03] border border-white/5 rounded-xl p-4 text-center"><div className="text-2xl font-bold text-indigo-300">{bp.score}</div><div className="text-xs text-slate-500 mt-1">{tt('modal.score')}</div></div><div className="bg-white/[.03] border border-white/5 rounded-xl p-4 text-center"><div className="text-2xl font-bold text-indigo-300">{bp.entities}</div><div className="text-xs text-slate-500 mt-1">{tt('modal.entities')}</div></div><div className="bg-white/[.03] border border-white/5 rounded-xl p-4 text-center"><div className="text-2xl font-bold text-indigo-300">{bp.workflows}</div><div className="text-xs text-slate-500 mt-1">{tt('modal.workflows')}</div></div><div className="bg-white/[.03] border border-white/5 rounded-xl p-4 text-center"><div className="text-2xl font-bold text-indigo-300">{bp.sessions}</div><div className="text-xs text-slate-500 mt-1">{tt('dashboard.sessions')}</div></div></div><div className="flex items-center gap-3"><button className="flex-1 flex items-center justify-center gap-2 px-4 py-2.5 rounded-xl bg-indigo-600 hover:bg-indigo-500 text-white text-sm font-medium"><window.IconExport/> {tt('modal.exportLabel')}</button><button onClick={onClose} className="px-4 py-2.5 rounded-xl bg-white/5 hover:bg-white/10 text-slate-300 text-sm">{tt('dashboard.view')==='Ver'?'Cerrar':'Close'}</button></div></div></div></div>);
};

// ===== DOCS =====
window.Docs = ({ session, blueprint, forensic }) => {
  const tt = window.useT();
  const roadmap = tt('docs.roadmap', { returnObjects: true });
  const { lang } = window.useLang();
  
  // Mostrar datos dinámicos si están disponibles
  const hasDynamicData = blueprint && forensic;
  
  return (
    <div className="min-h-screen pt-16 pb-12 px-4 fi">
      <div className="max-w-7xl mx-auto">
        <h1 className="text-2xl font-bold text-white mb-6">{tt('docs.title')}</h1>
        
        {/* Mostrar resumen de sesión si hay datos dinámicos */}
        {hasDynamicData && session && (
          <div className="bg-gradient-to-br from-indigo-600/10 to-purple-600/10 border border-indigo-500/20 rounded-xl p-6 mb-8">
            <h2 className="text-lg font-semibold text-white mb-2">{lang === 'es' ? 'Análisis Generado por IA' : 'AI-Generated Analysis'}</h2>
            <p className="text-slate-300 text-sm mb-4">{session.idea}</p>
            <div className="flex gap-4 text-xs">
              <span className="px-2 py-1 rounded bg-indigo-500/20 text-indigo-300">{blueprint.entities?.length || 0} {lang === 'es' ? 'entidades' : 'entities'}</span>
              <span className="px-2 py-1 rounded bg-purple-500/20 text-purple-300">{blueprint.brechas?.length || 0} {lang === 'es' ? 'brechas' : 'gaps'}</span>
              <span className="px-2 py-1 rounded bg-green-500/20 text-green-300">{(blueprint.confidence * 100)?.toFixed(0)}% {lang === 'es' ? 'confianza' : 'confidence'}</span>
            </div>
          </div>
        )}
        
        {/* Roadmap Section */}
        <div className="mb-12 space-y-8">
          <h2 className="text-xl font-bold text-indigo-300 mb-2">{roadmap.title}</h2>
          <p className="text-slate-400 mb-4">{roadmap.subtitle}</p>
          
          <div className="bg-white/[.03] border border-white/5 rounded-xl p-6 mb-6">
            <p className="text-slate-300 mb-4">{roadmap.intro}</p>
          </div>
          
          {/* Layers Table */}
          <div className="bg-white/[.03] border border-white/5 rounded-xl p-6 mb-6">
            <h3 className="text-lg font-semibold text-white mb-3">{roadmap.layersTitle}</h3>
            <p className="text-slate-400 mb-4">{roadmap.layersDesc}</p>
            <div className="overflow-x-auto">
              <table className="w-full text-sm">
                <thead>
                  <tr className="border-b border-white/10">
                    {roadmap.layersTable.headers.map((h, i) => (
                      <th key={i} className="text-left py-2 px-3 text-indigo-300 font-semibold">{h}</th>
                    ))}
                  </tr>
                </thead>
                <tbody>
                  {roadmap.layersTable.rows.map((row, i) => (
                    <tr key={i} className="border-b border-white/5 last:border-0">
                      {row.map((cell, j) => (
                        <td key={j} className="py-3 px-3 text-slate-300">{cell}</td>
                      ))}
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
            {roadmap.layersConsequence && <p className="text-slate-400 mt-4 italic">{roadmap.layersConsequence}</p>}
          </div>
          
          {/* Universal Section */}
          <div className="bg-white/[.03] border border-white/5 rounded-xl p-6 mb-6">
            <h3 className="text-lg font-semibold text-white mb-3">{roadmap.universalTitle}</h3>
            <p className="text-slate-400 mb-4">{roadmap.universalDesc}</p>
            <ul className="grid grid-cols-1 md:grid-cols-2 gap-2">
              {roadmap.domains.map((d, i) => (
                <li key={i} className="flex items-start gap-2 text-sm text-slate-300">
                  <span className="w-1.5 h-1.5 rounded-full bg-indigo-400 mt-1.5 flex-shrink-0"></span>
                  {d}
                </li>
              ))}
            </ul>
          </div>
          
          {/* Advantages */}
          <div className="mb-6">
            <h3 className="text-lg font-semibold text-white mb-4">{roadmap.advantagesTitle}</h3>
            {roadmap.advantagesIntro && <p className="text-slate-400 mb-4">{roadmap.advantagesIntro}</p>}
            <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
              {roadmap.advantages.map((adv, i) => (
                <div key={i} className="bg-white/[.03] border border-white/5 rounded-xl p-4">
                  <h4 className="text-sm font-semibold text-indigo-300 mb-2">{adv.title}</h4>
                  <p className="text-xs text-slate-400 leading-relaxed">{adv.desc}</p>
                </div>
              ))}
            </div>
          </div>
          
          {/* Timeline */}
          <div className="bg-white/[.03] border border-white/5 rounded-xl p-6 mb-6">
            <h3 className="text-lg font-semibold text-white mb-4">{roadmap.timelineTitle}</h3>
            {roadmap.prototypeDesc && <p className="text-slate-400 mb-4">{roadmap.prototypeDesc}</p>}
            <div className="space-y-4">
              {roadmap.phases.map((phase, i) => (
                <div key={i} className="pb-4 border-b border-white/5 last:border-0 last:pb-0">
                  <div className="flex gap-4 mb-2">
                    {phase.weeks && (
                      <div className="flex-shrink-0 w-16 h-16 rounded-lg bg-indigo-600/20 border border-indigo-500/30 flex items-center justify-center">
                        <span className="text-xs font-bold text-indigo-300">{phase.weeks}</span>
                      </div>
                    )}
                    <div className="flex-1">
                      <h4 className="text-sm font-semibold text-white mb-1">{phase.name}</h4>
                      {phase.objective && <p className="text-xs text-slate-400 mb-2"><span className="font-semibold text-indigo-300">Objetivo:</span> {phase.objective}</p>}
                      {phase.result && <p className="text-xs text-slate-400 mb-2"><span className="font-semibold text-green-300">Resultado tangible:</span> {phase.result}</p>}
                      {phase.metric && <p className="text-xs text-slate-400"><span className="font-semibold text-purple-300">Métrica de éxito:</span> {phase.metric}</p>}
                    </div>
                  </div>
                </div>
              ))}
            </div>
          </div>
          
          {/* Milestones */}
          <div className="mb-6">
            <h3 className="text-lg font-semibold text-white mb-4">{roadmap.milestonesTitle}</h3>
            <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
              {roadmap.milestones.map((m, i) => (
                <div key={i} className="bg-gradient-to-br from-indigo-600/10 to-purple-600/10 border border-indigo-500/20 rounded-xl p-4">
                  <div className="text-xs font-bold text-indigo-400 mb-2">{m.week}</div>
                  <h4 className="text-sm font-semibold text-white mb-2">{m.milestone}</h4>
                  <p className="text-xs text-slate-400">{m.outcome}</p>
                </div>
              ))}
            </div>
          </div>
          
          {/* Quality Section */}
          {roadmap.qualityTitle && (
            <div className="bg-white/[.03] border border-white/5 rounded-xl p-6 mb-6">
              <h3 className="text-lg font-semibold text-white mb-3">{roadmap.qualityTitle}</h3>
              <p className="text-slate-400">{roadmap.qualityDesc}</p>
            </div>
          )}
          
          {/* Risks Section */}
          {roadmap.risksTitle && (
            <div className="bg-white/[.03] border border-white/5 rounded-xl p-6 mb-6">
              <h3 className="text-lg font-semibold text-white mb-4">{roadmap.risksTitle}</h3>
              <div className="space-y-4">
                {roadmap.risks.map((risk, i) => (
                  <div key={i} className="bg-white/[.02] border border-white/5 rounded-lg p-4">
                    <h4 className="text-sm font-semibold text-red-300 mb-2">{risk.title}</h4>
                    <p className="text-xs text-slate-400">{risk.desc}</p>
                  </div>
                ))}
              </div>
            </div>
          )}
          
          {/* Monetization Section */}
          {roadmap.monetizationTitle && (
            <div className="bg-white/[.03] border border-white/5 rounded-xl p-6 mb-6">
              <h3 className="text-lg font-semibold text-white mb-4">{roadmap.monetizationTitle}</h3>
              <div className="overflow-x-auto mb-4">
                <table className="w-full text-sm">
                  <thead>
                    <tr className="border-b border-white/10">
                      {roadmap.monetizationTable.headers.map((h, i) => (
                        <th key={i} className="text-left py-2 px-3 text-indigo-300 font-semibold">{h}</th>
                      ))}
                    </tr>
                  </thead>
                  <tbody>
                    {roadmap.monetizationTable.rows.map((row, i) => (
                      <tr key={i} className="border-b border-white/5 last:border-0">
                        {row.map((cell, j) => (
                          <td key={j} className="py-3 px-3 text-slate-300">{cell}</td>
                        ))}
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
              <p className="text-slate-400">{roadmap.monetizationDesc}</p>
            </div>
          )}
          
          {/* Acquisition Section */}
          {roadmap.acquisitionTitle && (
            <div className="bg-white/[.03] border border-white/5 rounded-xl p-6 mb-6">
              <h3 className="text-lg font-semibold text-white mb-4">{roadmap.acquisitionTitle}</h3>
              <p className="text-slate-400 mb-4">{roadmap.acquisitionDesc}</p>
              <div className="space-y-4">
                {roadmap.acquisitionChannels.map((channel, i) => (
                  <div key={i} className="bg-white/[.02] border border-white/5 rounded-lg p-4">
                    <h4 className="text-sm font-semibold text-indigo-300 mb-2">{channel.title}</h4>
                    <p className="text-xs text-slate-400">{channel.desc}</p>
                  </div>
                ))}
              </div>
              <p className="text-slate-400 mt-4 italic">{roadmap.acquisitionGoal}</p>
            </div>
          )}
          
          {/* Moat Section */}
          {roadmap.moatTitle && (
            <div className="bg-white/[.03] border border-white/5 rounded-xl p-6 mb-6">
              <h3 className="text-lg font-semibold text-white mb-4">{roadmap.moatTitle}</h3>
              <p className="text-slate-400 mb-4">{roadmap.moatDesc}</p>
              <div className="space-y-4">
                {roadmap.moatAdvantages.map((adv, i) => (
                  <div key={i} className="bg-white/[.02] border border-white/5 rounded-lg p-4">
                    <h4 className="text-sm font-semibold text-green-300 mb-2">{adv.title}</h4>
                    <p className="text-xs text-slate-400">{adv.desc}</p>
                  </div>
                ))}
              </div>
            </div>
          )}
          
          {/* Origin Section */}
          {roadmap.originTitle && (
            <div className="bg-white/[.03] border border-white/5 rounded-xl p-6 mb-6">
              <h3 className="text-lg font-semibold text-white mb-4">{roadmap.originTitle}</h3>
              <p className="text-slate-400">{roadmap.originDesc}</p>
            </div>
          )}
          
          {/* Vision Section */}
          {roadmap.visionTitle && (
            <div className="bg-gradient-to-br from-indigo-600/10 to-purple-600/10 border border-indigo-500/20 rounded-xl p-6">
              <h3 className="text-lg font-semibold text-white mb-4">{roadmap.visionTitle}</h3>
              <p className="text-slate-300">{roadmap.visionDesc}</p>
            </div>
          )}
        </div>
        
        {/* Original Docs Content */}
        <div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-8">
          {tt('docs.archCards',{returnObjects:true}).map((card,i)=>(
            <div key={i} className="bg-white/[.03] border border-white/5 rounded-xl p-4">
              <h3 className="text-sm font-semibold text-white mb-1">{card.n}</h3>
              <p className="text-xs text-slate-400 mb-2">{card.t}</p>
              <span className="text-[10px] px-2 py-0.5 rounded bg-green-500/10 text-green-400">{card.m}</span>
            </div>
          ))}
        </div>
        <div className="bg-white/[.03] border border-white/5 rounded-xl p-4 mb-6">
          <h3 className="text-sm font-semibold text-white mb-3">API Endpoints</h3>
          <div className="space-y-2">
            {tt('docs.apiEndpoints',{returnObjects:true}).map((ep,i)=>(
              <div key={i} className="flex items-center gap-3 text-xs font-mono">
                <span className={`px-2 py-1 rounded ${ep.m==='POST'?'bg-green-500/10 text-green-400':ep.m==='PUT'?'bg-blue-500/10 text-blue-400':'bg-slate-500/10 text-slate-400'}`}>{ep.m}</span>
                <span className="text-slate-300">{ep.p}</span>
              </div>
            ))}
          </div>
        </div>
        <div className="bg-white/[.03] border border-white/5 rounded-xl p-4 mb-6">
          <h3 className="text-sm font-semibold text-white mb-3">Schema SQL</h3>
          <pre className="text-xs text-slate-400 font-mono whitespace-pre overflow-x-auto">{tt('docs.schemaSQL')}</pre>
        </div>
        <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
          {tt('docs.securityCards',{returnObjects:true}).map((card,i)=>(
            <div key={i} className="bg-white/[.03] border border-white/5 rounded-xl p-4">
              <h3 className="text-sm font-semibold text-white mb-2">{card.t}</h3>
              <ul className="space-y-1">
                {card.items.map((item,j)=>(
                  <li key={j} className="text-xs text-slate-400 flex items-center gap-1.5">
                    <span className="w-1 h-1 rounded-full bg-indigo-400"/>{item}
                  </li>
                ))}
              </ul>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
};

// ===== APP PRINCIPAL =====
function App() {
  const [page, setPage] = React.useState('home');
  const [session, setSession] = React.useState(null);
  const [extractionData, setExtractionData] = React.useState(null);
  const [blueprintData, setBlueprintData] = React.useState(null);
  const [forensicData, setForensicData] = React.useState(null);
  const [lang, setLang] = React.useState('es');
  const [toasts, setToasts] = React.useState([]);

  const addToast = (msg, type = 'info') => {
    const id = Date.now();
    setToasts(prev => [...prev, { id, msg, type }]);
    setTimeout(() => setToasts(prev => prev.filter(t => t.id !== id)), 3000);
  };

  // CONEXIÓN CON BACKEND IA
  const handleStart = async (idea, mode, domain) => {
    try {
      addToast(lang === 'es' ? 'Analizando con IA...' : 'Analyzing with AI...', 'info');
      
      const response = await fetch('/api/extract', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ idea, domain, lang })
      });

      if (!response.ok) throw new Error('Error en análisis IA');
      
      const analysis = await response.json();
      
      setExtractionData({
        entities: analysis.entities || [],
        workflows: analysis.workflows || [],
        brechas: analysis.brechas || [],
        confidence: analysis.confidence || 0.5
      });
      
      setSession({ idea, mode, domain });
      setPage('extraction');
      addToast(lang === 'es' ? '¡Análisis completado!' : 'Analysis complete!', 'success');
    } catch (error) {
      console.error('Error:', error);
      addToast(lang === 'es' ? 'Error al analizar' : 'Error analyzing', 'error');
    }
  };

  const handleExtractionComplete = (data) => {
    setExtractionData(prev => ({ ...prev, ...data }));
    setBlueprintData({ extraction: data, session });
    setPage('blueprint');
  };

  const handleBlueprintComplete = (data) => {
    setBlueprintData(prev => ({ ...prev, ...data }));
    
    if (session.mode === 'forense') {
      setPage('forensic');
    } else {
      setForensicData(data);
      setPage('docs');
    }
  };

  const handleForensicComplete = (data) => {
    setForensicData(data);
    setPage('docs');
  };

  return (
    <window.LangContext.Provider value={{ lang, setLang }}>
      <window.Nav page={page} setPage={setPage} />
      <window.Toasts items={toasts} />
      
      {page === 'home' && <window.Home onStart={handleStart} />}
      {page === 'extraction' && extractionData && (
        <window.Extraction 
          idea={session.idea} 
          domain={session.domain}
          initialData={extractionData}
          onComplete={handleExtractionComplete}
          onBack={() => setPage('home')}
        />
      )}
      {page === 'blueprint' && blueprintData && (
        <window.Blueprint 
          extraction={blueprintData.extraction}
          session={session}
          onComplete={handleBlueprintComplete}
          onBack={() => setPage('extraction')}
        />
      )}
      {page === 'forensic' && (
        <window.Forensic 
          session={session}
          onComplete={handleForensicComplete}
          onBack={() => setPage('blueprint')}
        />
      )}
      {page === 'docs' && forensicData && (
        <window.Docs 
          session={session}
          blueprint={blueprintData}
          forensic={forensicData}
        />
      )}
      {page === 'dashboard' && (
        <div className="min-h-screen pt-20 pb-12 px-4 fi">
          <div className="max-w-4xl mx-auto text-center">
            <h1 className="text-3xl font-bold text-white mb-4">Dashboard</h1>
            <p className="text-slate-400">{lang === 'es' ? 'Próximamente: Historial de análisis y métricas' : 'Coming soon: Analysis history and metrics'}</p>
          </div>
        </div>
      )}
    </window.LangContext.Provider>
  );
}

// Renderizar aplicación
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);