/* view_live.jsx — live telemetry monitor */

function fmtBandLoudness(v) {
  return v <= -85 ? "0.0" : v.toFixed(1);
}

function KpiStrip() {
  const s = useAudioEngine(10);
  const items = [
    { label: "LUFS",   val: s.lufs.toFixed(1), unit: "LUFS", color: "var(--c-loud)" },
    { label: "Peak",   val: s.peak.toFixed(1), unit: "dBFS", color: s.peak > -1 ? "var(--c-clip)" : "var(--c-loud)" },
    { label: "Bass LUFS",   val: fmtBandLoudness(s.bass), unit: "LUFS", color: "var(--c-bass)" },
    { label: "Mid LUFS",    val: fmtBandLoudness(s.mid), unit: "LUFS", color: "var(--c-mid)" },
    { label: "Treble LUFS", val: fmtBandLoudness(s.treble), unit: "LUFS", color: "var(--c-treble)" },
    { label: "Clips",  val: s.clips, color: s.clips > 0 ? "var(--c-clip)" : "var(--c-mid)" },
    { label: "Status", val: s.status, color: s.status === "GOOD" ? "var(--c-mid)" : s.status === "QUIET" ? "var(--fg-2)" : "var(--c-treble)", small: true },
  ];
  return (
    <div className="panel" style={{ padding: 0, display: "flex", alignItems: "stretch", marginBottom: 16, overflow: "hidden" }}>
      <div style={{ display: "flex", alignItems: "center", gap: 12, padding: "16px 22px", flex: "0 0 auto" }}>
        <div style={{ color: "var(--accent)" }}><Icon name="waveform" size={26} strokeWidth={2} /></div>
        <div style={{ whiteSpace: "nowrap" }}>
          <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
            <span style={{ fontWeight: 800, letterSpacing: ".08em", fontSize: 15 }}>LIVE MONITOR</span>
            <span className="live-pill"><span className="live-dot" />LIVE</span>
          </div>
          <div className="dim" style={{ fontSize: 12, marginTop: 2 }}>Rolling {s.avgWindowSec}-second average</div>
        </div>
      </div>
      <div className="kpi-strip" style={{ flex: 1 }}>
        {items.map(k => (
          <div className="kpi" key={k.label}>
            <span className="kpi-label">{k.label}</span>
            <span className="kpi-val" style={{ color: k.color, fontSize: k.small ? 17 : 22 }}>
              {k.val}{k.unit && <span className="unit"> {k.unit}</span>}
            </span>
          </div>
        ))}
      </div>
    </div>
  );
}

function AverageWindowControl() {
  const s = useAudioEngine(4);
  return (
    <Panel title="Metrics Window" icon="clock" style={{ marginBottom: 16 }}
      right={
        <select className="select" value={s.avgWindowSec} onChange={e => window.AudioEngine.setAverageWindow(e.target.value)}>
          <option value="5">5 seconds</option>
          <option value="10">10 seconds</option>
          <option value="15">15 seconds</option>
        </select>
      }>
      <div className="dim" style={{ fontSize: 13 }}>
        Main loudness, band loudness and activity use the selected rolling average. Peak shows the highest peak inside that same window.
      </div>
    </Panel>
  );
}

