// SIMULADOR LAUNCHER — carga HTML en iframe, gestiona límite de intentos y guarda resultados

window.SimuladorLauncher = function SimuladorLauncher({ navigate, store, pruebaId, modo }) {
  const PRUEBAS    = store.pruebas || window.SD_SEED.PRUEBAS;
  const prueba     = PRUEBAS.find(p => p.id === pruebaId);
  const isCompleto = modo === 'completo';

  if (!store.session) { navigate('/login'); return null; }
  if (!prueba) {
    return (
      <div style={{ padding: 60, textAlign: 'center' }}>
        <h3>Prueba no encontrada</h3>
        <button className="btn btn-ghost" style={{ marginTop: 16 }} onClick={() => navigate('/dashboard')}>← Volver</button>
      </div>
    );
  }

  if (isCompleto && !store.hasPremium(pruebaId)) {
    return (
      <div>
        <window.DashHeader navigate={navigate} store={store} />
        <div className="container container-narrow" style={{ paddingTop: 60, paddingBottom: 80 }}>
          <div className="card card-pad-lg" style={{ textAlign: 'center' }}>
            <div style={{ fontSize: 48 }}>{prueba.icono || '🔒'}</div>
            <h2 style={{ marginTop: 16 }}>Simulador completo — acceso premium</h2>
            <p className="muted" style={{ marginTop: 12, fontSize: 15, lineHeight: 1.6 }}>
              Desbloquea <strong>{prueba.nombre}</strong> con un pago único de{' '}
              <strong>{window.formatPrice(prueba.precio || prueba.precio_mxn)}</strong>.
            </p>
            <div className="row gap-3" style={{ justifyContent: 'center', marginTop: 28 }}>
              <button className="btn btn-ghost btn-lg" onClick={() => navigate(`/simulador/${pruebaId}/muestra`)}>
                Probar muestra gratis
              </button>
              <button className="btn btn-amber btn-lg"
                onClick={() => { store.addToCart(pruebaId); navigate('/checkout'); }}>
                ★ Desbloquear · {window.formatPrice(prueba.precio || prueba.precio_mxn)}
              </button>
            </div>
          </div>
        </div>
      </div>
    );
  }

  return <SimuladorFrame prueba={prueba} modo={modo} isCompleto={isCompleto} navigate={navigate} store={store} />;
};

