/* SportK — Pantalla del entrenador activo (timer pro), Summary, Tests y Create. */

const { useState: useStateA, useEffect: useEffectA, useRef: useRefA, useMemo: useMemoA } = React;

// ============================================================
// ENTRENADOR ACTIVO — usa useTimerEngine + Feedback
// ============================================================
function ActiveScreen({ store, navigate, params }) {
  const { state, completeSession } = store;
  const all = [...PRESET_ROUTINES, ...state.customRoutines];
  const baseRoutine = all.find((r) => r.id === params.routineId);

  const [eyesClosed, setEyesClosed] = useStateA(false);
  const [completedAt, setCompletedAt] = useStateA(null);
  const lastHoldTickRef = useRefA(0);

  // Modo "con estimulación": el usuario eligió en la pantalla de detalle el ciclo
  // Stop-Start clínico (fase 'arousal' tap-controlada antes de cada Edge).
  // Sólo afecta a ejercicios de tipo 'edging-hold'.
  const withArousal = !!params.withArousal;
  const routine = useMemoA(() => {
    if (!baseRoutine) return null;
    if (!withArousal) return baseRoutine;
    return {
      ...baseRoutine,
      exercises: baseRoutine.exercises.map((ex) =>
        ex.type === "edging-hold" || ex.type === "edge" ? { ...ex, withArousal: true } : ex
      ),
    };
  }, [baseRoutine, withArousal]);

  // Inicializa Feedback con preferencias + desbloquea AudioContext.
  useEffectA(() => {
    if (!window.Feedback) return;
    Feedback.setPrefs({
      soundOn: state.profile.preferences.soundOn,
      hapticOn: state.profile.preferences.hapticOn,
      volume: state.profile.preferences.volume,
    });
    Feedback.unlock();
  }, []);

  // Cuando la pestaña vuelve a ser visible tras pasar a background, los navegadores
  // suspenden el AudioContext (política de power-saving). Lo reanudamos automáticamente
  // para que los siguientes cues suenen sin que el usuario tenga que tocar la pantalla.
  useEffectA(() => {
    const onVisibility = () => {
      if (document.visibilityState === "visible" && window.Feedback) {
        Feedback.unlock();
      }
    };
    document.addEventListener("visibilitychange", onVisibility);
    return () => document.removeEventListener("visibilitychange", onVisibility);
  }, []);

  // Wake Lock de pantalla durante la sesión activa: evita que el móvil bloquee
  // la pantalla durante un edging hold de 60s o un descanso largo. Se libera al
  // desmontar la pantalla (sesión completa, salida, o navegación).
  useEffectA(() => {
    let wakeLock = null;
    let released = false;
    const acquire = async () => {
      try {
        if (navigator.wakeLock && navigator.wakeLock.request) {
          wakeLock = await navigator.wakeLock.request("screen");
        }
      } catch (e) {}
    };
    const onVisibility = () => {
      if (document.visibilityState === "visible" && !released) acquire();
    };
    acquire();
    document.addEventListener("visibilitychange", onVisibility);
    return () => {
      released = true;
      document.removeEventListener("visibilitychange", onVisibility);
      try { if (wakeLock && wakeLock.release) wakeLock.release(); } catch (e) {}
    };
  }, []);

  const onPhaseChange = (phase, info) => {
    if (window.Feedback) Feedback.cuePhase(phase, info);
    lastHoldTickRef.current = 0;
  };

  const onTick = (msIn, msTot, segment) => {
    if (!segment) return;
    if (segment.phase === "hold" && msTot >= 3000) {
      const sec = Math.floor(msIn / 1000);
      if (sec !== lastHoldTickRef.current && sec > 0 && sec < Math.floor(msTot / 1000)) {
        lastHoldTickRef.current = sec;
        if (window.Feedback) Feedback.cuePhase("tick");
      }
      return;
    }
    // Fase 'arousal' (espera del PONR): beep cálido cada segundo como recordatorio
    // sensorial mientras el usuario sube la excitación. Empieza a partir del segundo 1.
    if (segment.untilTap && segment.phase === "arousal") {
      const sec = Math.floor(msIn / 1000);
      if (sec !== lastHoldTickRef.current && sec > 0) {
        lastHoldTickRef.current = sec;
        if (window.Feedback) Feedback.cuePhase("arousal-tick");
      }
    }
  };

  const onComplete = (stats) => {
    if (window.Feedback) Feedback.cuePhase("session-complete");
    const durationSec = Math.round(stats.elapsedMs / 1000);
    setCompletedAt({
      routineId: routine && routine.id,
      routineName: routine && routine.name,
      track: routine && routine.track,
      totalReps: stats.totalCompletedReps,
      totalSets: routine ? routine.exercises.length : 0,
      durationSec,
      perExercise: stats.perExercise,
    });
  };

  // Hook siempre llamado, con fallback para mantener regla de hooks.
  const engine = useTimerEngine(routine || { exercises: [] }, { onPhaseChange, onTick, onComplete });

  if (!routine) {
    const tt = window.t || ((k) => k);
    return (
      <div style={{ padding: 40 }}>
        {tt("detail.not_found")}
        <button className="btn btn-ghost" onClick={() => navigate("home")}>{tt("common.back")}</button>
      </div>
    );
  }

  if (completedAt) {
    return (
      <SummaryScreen
        session={completedAt}
        onClose={() => {
          completeSession(completedAt);
          navigate("home");
        }}
      />
    );
  }

  return (
    <ActiveTrainer
      engine={engine}
      routine={routine}
      eyesClosed={eyesClosed}
      setEyesClosed={setEyesClosed}
      navigate={navigate}
    />
  );
}