function LiveView() {
  const s = useAudioEngine(14);
  const D = window.QA_DATA;
  const [win, setWin] = React.useState("20 Seconds");

  const series = [
    { color: "var(--c-loud)",   points: s.hist.lufs,   width: 2.6 },
    { color: "var(--c-bass)",   points: s.hist.bass,   width: 2.4 },
    { color: "var(--c-mid)",    points: s.hist.mid,    width: 2.4 },
    { color: "var(--c-treble)", points: s.hist.treble, width: 2.4 },
  ];

  const currentVals = [
    { label: "Loudness (LUFS)",    val: s.lufs.toFixed(1),           color: "var(--c-loud)" },
    { label: "Bass Loudness (20-250 Hz)",    val: fmtBandLoudness(s.bass) + " LUFS",    color: "var(--c-bass)" },
    { label: "Mid Loudness (250 Hz-4 kHz)",  val: fmtBandLoudness(s.mid) + " LUFS",     color: "var(--c-mid)" },
    { label: "Treble Loudness (4-20 kHz)",   val: fmtBandLoudness(s.treble) + " LUFS",  color: "var(--c-treble)" },
    { label: "Audio Activity",     val: Math.round(s.activity) + "%", color: "var(--c-mid)" },
    { label: "True Peak",          val: s.peak.toFixed(1) + " dBFS", color: "var(--c-clip)" },
  ];

  return (
    <div className="page fade-up">
      <KpiStrip />
      <AverageWindowControl />
      <UrlAudioSource />

      <Panel title="Audio Loudness Over Time" info style={{ marginBottom: 16 }}
        right={
          <div className="row gap-sm">
            <select className="select" value={win} onChange={e => setWin(e.target.value)}>
              <option>20 Seconds</option>
              <option>60 Seconds</option>
              <option>5 Minutes</option>
            </select>
            <button className="btn ghost sm" style={{ padding: "7px" }}><Icon name="more" size={18} /></button>
          </div>
        }>
        <div className="legend" style={{ marginBottom: 8 }}>
          <span className="legend-item"><span className="legend-line" style={{ background: "var(--c-loud)" }} />Loudness (LUFS)</span>
          <span className="legend-item"><span className="legend-swatch" style={{ background: "var(--c-bass)", borderRadius: 999 }} />Bass Loudness (20-250 Hz)</span>
          <span className="legend-item"><span className="legend-swatch" style={{ background: "var(--c-mid)", borderRadius: 999 }} />Mid Loudness (250 Hz-4 kHz)</span>
          <span className="legend-item"><span className="legend-swatch" style={{ background: "var(--c-treble)", borderRadius: 999 }} />Treble Loudness (4-20 kHz)</span>
        </div>
        <LineChart series={series} height={330} yLabelFormat={v => String(Math.round(-90 + (v / 100) * 80))} />
      </Panel>

      <Panel title="Audio Activity" info style={{ marginBottom: 16 }}
        right={
          <div className="legend">
            {[["Strong","#2fb84d"],["Moderate","#f59e0b"],["Low","#f4503f"],["Silence","#4a566a"]].map(([l,c]) => (
              <span className="legend-item" key={l}><span className="legend-swatch" style={{ background: c, borderRadius: 999 }} />{l}</span>
            ))}
          </div>
        }>
        <ActivityMeter values={s.activityHist} height={66} />
        <div className="row between" style={{ marginTop: 8 }}>
          {["-20s","-16s","-12s","-8s","-4s","0s"].map(l => <span key={l} className="dim mono" style={{ fontSize: 11 }}>{l}</span>)}
        </div>
      </Panel>

      <div className="grid" style={{ gridTemplateColumns: "minmax(280px, 1fr) minmax(360px, 1.4fr) minmax(320px, 1.1fr)", marginBottom: 16 }}>
        <Panel title="Current Values">
          <div className="readout">
            {currentVals.map(c => (
              <div className="readout-row" key={c.label}>
                <span className="rdot" style={{ background: c.color }} />
                <span className="rlabel">{c.label}</span>
                <span className="rval" style={{ color: c.color }}>{c.val}</span>
              </div>
            ))}
          </div>
        </Panel>

        <Panel title="Spectrum Analyzer" info>
          <SpectrumBars values={s.spectrum} height={210} />
        </Panel>

        <Panel title="Events (Recent)">
          <div>
            {D.events.slice(0, 6).map((e, i) => (
              <div className="event" key={i}>
                <span className="edot" style={{ background: e.grade === "high" ? "var(--c-clip)" : e.grade === "warn" ? "var(--c-treble)" : "var(--c-mid)" }} />
                <span className="etime">{e.t}</span>
                <span className="etext">{e.text}</span>
                <span className={`tag ${e.tagClass}`}>{e.tag}</span>
              </div>
            ))}
          </div>
        </Panel>
      </div>

      <SessionFootbar />
    </div>
  );
}