// ── Frame: pide URL al API, respeta límite, inyecta monitor ──
function SimuladorFrame({ prueba, modo, isCompleto, navigate, store }) {
  const BASE = window.API_BASE || '/simuladordocente/api';

  const [iframeUrl,    setIframeUrl]    = React.useState(null);
  const [resultadoId,  setResultadoId]  = React.useState(null);
  const [intentosInfo, setIntentosInfo] = React.useState(null); // { intentos_usados, limite }
  const [limiteMsg,    setLimiteMsg]    = React.useState(null); // objeto si límite alcanzado
  const [error,        setError]        = React.useState('');
  const [loading,      setLoading]      = React.useState(true);

  const iframeRef  = React.useRef(null);
  const lsSnapshot = React.useRef({});
  const startTime  = React.useRef(Date.now());
  const savedRef   = React.useRef(null); // null | 'noScore' | 'withScore'

  // ── 1. Solicitar URL al API ───────────────────────────────
  React.useEffect(() => {
    const tok = localStorage.getItem('sd_token');
    if (!tok) { setLoading(false); return; }

    fetch(`${BASE}/pruebas/${prueba.id}/abrir/${modo}`, {
      headers: { Authorization: `Bearer ${tok}` }
    })
      .then(r => r.json().then(d => ({ ok: r.ok, d })))
      .then(({ ok, d }) => {
        if (!ok) {
          if (d.error === 'limite_alcanzado') {
            setLimiteMsg(d);
          } else {
            setError(d.error || 'No se pudo cargar');
          }
        } else {
          setIframeUrl(d.url);
          setResultadoId(d.resultado_id);
          setIntentosInfo({ intentos_usados: d.intentos_usados, limite: d.limite });
          startTime.current = Date.now();
        }
        setLoading(false);
      })
      .catch(() => { setError('Error de conexión'); setLoading(false); });
  }, [prueba.id, modo]);

  // ── 2. Inyectar monitor cuando el iframe carga ────────────
  const onIframeLoad = () => {
    // Snapshot inicial de localStorage
    const snap = {};
    for (let i = 0; i < localStorage.length; i++) {
      const k = localStorage.key(i); snap[k] = localStorage.getItem(k);
    }
    lsSnapshot.current = snap;

    try {
      const doc = iframeRef.current?.contentDocument;
      if (!doc) return;
      const s = doc.createElement('script');
      // Monitor que:
      // 1. Se engancha en mostrarResultados() si existe (biología y similares)
      // 2. Copia localStorage + variables globales de score
      // 3. Vigila clicks en botones de finalizar
      s.textContent = `(function(){
        function capturar(){
          var ls={};
          for(var i=0;i<localStorage.length;i++){var k=localStorage.key(i);ls[k]=localStorage.getItem(k);}
          var extras={};

          /* DOM scraping — pct ya es 0-100 en .score-sub */
          var sub=document.querySelector('.score-sub');
          if(sub){var m=sub.textContent.match(/(\\d+(?:\\.\\d+)?)%/);if(m)extras.pct=parseFloat(m[1]);}
          var big=document.querySelector('.score-big');
          if(big){
            var m2=big.textContent.match(/^(\\d+)/);if(m2)extras.total_aciertos=parseInt(m2[1]);
            var m3=big.textContent.match(/\\/(\\d+)/);if(m3)extras.max_aciertos=parseInt(m3[1]);
          }
          var niv=document.querySelector('.nivel-txt');
          if(niv)extras.nivel_texto=niv.textContent.trim();

          /* _examenData — q.d es el tipo ('analisis'/'comprension'), r.nivel es nivel de respuesta */
          try{
            if(window._examenData&&Array.isArray(window._examenData)){
              extras._examenData=window._examenData.map(function(item){
                return{
                  tipo:   item.q&&item.q.d,
                  chosen: item.r&&item.r.chosen,
                  correct:item.r&&item.r.opt&&item.r.opt.l
                };
              });
            }
          }catch(e){}

          window.parent.postMessage({type:'sim_resultado',datos:ls,extras:extras},'*');
        }

        /* Enganche a mostrarResultados() — función global en el simulador */
        if(typeof mostrarResultados==='function'){
          var _orig=mostrarResultados;
          mostrarResultados=function(){
            _orig.apply(this,arguments);
            setTimeout(capturar,600);
          };
        }

        /* Listener para petición explícita del parent */
        window.addEventListener('message',function(e){
          if(e.data&&e.data.type==='request_capture')capturar();
        });

        /* Fallback: clicks en botones de resultado/finalizar */
        document.addEventListener('click',function(e){
          var txt=(e.target.textContent||e.target.innerText||'').toLowerCase();
          if(/finaliz|termina|resultado|calific|ver res|guardar|submit|finish/i.test(txt))
            setTimeout(capturar,900);
        },true);

        window.addEventListener('beforeunload',capturar);
      })();`;
      doc.head.appendChild(s);
    } catch {}
  };

  // ── 3a. Parent escucha storage events del iframe (mismo origen) ──
  React.useEffect(() => {
    if (!iframeUrl) return;
    const handler = () => {
      // El iframe escribió localStorage → pedir captura
      iframeRef.current?.contentWindow?.postMessage({ type: 'request_capture' }, '*');
    };
    window.addEventListener('storage', handler);
    return () => window.removeEventListener('storage', handler);
  }, [iframeUrl]);

  // ── 3b. Recibir resultado del iframe ──────────────────────
  React.useEffect(() => {
    const handler = (e) => {
      if (e.data?.type !== 'sim_resultado') return;
      guardarResultado(e.data.datos, e.data.extras);
    };
    window.addEventListener('message', handler);
    return () => window.removeEventListener('message', handler);
  }, [resultadoId]);

  // ── 4. Guardar / actualizar resultado en API ──────────────
  const guardarResultado = React.useCallback((datosIframe, extras) => {
    if (!resultadoId) return;
    const hasScore = extras?.pct != null;
    if (savedRef.current === 'withScore') return;
    if (savedRef.current === 'noScore' && !hasScore) return;

    const tok = localStorage.getItem('sd_token');
    if (!tok) return;

    const changed = {};
    if (datosIframe) {
      Object.keys(datosIframe).forEach(k => {
        if (lsSnapshot.current[k] !== datosIframe[k]) changed[k] = datosIframe[k];
      });
    }
    if (extras && Object.keys(extras).length) changed._sim_extras = extras;

    // pct ya viene 0-100 del DOM (.score-sub)
    const calificacion = hasScore ? parseFloat(extras.pct) : null;

    fetch(`${BASE}/resultados/${resultadoId}`, {
      method: 'PUT',
      headers: { Authorization: `Bearer ${tok}`, 'Content-Type': 'application/json' },
      body: JSON.stringify({
        calificacion,
        datos:        Object.keys(changed).length ? changed : null,
        duracion_seg: Math.round((Date.now() - startTime.current) / 1000),
      }),
    }).catch(() => {});

    savedRef.current = calificacion !== null ? 'withScore' : 'noScore';
  }, [resultadoId]);

  const salir = () => {
    // Si no se guardó con score, registrar al menos la duración
    if (savedRef.current !== 'withScore' && resultadoId) {
      const tok = localStorage.getItem('sd_token');
      if (tok) {
        fetch(`${BASE}/resultados/${resultadoId}`, {
          method: 'PUT',
          headers: { Authorization: `Bearer ${tok}`, 'Content-Type': 'application/json' },
          body: JSON.stringify({ duracion_seg: Math.round((Date.now() - startTime.current) / 1000) }),
          keepalive: true,
        }).catch(() => {});
      }
    }
    navigate('/dashboard');
  };

  // ── Pantalla: límite alcanzado ────────────────────────────
  if (limiteMsg) {
    const esCompleto = limiteMsg.modo === 'completo';
    return (
      <div>
        <window.DashHeader navigate={navigate} store={store} />
        <div className="container container-narrow" style={{ paddingTop: 60, paddingBottom: 80 }}>
          <div className="card card-pad-lg" style={{ textAlign: 'center' }}>
            <div style={{ fontSize: 48 }}>🔒</div>
            <h2 style={{ marginTop: 16 }}>
              {esCompleto ? 'Has agotado tus intentos del simulador completo' : 'Has usado todos tus intentos gratuitos'}
            </h2>
            <p className="muted" style={{ marginTop: 12, fontSize: 15, lineHeight: 1.6 }}>
              {esCompleto
                ? <>Usaste tus <strong>{limiteMsg.limite} intentos</strong> del simulador completo de{' '}
                    <strong>{prueba.nombre}</strong>. Contacta al administrador para obtener más intentos.</>
                : <>Usaste tus <strong>{limiteMsg.limite} intentos</strong> de muestra para{' '}
                    <strong>{prueba.nombre}</strong>. Desbloquea el simulador completo para acceso ampliado.</>}
            </p>
            <div style={{ display:'flex', gap:6, justifyContent:'center', margin:'24px auto', maxWidth:200 }}>
              {Array.from({length: limiteMsg.limite}).map((_,i) => (
                <div key={i} style={{ flex:1, height:10, borderRadius:5, background: esCompleto ? 'var(--amber)' : 'var(--teal)' }}/>
              ))}
            </div>
            <div className="row gap-3" style={{ justifyContent: 'center', marginTop: 8 }}>
              <button className="btn btn-ghost btn-lg" onClick={() => navigate('/dashboard')}>
                ← Volver al panel
              </button>
              {!esCompleto && (
                <button className="btn btn-amber btn-lg"
                  onClick={() => { store.addToCart(prueba.id); navigate('/checkout'); }}>
                  ★ Desbloquear · {window.formatPrice(prueba.precio || prueba.precio_mxn)}
                </button>
              )}
            </div>
          </div>
        </div>
      </div>
    );
  }

  // ── Render principal ──────────────────────────────────────
  return (
    <div className="simulador-launcher">
      <div className="sim-bar">
        <button className="btn btn-ghost btn-sm" onClick={salir}>← Salir</button>
        <div className="sim-bar-title">
          {prueba.icono} <strong>{prueba.nombre}</strong>
          {isCompleto
            ? <span className="pill pill-amber" style={{ marginLeft: 10 }}>★ Completo</span>
            : <span className="pill pill-teal"  style={{ marginLeft: 10 }}>Muestra</span>}
        </div>
        <div style={{ fontSize: 12, color: 'rgba(255,255,255,0.6)' }}>
          {intentosInfo?.limite && !isCompleto
            ? `${intentosInfo.intentos_usados}/${intentosInfo.limite} intentos`
            : 'Acceso desbloqueado'}
        </div>
      </div>

      <div className="sim-frame">
        {loading && (
          <div className="sim-center">
            <div style={{ fontSize: 36 }}>⏳</div>
            <p style={{ marginTop: 12, color: 'var(--muted)' }}>Cargando simulador…</p>
          </div>
        )}
        {!loading && error && (
          <div className="sim-center">
            <div style={{ fontSize: 48 }}>📭</div>
            <h3 style={{ marginTop: 16 }}>Simulador no disponible</h3>
            <p className="muted" style={{ marginTop: 10, fontSize: 14 }}>{error}</p>
            <p className="muted" style={{ fontSize: 13, marginTop: 6 }}>El administrador aún no ha subido el archivo HTML.</p>
            <button className="btn btn-ghost" style={{ marginTop: 20 }} onClick={() => navigate('/dashboard')}>
              ← Volver al panel
            </button>
          </div>
        )}
        {!loading && !error && iframeUrl && (
          <iframe
            ref={iframeRef}
            src={iframeUrl}
            title={prueba.nombre}
            className="sim-iframe"
            allow="fullscreen"
            onLoad={onIframeLoad}
          />
        )}
        {!loading && !error && !iframeUrl && (
          <div className="sim-center">
            <div className="sim-mock">
              <div style={{ fontSize: 48 }}>📝</div>
              <h3 style={{ marginTop: 12 }}>Modo demo</h3>
              <p className="muted" style={{ marginTop: 10, fontSize: 14 }}>
                Inicia sesión con una cuenta real para abrir el simulador.
              </p>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}