// ============================================================
// Componente visual del entrenador
// ============================================================
function ActiveTrainer({ engine, routine, eyesClosed, setEyesClosed, navigate }) {
  const tt = window.t || ((k) => k);
  const pk = window.pick || ((x) => x);
  const { exercise, exerciseIdx, repIdx, segment, phase, cue, intensity, msIntoPhase, msTotalPhase, isReverseRep, paused, overallProgress, controls } = engine;

  // Fase 'arousal' (tap-controlada): el motor no avanza por tiempo, el usuario pulsa cuando llega al PONR.
  const isArousal = !!(segment && segment.untilTap);

  // ¿Tiene este segmento cuenta numérica visible?
  const showNumber = segment && (segment.phase === "hold" || segment.phase === "peak") && msTotalPhase >= 3000;
  const secLeft = Math.max(0, Math.ceil((msTotalPhase - msIntoPhase) / 1000));

  // Tip rotativo (cambia por ejercicio para no distraer)
  const tip = useMemoA(() => getRandomTip(exerciseIdx + new Date().getDate()), [exerciseIdx]);

  // Anillo: progreso temporal del segmento actual.
  const ringProgress = msTotalPhase > 0 ? Math.min(1, msIntoPhase / msTotalPhase) : 0;
  // En fases de Sostén el aro queda fijo en el % de apriete (espejo de la barra),
  // así no se "llena solo" mientras el usuario aguanta. En el resto de fases
  // (inhalar / aprieta / soltar / reposo) avanza con el tiempo.
  const isHoldPhase = phase === "hold" || phase === "peak";
  const ringFill = isHoldPhase
    ? Math.max(0, Math.min(1, (intensity || 0) / 100))
    : ringProgress;
  const phaseColor = (window.PHASE_COLORS && PHASE_COLORS[phase]) || "var(--accent)";
  const phaseLbl = phase ? tt(`phase.${phase}`) : "";

  // Blob de respiración: escala según fase
  const blobScale = (() => {
    if (phase === "inhale") return 0.55 + 0.45 * ringProgress; // 0.55 → 1.0
    if (phase === "exhale") return 1.0 - 0.45 * ringProgress;  // 1.0 → 0.55
    if (phase === "contract" || phase === "hold" || phase === "peak") return 0.55;
    if (phase === "release") return 0.55 + 0.30 * ringProgress; // 0.55 → 0.85
    if (phase === "rest") return 0.85;
    if (phase === "reverse") return 1.0; // expansión hacia abajo (empuje)
    return 0.75;
  })();

  // Pulso visual extra para flicks (segments cortos)
  const isFlick = segment && segment.ms < 800 && segment.phase === "contract";

  // Pips con marker reverse
  const totalReps = (exercise && exercise.reps) || 1;
  const reverseEvery = (exercise && exercise.reverseEvery) || 0;

  if (eyesClosed) {
    return (
      <EyesClosedMode
        engine={engine}
        onTap={() => setEyesClosed(false)}
        controls={controls}
      />
    );
  }

  return (
    <div className={`exercise-active phase-${phase} ${paused ? "is-paused" : ""} ${isReverseRep ? "is-reverse-rep" : ""}`}>
      <div className="top">
        <button
          className="icon-btn"
          style={{ width: 40, height: 40 }}
          onClick={() => {
            if (confirm(tt("active.exit_confirm"))) navigate("home");
          }}
          aria-label={tt("common.close")}
        >
          <Icon.Close />
        </button>
        <div className="ex-counter">
          {exerciseIdx + 1} / {routine.exercises.length}
        </div>
        <button
          className="icon-btn"
          style={{ width: 40, height: 40 }}
          onClick={() => setEyesClosed(true)}
          aria-label={tt("active.eyes_closed")}
          title={tt("active.eyes_closed")}
        >
          <Icon.EyeClosed />
        </button>
      </div>

      <div className="progress-track">
        <div className="fill" style={{ width: `${overallProgress * 100}%` }} />
      </div>

      <div className="body">
        <div className="phase-pill" style={{ color: phaseColor, borderColor: phaseColor }}>
          {phaseLbl}
          {isReverseRep && <span className="reverse-tag">{tt("active.reverse_label")}</span>}
        </div>

        <div className="exercise-name">{exercise && pk(exercise.name)}</div>
        <div className="exercise-sub">
          {tt("active.rep_of", { n: Math.min(repIdx + 1, totalReps), total: totalReps })}
          {isReverseRep && ` · ${tt("active.reverse_inserted")}`}
        </div>

        {isArousal ? (
          <div className="arousal-zone" style={{ "--phase-c": phaseColor }}>
            <div className="arousal-hint">{cue || tt("active.arousal_hint")}</div>
            <button
              className="btn btn-primary btn-block btn-lg arousal-tap"
              onClick={() => controls.tapPONR()}
              aria-label={tt("active.tap_ponr")}
            >
              <Icon.Play width={16} height={16} /> {tt("active.tap_ponr")}
            </button>
            <div className="arousal-sub">{tt("active.arousal_sub")}</div>
          </div>
        ) : (
          <>
            <div className={`timer-ring-pro ${isFlick ? "is-flick" : ""}`} style={{ "--phase-c": phaseColor }}>
              <svg viewBox="0 0 280 280">
                <circle cx="140" cy="140" r="124" stroke="var(--line)" strokeWidth="6" fill="none" />
                <circle
                  cx="140" cy="140" r="124"
                  stroke="var(--phase-c)"
                  strokeWidth="8"
                  fill="none"
                  strokeLinecap="round"
                  strokeDasharray={2 * Math.PI * 124}
                  strokeDashoffset={(1 - ringFill) * 2 * Math.PI * 124}
                  style={{ transition: isHoldPhase ? "stroke-dashoffset 400ms ease-out" : (msTotalPhase < 800 ? "none" : "stroke-dashoffset 60ms linear") }}
                />
              </svg>
              <div className="breath-blob" style={{ transform: `translate(-50%, -50%) scale(${blobScale})`, background: `radial-gradient(circle at 40% 40%, var(--phase-c) 0%, color-mix(in oklch, var(--phase-c) 50%, transparent) 70%, transparent 100%)` }} />
              <div className="ring-inner">
                <div className="cue-text">{phaseLbl}</div>
                {showNumber && <div className="cue-number">{secLeft}</div>}
                {!showNumber && segment && segment.phase === "rest" && (
                  <div className="cue-sub">{Math.ceil((msTotalPhase - msIntoPhase) / 1000)}s</div>
                )}
              </div>
            </div>

            <div className="intensity-caption">{tt("active.intensity_caption")}</div>
            <div className="intensity-bar" aria-label={tt("active.intensity_aria")}>
              <div className="intensity-fill" style={{ width: `${Math.max(0, intensity)}%`, background: phaseColor }} />
              {intensity < 0 && (
                <div className="intensity-fill reverse" style={{ width: `${Math.min(100, -intensity)}%` }} />
              )}
              <div className="intensity-label">
                {intensity > 0 && `${intensity}%`}
                {intensity === 0 && "—"}
                {intensity < 0 && tt("active.intensity_push")}
              </div>
            </div>
          </>
        )}

        <div className="rep-counter-pro">
          {Array.from({ length: totalReps }).map((_, i) => {
            const isReverseMark = reverseEvery > 0 && (i + 1) % reverseEvery === 0;
            const done = i < repIdx || (i === repIdx && (segment && (segment.phase === "rest" || segment.phase === "release")));
            return (
              <div
                key={i}
                className={`pip ${done ? "done" : ""} ${i === repIdx ? "current" : ""} ${isReverseMark ? "reverse-mark" : ""}`}
              />
            );
          })}
        </div>

        <div className="active-tip">
          <span className="tag">{pk(tip.tag)}</span> {pk(tip.text)}
        </div>
      </div>

      <div className="exercise-controls">
        <button
          className="icon-btn"
          onClick={() => controls.back()}
          aria-label={tt("active.aria_back")}
        >
          <Icon.SkipBack />
        </button>
        <button
          className="icon-btn primary big"
          onClick={() => controls.toggle()}
          aria-label={paused ? tt("active.resume") : tt("active.aria_pause")}
        >
          {paused ? <Icon.Play width={32} height={32} /> : <Icon.Pause width={32} height={32} />}
        </button>
        <button
          className="icon-btn"
          onClick={() => controls.skipSegment()}
          aria-label={tt("active.aria_skip")}
        >
          <Icon.Skip />
        </button>
      </div>

      {paused && (
        <div className="pause-overlay" onClick={() => controls.toggle()}>
          <div className="pause-card" onClick={(e) => e.stopPropagation()}>
            <div className="pause-title">{tt("active.paused")}</div>
            <div className="pause-tips">
              {tt("active.pause_tip_valsalva")}<br />
              {tt("active.pause_tip_no_glutes")}<br />
              {tt("active.pause_tip_breath")}
            </div>
            <div className="pause-actions">
              <button className="btn btn-ghost" onClick={() => { controls.skipExercise(); controls.resume(); }}>
                <Icon.Skip width={14} height={14} /> {tt("active.skip_exercise")}
              </button>
              <button className="btn btn-primary" onClick={() => controls.toggle()}>
                <Icon.Play width={14} height={14} /> {tt("active.resume")}
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

// ============================================================
// Modo "ojos cerrados": full-screen, color por fase, blob central, tap = pausa
// ============================================================
function EyesClosedMode({ engine, onTap, controls }) {
  const tt = window.t || ((k) => k);
  const { phase, segment, msIntoPhase, msTotalPhase, paused, isReverseRep, intensity, cue } = engine;
  const phaseColor = (window.PHASE_COLORS && PHASE_COLORS[phase]) || "var(--accent)";
  const phaseLbl = phase ? tt(`phase.${phase}`) : "";
  const ringProgress = msTotalPhase > 0 ? Math.min(1, msIntoPhase / msTotalPhase) : 0;

  // Fase 'arousal' (Stop-Start): el motor espera el tap del usuario al PONR.
  // En modo ciego el tap del fondo PAUSA por defecto, así que durante arousal
  // lo redirigimos a tapPONR() y mostramos un CTA explícito.
  const isArousal = !!(segment && segment.untilTap) || phase === "arousal";
  // Tiempo en arousal usado solo como semilla para la pulsación sutil del blob (sin mostrarse).
  const arousalSec = Math.floor(msIntoPhase / 1000);

  const blobScale = (() => {
    if (phase === "inhale") return 0.6 + 0.4 * ringProgress;
    if (phase === "exhale") return 1.0 - 0.4 * ringProgress;
    if (phase === "contract" || phase === "hold" || phase === "peak") return 0.55;
    if (phase === "release") return 0.55 + 0.3 * ringProgress;
    if (phase === "rest") return 0.85;
    if (phase === "reverse") return 1.05;
    if (phase === "arousal") return 0.7 + 0.05 * Math.sin(arousalSec * 0.6);
    return 0.75;
  })();

  return (
    <div
      className="eyes-closed"
      onClick={() => { if (isArousal) controls.tapPONR(); else controls.toggle(); }}
      style={{ background: `radial-gradient(circle at 50% 45%, color-mix(in oklch, ${phaseColor} 22%, var(--bg)) 0%, var(--bg) 70%)` }}
    >
      <button
        className="ec-exit"
        onClick={(e) => { e.stopPropagation(); onTap(); }}
        aria-label={tt("active.eyes_closed_exit")}
      >
        <Icon.Eye width={20} height={20} /> {tt("active.eyes_closed_short")}
      </button>
      <div className="ec-blob" style={{ transform: `translate(-50%, -50%) scale(${blobScale})`, background: phaseColor }} />
      {isArousal ? (
        <>
          <div className="ec-cue">{cue || phaseLbl}</div>
          <button
            className="btn btn-primary btn-lg ec-arousal-tap"
            onClick={(e) => { e.stopPropagation(); controls.tapPONR(); }}
            aria-label={tt("active.tap_ponr")}
          >
            <Icon.Play width={16} height={16} /> {tt("active.tap_ponr")}
          </button>
        </>
      ) : (
        <>
          <div className="ec-cue">{phaseLbl}</div>
          {intensity > 0 && <div className="ec-intensity" style={{ color: phaseColor }}>{intensity}%</div>}
          {intensity < 0 && <div className="ec-intensity ec-intensity-push">{tt("active.intensity_push")}</div>}
        </>
      )}
      {paused && !isArousal && <div className="ec-paused">{tt("active.paused_tap_resume")}</div>}
      {isReverseRep && <div className="ec-reverse">{tt("active.reverse_label")}</div>}
    </div>
  );
}

// ============================================================
// SUMMARY (post sesión)
// ============================================================
function SummaryScreen({ session, onClose }) {
  const tt = window.t || ((k) => k);
  const pk = window.pick || ((x) => x);
  return (
    <div style={{ height: "100%", display: "flex", flexDirection: "column" }}>
      <div className="summary-head">
        <div className="badge">
          <Icon.Trophy width={40} height={40} />
        </div>
        <h1>{tt("active.session_complete")}</h1>
        <div className="sub">{pk(session.routineName)}</div>
      </div>

      <div className="summary-stats">
        <div className="stat">
          <div className="label">{tt("active.summary_repetitions")}</div>
          <div className="value">{session.totalReps}</div>
        </div>
        <div className="stat">
          <div className="label">{tt("active.summary_exercises")}</div>
          <div className="value">{session.totalSets}</div>
        </div>
        <div className="stat">
          <div className="label">{tt("active.summary_duration")}</div>
          <div className="value">{Math.floor(session.durationSec / 60)}:{String(session.durationSec % 60).padStart(2, "0")}</div>
        </div>
        <div className="stat">
          <div className="label">{tt("active.summary_achievement")}</div>
          <div className="value" style={{ fontSize: 22, fontFamily: "var(--font-sans)" }}>{tt("active.summary_streak_plus")}</div>
        </div>
      </div>

      <div style={{ flex: 1, display: "flex", flexDirection: "column", justifyContent: "center", alignItems: "center", padding: "20px 32px", textAlign: "center" }}>
        <div style={{ fontSize: 14, color: "var(--ink-2)", lineHeight: 1.6, maxWidth: 320 }}>
          {tt("active.summary_motivation")}
        </div>
      </div>

      <div style={{ padding: "0 22px 32px" }}>
        <button className="btn btn-primary btn-block btn-lg" onClick={onClose}>
          <Icon.Check width={16} height={16} /> {tt("active.summary_save_close")}
        </button>
      </div>
    </div>
  );
}

// ============================================================
// TESTS — Max hold + Quick flicks 10s + MVC subjetivo
// ============================================================
function TestsScreen({ store, navigate }) {
  const { state, logTest } = store;
  const tt = window.t || ((k) => k);
  const tB = window.tBold || ((s) => s);
  const [step, setStep] = useStateA("intro"); // intro | running | done
  const [results, setResults] = useStateA(null);

  const BaselineTestC = window.BaselineTest;

  const handleComplete = (res) => {
    logTest(res);
    setResults(res);
    setStep("done");
  };

  if (step === "done" && results) {
    const lvl = window.classifyLevel ? window.classifyLevel({ holdMs: results.holdMs, flicksPer10s: results.flicksPer10s }) : "beginner";
    const lvlLabel = tt(`common.${lvl}`);
    return (
      <div>
        <div className="app-header">
          <button className="icon-btn" style={{ width: 40, height: 40 }} onClick={() => navigate("home")} aria-label={tt("common.close")}>
            <Icon.Close />
          </button>
          <div style={{ fontSize: 13, color: "var(--ink-3)", fontWeight: 600 }}>{tt("test.title_done")}</div>
          <div style={{ width: 40 }} />
        </div>
        <div className="screen-pad" style={{ paddingTop: 30 }}>
          <div className="badge-circle"><Icon.CheckCircle width={48} height={48} /></div>
          <h2 style={{ textAlign: "center", marginTop: 20, fontSize: 24 }}>{tt("onboarding.results")}</h2>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12, marginTop: 18 }}>
            <div className="stat"><div className="label">{tt("test.max_hold")}</div><div className="value">{(results.holdMs / 1000).toFixed(1)}<span style={{ fontSize: 12, color: "var(--ink-3)", marginLeft: 4 }}>{tt("common.seconds_short")}</span></div></div>
            <div className="stat"><div className="label">{tt("test.flicks_per_10s")}</div><div className="value">{results.flicksPer10s}</div></div>
            <div className="stat"><div className="label">{tt("test.mvc_subjective")}</div><div className="value">{results.mvcSubjective}<span style={{ fontSize: 12, color: "var(--ink-3)" }}>/10</span></div></div>
            <div className="stat"><div className="label">{tt("test.level_suggested")}</div><div className="value" style={{ fontSize: 20, fontFamily: "var(--font-sans)" }}>{lvlLabel}</div></div>
          </div>
          <button className="btn btn-primary btn-block btn-lg" style={{ marginTop: 24 }} onClick={() => navigate("home")}>
            {tt("test.done_back")}
          </button>
        </div>
      </div>
    );
  }

  return (
    <div>
      <div className="app-header">
        <button className="icon-btn" style={{ width: 40, height: 40 }} onClick={() => navigate("home")} aria-label={tt("common.close")}>
          <Icon.Close />
        </button>
        <div style={{ fontSize: 13, color: "var(--ink-3)", fontWeight: 600 }}>{tt("test.title")}</div>
        <div style={{ width: 40 }} />
      </div>

      <div className="screen-pad">
        {step === "intro" && (
          <div>
            <h1 style={{ fontSize: 26, fontWeight: 700, letterSpacing: "-0.02em", marginTop: 8 }}>
              {tt("test.intro_title")}
            </h1>
            <p style={{ fontSize: 14.5, color: "var(--ink-2)", lineHeight: 1.5 }}>
              {tt("test.intro_desc")}
            </p>
            <ol style={{ fontSize: 14, color: "var(--ink-2)", lineHeight: 1.7, paddingLeft: 18, marginTop: 14 }}>
              <li>{tB(tt("test.intro_li1"))}</li>
              <li>{tB(tt("test.intro_li2"))}</li>
              <li>{tB(tt("test.intro_li3"))}</li>
            </ol>
            <button className="btn btn-primary btn-block btn-lg" style={{ marginTop: 20 }} onClick={() => setStep("running")}>
              {tt("test.intro_start")}
            </button>
          </div>
        )}

        {step === "running" && BaselineTestC && (
          <BaselineTestC
            initial={{ mvcSubjective: state.profile.baseline.mvcSubjective || 5 }}
            onComplete={handleComplete}
          />
        )}
      </div>
    </div>
  );
}

// ============================================================
// CREAR RUTINA (simplificado, type='standard' por defecto)
// ============================================================
function CreateRoutineScreen({ store, navigate }) {
  const { state } = store;
  const tt = window.t || ((k) => k);
  const pk = window.pick || ((x) => x);
  const [name, setNameC] = useStateA("");
  const [track, setTrackC] = useStateA(state.profile.track || "general-strength");
  const [level, setLevelC] = useStateA(state.profile.level || "beginner");
  const [exercises, setExercises] = useStateA([
    { id: `c-${Date.now()}-1`, name: tt("create.default_ex_name"), type: "standard", reps: 10, holdSec: 5, restSec: 5, instruction: tt("create.default_ex_instruction") },
  ]);

  const addExercise = (type = "standard") => {
    const base = { id: `c-${Date.now()}`, name: tt("create.default_new_ex"), type, instruction: "" };
    if (type === "standard") setExercises([...exercises, { ...base, name: tt("create.btn_holds"), reps: 10, holdSec: 5, restSec: 5 }]);
    else if (type === "flick") setExercises([...exercises, { ...base, name: tt("create.btn_flicks"), reps: 15 }]);
    else if (type === "ladder") setExercises([...exercises, { ...base, name: tt("create.btn_ladder"), reps: 5 }]);
    else if (type === "elevator") setExercises([...exercises, { ...base, name: tt("create.btn_elevator"), reps: 3 }]);
    else if (type === "knack") setExercises([...exercises, { ...base, name: tt("create.btn_knack"), reps: 8 }]);
    else if (type === "edging-hold") setExercises([...exercises, { ...base, name: `${tt("create.btn_edge")} 30s`, reps: 3, params: { holdSec: 30 } }]);
    else if (type === "edge") setExercises([...exercises, { ...base, name: tt("create.btn_edge_no_hold"), reps: 4, params: { squeezeMs: 2000, flickAfterSec: 30 } }]);
    else if (type === "reverse") setExercises([...exercises, { ...base, name: tt("create.btn_reverse"), reps: 5 }]);
  };
  const removeExercise = (id) => setExercises(exercises.filter((e) => e.id !== id));
  const updateExercise = (id, patch) => setExercises(exercises.map((e) => (e.id === id ? { ...e, ...patch } : e)));

  const totalReps = exercises.reduce((s, e) => s + (Number(e.reps) || 0), 0);
  const durationMin = Math.max(1, Math.round(
    exercises.reduce((s, e) => {
      const reps = Number(e.reps) || 0;
      // Rest unificado: 3s por rep (engine REST_MS = 3000).
      if (e.type === "standard") return s + reps * ((Number(e.holdSec) || 5) + 3);
      if (e.type === "flick") return s + reps * 1; // ~1s por flick
      if (e.type === "edging-hold") {
        const flickAfter = (e.params && e.params.flickAfterSec) || 0;
        return s + reps * (((e.params && e.params.holdSec) || 30) + flickAfter + 8);
      }
      if (e.type === "edge") {
        const flickAfter = (e.params && e.params.flickAfterSec) || 0;
        return s + reps * (Math.round(((e.params && e.params.squeezeMs) || 2000) / 1000) + flickAfter + 8);
      }
      return s + reps * 8; // estimación
    }, 0) / 60
  ));

  const save = () => {
    if (!name.trim()) return alert(tt("create.need_name"));
    if (exercises.length === 0) return alert(tt("create.need_exercises"));
    const audience = TRACKS[track] ? TRACKS[track].audience : "all";
    const routine = {
      id: `custom-${Date.now()}`,
      name: name.trim(),
      track,
      audience,
      level,
      durationMin,
      description: tt("create.description_default"),
      exercises: exercises.map((e) => ({
        ...e,
        reps: Number(e.reps) || 1,
        holdSec: e.holdSec ? Number(e.holdSec) : undefined,
        restSec: e.restSec ? Number(e.restSec) : undefined,
      })),
    };
    store.addCustomRoutine(routine);
    navigate("catalog");
  };

  return (
    <div>
      <div className="app-header">
        <button className="icon-btn" style={{ width: 40, height: 40 }} onClick={() => navigate("catalog")} aria-label={tt("active.aria_back")}>
          <Icon.Back />
        </button>
        <div style={{ fontSize: 16, fontWeight: 700 }}>{tt("create.title")}</div>
        <div style={{ width: 40 }} />
      </div>

      <div className="screen-pad">
        <div className="field">
          <label className="l">{tt("create.name")}</label>
          <input value={name} onChange={(e) => setNameC(e.target.value)} placeholder={tt("create.name_ph")} />
        </div>
        <div className="field">
          <label className="l">{tt("create.track")}</label>
          <select className="twk-field" value={track} onChange={(e) => setTrackC(e.target.value)} style={{ width: "100%", padding: 12, borderRadius: 12, border: "1px solid var(--line)", background: "var(--surface)", color: "var(--ink)", fontSize: 14 }}>
            {TRACK_LIST.map((t) => <option key={t.id} value={t.id}>{pk(t.name)}</option>)}
          </select>
        </div>
        <div className="field">
          <label className="l">{tt("create.level")}</label>
          <div className="seg">
            <button className={level === "beginner" ? "active" : ""} onClick={() => setLevelC("beginner")}>{tt("common.beginner")}</button>
            <button className={level === "intermediate" ? "active" : ""} onClick={() => setLevelC("intermediate")}>{tt("common.intermediate")}</button>
            <button className={level === "advanced" ? "active" : ""} onClick={() => setLevelC("advanced")}>{tt("common.advanced")}</button>
          </div>
        </div>

        <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 10, marginTop: 8, marginBottom: 12 }}>
          <div className="stat"><div className="label">{tt("create.exercises")}</div><div className="value">{exercises.length}</div></div>
          <div className="stat"><div className="label">{tt("create.reps")}</div><div className="value">{totalReps}</div></div>
          <div className="stat"><div className="label">{tt("create.min_short")}</div><div className="value">{durationMin}</div></div>
        </div>

        <div className="section-head" style={{ marginTop: 4 }}><h2>{tt("create.exercises")}</h2></div>

        <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
          {exercises.map((ex, i) => (
            <div key={ex.id} className="card" style={{ padding: 14 }}>
              <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 10 }}>
                <div style={{ width: 24, height: 24, borderRadius: 6, background: "var(--surface-2)", border: "1px solid var(--line)", display: "grid", placeItems: "center", fontSize: 11, fontWeight: 700, fontFamily: "var(--font-mono)", color: "var(--ink-2)" }}>
                  {i + 1}
                </div>
                <input
                  value={ex.name}
                  onChange={(e) => updateExercise(ex.id, { name: e.target.value })}
                  style={{ flex: 1, padding: "8px 10px", border: "1px solid var(--line)", borderRadius: 8, background: "var(--surface)", color: "var(--ink)", fontSize: 14, fontWeight: 600 }}
                />
                <button className="icon-btn" style={{ width: 32, height: 32, background: "transparent", border: "none" }} onClick={() => removeExercise(ex.id)}>
                  <Icon.Trash width={15} height={15} />
                </button>
              </div>
              <div style={{ fontSize: 11, color: "var(--ink-3)", textTransform: "uppercase", fontWeight: 600, letterSpacing: "0.06em", marginBottom: 6 }}>
                {tt("create.type_label")}: {ex.type}
              </div>
              <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 8 }}>
                <NumberField label={tt("create.reps")} value={ex.reps} onChange={(v) => updateExercise(ex.id, { reps: v })} min={1} max={50} />
                {ex.type === "standard" && <NumberField label={tt("create.hold_sec")} value={ex.holdSec} onChange={(v) => updateExercise(ex.id, { holdSec: v })} min={1} max={30} />}
                {ex.type === "standard" && <NumberField label={tt("create.rest_sec")} value={ex.restSec} onChange={(v) => updateExercise(ex.id, { restSec: v })} min={1} max={30} />}
                {ex.type === "edging-hold" && (
                  <NumberField label={tt("create.hold_sec")} value={(ex.params && ex.params.holdSec) || 30} onChange={(v) => updateExercise(ex.id, { params: { ...(ex.params || {}), holdSec: v } })} min={10} max={120} />
                )}
              </div>
            </div>
          ))}
          <div className="exercise-type-grid">
            {[
              ["standard", tt("create.btn_holds")],
              ["flick", tt("create.btn_flicks")],
              ["ladder", tt("create.btn_ladder")],
              ["elevator", tt("create.btn_elevator")],
              ["knack", tt("create.btn_knack")],
              ["edging-hold", tt("create.btn_edge")],
              ["edge", tt("create.btn_edge_no_hold")],
              ["reverse", tt("create.btn_reverse")],
            ].map(([t, lbl]) => (
              <button key={t} className="chip" onClick={() => addExercise(t)} style={{ display: "inline-flex", alignItems: "center", gap: 4 }}>
                <Icon.Plus width={12} height={12} /> {lbl}
              </button>
            ))}
          </div>
        </div>

        <div style={{ marginTop: 20, marginBottom: 8 }}>
          <button className="btn btn-primary btn-block btn-lg" onClick={save}>
            <Icon.Check width={16} height={16} /> {tt("create.save")}
          </button>
        </div>
      </div>
    </div>
  );
}

function NumberField({ label, value, onChange, min, max }) {
  const v = Number(value) || min;
  return (
    <div style={{ background: "var(--surface-2)", border: "1px solid var(--line)", borderRadius: 10, padding: 8 }}>
      <div style={{ fontSize: 10, color: "var(--ink-3)", textTransform: "uppercase", fontWeight: 600, letterSpacing: "0.06em", textAlign: "center" }}>{label}</div>
      <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginTop: 4 }}>
        <button onClick={() => onChange(Math.max(min, v - 1))} style={{ width: 22, height: 22, borderRadius: 6, background: "var(--surface)", border: "1px solid var(--line)", color: "var(--ink-2)", fontWeight: 700 }}>−</button>
        <div style={{ fontFamily: "var(--font-mono)", fontWeight: 600, fontSize: 16 }}>{v}</div>
        <button onClick={() => onChange(Math.min(max, v + 1))} style={{ width: 22, height: 22, borderRadius: 6, background: "var(--surface)", border: "1px solid var(--line)", color: "var(--ink-2)", fontWeight: 700 }}>+</button>
      </div>
    </div>
  );
}

Object.assign(window, { ActiveScreen, CreateRoutineScreen, SummaryScreen, TestsScreen });