function UrlAudioSource() {
  const s = useAudioEngine(4);
  const { scanDevices, deviceAccess, analysisInputLabel } = useQA();
  const [url, setUrl] = React.useState("");
  const [busy, setBusy] = React.useState(false);
  const [msg, setMsg] = React.useState("");
  const pending = busy || deviceAccess === "requesting";

  async function startMic() {
    setBusy(true);
    setMsg("");
    try {
      await Promise.race([
        scanDevices(true),
        new Promise((_, reject) => setTimeout(() => reject(new Error("Permission prompt is still waiting. Choose Allow in the browser, then press Start Mic/Input again if needed.")), 12000)),
      ]);
      setMsg(window.AudioEngine.analyser ? "Analyzing microphone/input audio" : "No microphone/input started yet");
    } catch (e) {
      setMsg(e.message || "Unable to start microphone/input");
    } finally {
      setBusy(false);
    }
  }

  async function startUrl() {
    setBusy(true);
    setMsg("");
    try {
      await window.AudioEngine.useMediaUrl(url);
      setMsg("Analyzing URL audio");
    } catch (e) {
      window.AudioEngine.stopSource();
      setMsg(e.message || "Unable to analyze this URL");
    } finally {
      setBusy(false);
    }
  }

  function stopUrl() {
    window.AudioEngine.stopSource();
    setMsg("");
  }

  return (
    <Panel title="Audio Source" icon="signal" style={{ marginBottom: 16 }}
      right={
        s.sourceType !== "none"
          ? <button className="btn ghost sm" onClick={stopUrl}><Icon name="stop" size={13} fill="currentColor" />Stop Source</button>
          : null
      }>
      <div className="source-action-row">
        <button className="btn primary" onClick={startMic} disabled={busy}>
          <Icon name="mic" size={15} />{busy ? "Starting..." : "Start Mic/Input"}
        </button>
        <div className="source-url-note" style={{ marginTop: 0 }}>
          {s.sourceType === "microphone"
            ? <span><span className="sig-dot" style={{ background: "var(--grade-good)" }} />{s.sourceLabel || analysisInputLabel || "Microphone input"}</span>
            : pending
              ? <span><span className="sig-dot" style={{ background: "var(--c-treble)" }} />Waiting for the browser permission prompt. Choose Allow to start live data.</span>
              : <span>Live data needs a started mic/input, or a direct media URL below.</span>}
        </div>
      </div>
      <div className="source-url-row">
        <input className="op-input source-url-input" value={url} placeholder="Paste a direct audio/video URL (.mp3, .wav, .m4a, .ogg, .webm)"
          onChange={e => setUrl(e.target.value)}
          onKeyDown={e => { if (e.key === "Enter") startUrl(); }} />
        <button className="btn primary" onClick={startUrl} disabled={busy || !url.trim()}>
          <Icon name="play" size={15} fill="currentColor" />{busy ? "Loading..." : "Analyze URL"}
        </button>
      </div>
      <div className="source-url-note">
        {s.sourceType === "url"
          ? <span><span className="sig-dot" style={{ background: "var(--grade-good)" }} />{s.sourceLabel}</span>
          : <span>Direct media URLs work when the server allows browser audio access. Web pages and YouTube-style URLs usually cannot be captured.</span>}
      </div>
      {msg && s.sourceType === "none" && <div className="device-note" style={{ marginTop: 10 }}><Icon name="info" size={16} color="var(--c-treble)" /><span>{msg}</span></div>}
    </Panel>
  );
}

function SessionFootbar() {
  const D = window.QA_DATA;
  const { analysisInputLabel, playbackOutputLabel, currentSession } = useQA();
  const s = useAudioEngine(2);
  const [dur, setDur] = React.useState("00:00:00");
  React.useEffect(() => {
    let sec = 0;
    const id = setInterval(() => {
      sec++;
      const h = String(Math.floor(sec / 3600)).padStart(2, "0");
      const m = String(Math.floor((sec % 3600) / 60)).padStart(2, "0");
      const s = String(sec % 60).padStart(2, "0");
      setDur(`${h}:${m}:${s}`);
    }, 1000);
    return () => clearInterval(id);
  }, []);

  const cells = [
    { ico: "settings", label: "Session",     val: currentSession.name || D.session.name },
    { ico: "clock",    label: "Duration",    val: dur, mono: true },
    { ico: "signal",   label: "Sample Rate", val: D.session.sampleRate, mono: true },
    { ico: "cpu",      label: "Buffer",      val: D.session.buffer, mono: true },
    { ico: s.sourceType === "url" ? "signal" : "mic",  label: "Analysis Input",val: s.sourceLabel || analysisInputLabel || "No input selected" },
    { ico: "speaker", label: "Playback Output", val: playbackOutputLabel || "No output selected" },
  ];

  return (
    <div className="footbar">
      {cells.map(c => (
        <div className="footcell" key={c.label}>
          <span className="fc-ico"><Icon name={c.ico} size={18} /></span>
          <div>
            <div className="fc-label">{c.label}</div>
            <div className="fc-val" style={c.mono ? { fontFamily: "var(--mono)" } : null}>{c.val}</div>
          </div>
        </div>
      ))}
      <div className="footcell right">
        <span style={{ width: 9, height: 9, borderRadius: 999, background: "var(--c-mid)", boxShadow: "0 0 8px var(--c-mid)" }} />
        <span className="fc-val" style={{ letterSpacing: ".06em" }}>CONNECTED</span>
      </div>
    </div>
  );
}

Object.assign(window, { LiveView, SessionFootbar, KpiStrip, UrlAudioSource, AverageWindowControl });
