/* timer.jsx — cross-page stopwatch + timer state, pill, and modal.
   Globals: TimerProvider, TimerContext, useTimer, TimerPill, TimerToolModal,
            pad2, formatHMS, formatStopwatch
*/

(function () {
const { useState, useEffect, useRef } = React;

// ===========================================================
// Time helpers
// ===========================================================
function pad2(n) { return String(n).padStart(2, '0'); }
function formatHMS(ms) {
  const total = Math.max(0, Math.floor(ms / 1000));
  const h = Math.floor(total / 3600);
  const m = Math.floor((total % 3600) / 60);
  const s = total % 60;
  return h > 0 ? `${h}:${pad2(m)}:${pad2(s)}` : `${pad2(m)}:${pad2(s)}`;
}
function formatStopwatch(ms) {
  const total = Math.max(0, Math.floor(ms / 10));
  const cs = total % 100;
  const sTotal = Math.floor(total / 100);
  const s = sTotal % 60;
  const mTotal = Math.floor(sTotal / 60);
  const m = mTotal % 60;
  const h = Math.floor(mTotal / 60);
  return h > 0
    ? `${h}:${pad2(m)}:${pad2(s)}.${pad2(cs)}`
    : `${pad2(m)}:${pad2(s)}.${pad2(cs)}`;
}

// ===========================================================
// Timer context — survives modal close + page switches
// ===========================================================
const TimerContext = React.createContext(null);

function TimerProvider({ children }) {
  // Stopwatch
  const [swRunning, setSwRunning] = useState(false);
  const [swStartedAt, setSwStartedAt] = useState(0);
  const [swElapsedAtPause, setSwElapsedAtPause] = useState(0);
  const [swLaps, setSwLaps] = useState([]);

  // Timer
  const [tRunning, setTRunning]                 = useState(false);
  const [tEndsAt, setTEndsAt]                   = useState(0);
  const [tRemainingAtPause, setTRemainingAtPause] = useState(0);
  const [tRinging, setTRinging]                 = useState(false);

  const [now, setNow] = useState(() => Date.now());
  const rafRef = useRef(null);
  useEffect(() => {
    const anythingTicking = swRunning || tRunning || tRinging;
    if (!anythingTicking) return;
    let alive = true;
    const loop = () => {
      if (!alive) return;
      setNow(Date.now());
      rafRef.current = requestAnimationFrame(loop);
    };
    rafRef.current = requestAnimationFrame(loop);
    return () => {
      alive = false;
      if (rafRef.current) cancelAnimationFrame(rafRef.current);
    };
  }, [swRunning, tRunning, tRinging]);

  const audioCtxRef = useRef(null);
  const audioTimersRef = useRef([]);
  const ensureAudio = () => {
    if (!audioCtxRef.current) {
      const AC = window.AudioContext || window.webkitAudioContext;
      if (AC) audioCtxRef.current = new AC();
    }
    if (audioCtxRef.current?.state === 'suspended') {
      audioCtxRef.current.resume().catch(() => {});
    }
    return audioCtxRef.current;
  };
  const playBeep = (freq, when, duration) => {
    const ctx = audioCtxRef.current;
    if (!ctx) return;
    const o = ctx.createOscillator();
    const g = ctx.createGain();
    o.type = 'sine';
    o.frequency.value = freq;
    g.gain.setValueAtTime(0, when);
    g.gain.linearRampToValueAtTime(0.35, when + 0.02);
    g.gain.setValueAtTime(0.35, when + duration - 0.04);
    g.gain.linearRampToValueAtTime(0, when + duration);
    o.connect(g).connect(ctx.destination);
    o.start(when);
    o.stop(when + duration + 0.02);
  };
  const startChime = () => {
    const ctx = ensureAudio();
    if (!ctx) return;
    stopChime();
    const tick = () => {
      const t0 = ctx.currentTime;
      playBeep(880, t0,        0.18);
      playBeep(660, t0 + 0.25, 0.18);
    };
    tick();
    const id = setInterval(tick, 1200);
    audioTimersRef.current.push(id);
  };
  const stopChime = () => {
    for (const id of audioTimersRef.current) clearInterval(id);
    audioTimersRef.current = [];
  };

  useEffect(() => {
    if (!tRunning || tRinging) return;
    const remaining = tEndsAt - now;
    if (remaining <= 0) {
      setTRunning(false);
      setTRinging(true);
      startChime();
    }
  }, [tRunning, tEndsAt, now, tRinging]);

  const swStart = () => {
    ensureAudio();
    setSwStartedAt(Date.now() - swElapsedAtPause);
    setSwRunning(true);
  };
  const swPause = () => {
    setSwElapsedAtPause(Date.now() - swStartedAt);
    setSwRunning(false);
  };
  const swReset = () => {
    setSwRunning(false);
    setSwStartedAt(0);
    setSwElapsedAtPause(0);
    setSwLaps([]);
  };
  const swLap = () => {
    const elapsed = swRunning ? Date.now() - swStartedAt : swElapsedAtPause;
    setSwLaps(l => [...l, elapsed]);
  };
  const swElapsed = swRunning ? now - swStartedAt : swElapsedAtPause;

  const tStart = (durationMs) => {
    ensureAudio();
    const dur = durationMs ?? tRemainingAtPause;
    if (!dur || dur <= 0) return;
    setTEndsAt(Date.now() + dur);
    setTRemainingAtPause(0);
    setTRunning(true);
    setTRinging(false);
  };
  const tPause = () => {
    setTRemainingAtPause(Math.max(0, tEndsAt - Date.now()));
    setTRunning(false);
  };
  const tReset = () => {
    setTRunning(false);
    setTRinging(false);
    setTEndsAt(0);
    setTRemainingAtPause(0);
    stopChime();
  };
  const tStopChime = () => {
    setTRinging(false);
    stopChime();
  };
  const tRemaining = tRunning ? Math.max(0, tEndsAt - now) : tRemainingAtPause;

  const value = {
    swRunning, swElapsed, swLaps,
    swStart, swPause, swReset, swLap,
    tRunning, tRinging, tRemaining,
    tStart, tPause, tReset, tStopChime,
    ensureAudio,
  };

  return <TimerContext.Provider value={value}>{children}</TimerContext.Provider>;
}

function useTimer() {
  const v = React.useContext(TimerContext);
  if (!v) throw new Error('useTimer must be used within TimerProvider');
  return v;
}

// ===========================================================
// TimerPill — appbar status pill
// ===========================================================
function TimerPill({ onOpen }) {
  const t = useTimer();
  const swActive = t.swRunning || t.swElapsed > 0;
  const tActive  = t.tRunning || t.tRinging || t.tRemaining > 0;
  if (!swActive && !tActive) return null;

  const handleClick = (which) => {
    if (which === 'timer' && t.tRinging) t.tStopChime();
    onOpen(which);
  };

  return (
    <div className="timer-pills">
      {tActive && (
        <button
          className={`timer-pill ${t.tRinging ? 'ringing' : ''}`}
          onClick={() => handleClick('timer')}
          title={t.tRinging ? 'Klik om alarm te stoppen' : 'Open timer'}
        >
          <span className="pill-icon">⏳</span>
          <span className="pill-val">{formatHMS(t.tRemaining)}</span>
          {t.tRinging && <span className="pill-status">!</span>}
        </button>
      )}
      {swActive && (
        <button
          className="timer-pill"
          onClick={() => handleClick('stopwatch')}
          title="Open stopwatch"
        >
          <span className="pill-icon">⏱</span>
          <span className="pill-val">{formatHMS(t.swElapsed)}</span>
          {t.swRunning && <span className="pill-dot" />}
        </button>
      )}
    </div>
  );
}

// ===========================================================
// TimerToolModal — Stopwatch + Timer tabs
// ===========================================================
function TimerToolModal({ initialTab = 'stopwatch', onCancel }) {
  const t = useTimer();
  const [tab, setTab] = useState(initialTab);

  const [setH, setSetH] = useState(0);
  const [setM, setSetM] = useState(5);
  const [setS, setSetS] = useState(0);
  const setMs = ((setH * 3600) + (setM * 60) + setS) * 1000;

  const bump = (val, setter, max) => (delta) => {
    setter(Math.max(0, Math.min(max, val + delta)));
  };

  return (
    <div className="modal-overlay" onClick={onCancel}>
      <div className="modal wide" onClick={(e) => e.stopPropagation()} style={{ width: 'min(680px, 96%)' }}>
        <div className="modal-inner">
          <div className="modal-tabs">
            <button className={`modal-tab ${tab === 'stopwatch' ? 'active' : ''}`} onClick={() => setTab('stopwatch')}>Stopwatch</button>
            <button className={`modal-tab ${tab === 'timer'     ? 'active' : ''}`} onClick={() => setTab('timer')}>Timer</button>
          </div>

          {tab === 'stopwatch' && (
            <>
              <div className="big-readout">{formatStopwatch(t.swElapsed)}</div>
              <div className="modal-actions" style={{ justifyContent: 'center', flexWrap: 'wrap', gap: 10 }}>
                {!t.swRunning
                  ? <button className="btn-pixel violet" onClick={t.swStart}>▶ Start</button>
                  : <button className="btn-pixel"        onClick={t.swPause}>⏸ Pauze</button>}
                <button className="btn-pixel" onClick={t.swLap} disabled={!t.swRunning && t.swElapsed === 0}>+ Rondje</button>
                <button className="btn-pixel ghost" onClick={t.swReset}>Reset</button>
              </div>
              {t.swLaps.length > 0 && (
                <div className="lap-list">
                  {t.swLaps.map((ms, i) => (
                    <div key={i} className="lap-row">
                      <span className="lap-idx">#{i + 1}</span>
                      <span className="lap-time">{formatStopwatch(ms)}</span>
                    </div>
                  ))}
                </div>
              )}
            </>
          )}

          {tab === 'timer' && (
            <>
              {t.tRunning || t.tRinging ? (
                <>
                  <div className={`big-readout ${t.tRinging ? 'ringing' : ''}`}>{formatHMS(t.tRemaining)}</div>
                  <div className="modal-actions" style={{ justifyContent: 'center', flexWrap: 'wrap', gap: 10 }}>
                    {t.tRinging
                      ? <button className="btn-pixel violet" onClick={t.tStopChime}>Stop alarm</button>
                      : <button className="btn-pixel" onClick={t.tPause}>⏸ Pauze</button>}
                    <button className="btn-pixel ghost" onClick={t.tReset}>Reset</button>
                  </div>
                </>
              ) : t.tRemaining > 0 ? (
                <>
                  <div className="big-readout">{formatHMS(t.tRemaining)}</div>
                  <div className="modal-actions" style={{ justifyContent: 'center', flexWrap: 'wrap', gap: 10 }}>
                    <button className="btn-pixel violet" onClick={() => t.tStart()}>▶ Hervat</button>
                    <button className="btn-pixel ghost" onClick={t.tReset}>Reset</button>
                  </div>
                </>
              ) : (
                <>
                  <div className="timer-setup">
                    <div className="timer-spinner">
                      <button onClick={() => bump(setH, setSetH, 23)(+1)}>+</button>
                      <div className="spin-val">{pad2(setH)}</div>
                      <button onClick={() => bump(setH, setSetH, 23)(-1)}>−</button>
                      <div className="spin-label">U</div>
                    </div>
                    <div className="timer-colon">:</div>
                    <div className="timer-spinner">
                      <button onClick={() => bump(setM, setSetM, 59)(+1)}>+</button>
                      <div className="spin-val">{pad2(setM)}</div>
                      <button onClick={() => bump(setM, setSetM, 59)(-1)}>−</button>
                      <div className="spin-label">M</div>
                    </div>
                    <div className="timer-colon">:</div>
                    <div className="timer-spinner">
                      <button onClick={() => bump(setS, setSetS, 59)(+1)}>+</button>
                      <div className="spin-val">{pad2(setS)}</div>
                      <button onClick={() => bump(setS, setSetS, 59)(-1)}>−</button>
                      <div className="spin-label">S</div>
                    </div>
                  </div>
                  <div className="modal-actions" style={{ justifyContent: 'center', marginTop: 16 }}>
                    <button className="btn-pixel violet" disabled={setMs <= 0}
                      style={setMs <= 0 ? { opacity: 0.5, cursor: 'not-allowed' } : null}
                      onClick={() => t.tStart(setMs)}>
                      ▶ Start
                    </button>
                  </div>
                </>
              )}
            </>
          )}

          <div className="modal-actions" style={{ marginTop: 22 }}>
            <button className="btn-pixel ghost" onClick={onCancel}>Sluit</button>
          </div>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, {
  pad2, formatHMS, formatStopwatch,
  TimerContext, TimerProvider, useTimer,
  TimerPill, TimerToolModal,
});
})();
