/* ============================================================
   Guided Workshop — Transcribe + AI summary (shared)

   Records the live session, streams a transcript anchored to
   the item under discussion, and feeds the whole thing into
   Claude for a structured summary at the end.

   Exports onto window:
     useTranscribe({ activeItemId, activeItemLabel })  hook
     TranscribeButton                  start/stop pill (top bar)
     TranscribeBadge                   small floating "REC 02:14" pill
     TranscribeDrawer                  side panel with live transcript
     TranscribeSummaryModal            AI summary overlay (Claude)

   The recording itself is mocked — there's no Web Audio call.
   A scheduler drips pre-baked transcript lines into state every
   few seconds so the demo feels alive. When `summarize()` runs,
   we hand the real transcript to `window.claude.complete()` and
   show the result. ============================================================ */

const { useState: txUseState, useEffect: txUseEffect, useCallback: txUseCallback,
        useRef: txUseRef, useMemo: txUseMemo } = React;

/* ---------- Demo dialogue ----------
   A workshop unfolds left-to-right through Asset Management items.
   Each line is { ts (seconds into session), who, text, itemId }. The
   scheduler picks the next line whose ts is <= elapsed and inserts it.
   This keeps the appearance deterministic regardless of the user's
   actual navigation — the transcript reflects "what was said", not
   "what the user is looking at right now". */
const TX_DIALOGUE = [
  { ts: 2,   who: "supporter", text: "Okay Adaeze, I'm in — let's start with the intro. Quick read, we'll spend more time on chapter 4.", itemId: "1.1" },
  { ts: 8,   who: "completer", text: "Sounds good. I've already skimmed it. Skipping to the asset register now.", itemId: "1.1" },
  { ts: 15,  who: "supporter", text: "Right — so on 4.1, what do you have today? A spreadsheet, a system, both?", itemId: "4.1" },
  { ts: 22,  who: "completer", text: "Both, honestly. Finance keeps the ledger, Ops keeps a spreadsheet. They drift apart by the quarter.", itemId: "4.1" },
  { ts: 32,  who: "supporter", text: "Classic. That's an action — single source of truth, owner assigned. Let me drop that in for you.", itemId: "4.1" },
  { ts: 40,  who: "completer", text: "Yeah please do. On 4.2 — what's the honest maturity score then?", itemId: "4.2" },
  { ts: 47,  who: "supporter", text: "If there's data but no defined process, that's Initial. Don't talk yourself into Repeatable.", itemId: "4.2" },
  { ts: 55,  who: "completer", text: "Initial it is. I'll note that we're targeting Defined by Q4.", itemId: "4.2" },
  { ts: 64,  who: "supporter", text: "Perfect. Add a comment to that effect on 4.2 so we remember why during the readout.", itemId: "4.2" },
  { ts: 73,  who: "completer", text: "Done. Moving on — 5.1, the open poll question. I'm a bit unsure how to launch it.", itemId: "5.1" },
  { ts: 80,  who: "supporter", text: "Open it first, share the code on the screen, then read the question. Don't preface.", itemId: "5.1" },
  { ts: 88,  who: "completer", text: "Got it. And for 6.1 — the bottleneck question — they always list three.", itemId: "6.1" },
  { ts: 95,  who: "supporter", text: "Push back. One bottleneck, the one they'd fix this quarter. Otherwise the action list is noise.", itemId: "6.1" },
  { ts: 104, who: "completer", text: "Makes sense. I think we have enough to wrap up. Thank you, this was really useful.", itemId: "6.1" },
];

/* ---------- People dictionary ---------- */
const TX_PEOPLE = {
  completer: { id: "completer", name: "Adaeze Nwosu",   short: "Adaeze",   role: "Compliance Lead",   avatar: 47, hue: "#175cd3" },
  supporter: { id: "supporter", name: "Adetola Okafor", short: "Adetola",  role: "Module creator",    avatar: 14, hue: "#7a5af8" },
};

/* ---------- Time helpers ---------- */
function fmtElapsed(s) {
  const m = Math.floor(s / 60);
  const r = Math.floor(s % 60);
  return `${String(m).padStart(2, "0")}:${String(r).padStart(2, "0")}`;
}

/* ---------- Hook ---------- */
function useTranscribe({ moduleName = "Asset Management" } = {}) {
  /* status: 'idle' | 'recording' | 'paused' | 'stopped' | 'summarizing' */
  const [status, setStatus]       = txUseState("idle");
  const [elapsed, setElapsed]     = txUseState(0);
  const [lines, setLines]         = txUseState([]);   /* { ts, who, text, itemId } */
  const [drawerOpen, setDrawerOpen] = txUseState(false);
  const [summary, setSummary]     = txUseState(null); /* string from claude */
  const [summaryErr, setSummaryErr] = txUseState(null);
  const [showSummary, setShowSummary] = txUseState(false);

  /* Drip-feed scheduler. Tick once per second when recording, append any
     dialogue line whose timestamp passed since the last tick. */
  txUseEffect(() => {
    if (status !== "recording") return;
    const handle = setInterval(() => {
      setElapsed(prev => {
        const next = prev + 1;
        const cutoff = next;
        setLines(linesPrev => {
          const lastTs = linesPrev.length ? linesPrev[linesPrev.length - 1].ts : -1;
          const newOnes = TX_DIALOGUE.filter(l => l.ts > lastTs && l.ts <= cutoff);
          return newOnes.length ? [...linesPrev, ...newOnes] : linesPrev;
        });
        return next;
      });
    }, 1000);
    return () => clearInterval(handle);
  }, [status]);

  const start = txUseCallback(() => { setStatus("recording"); setSummary(null); setSummaryErr(null); }, []);
  const pause = txUseCallback(() => { setStatus(prev => prev === "recording" ? "paused" : prev); }, []);
  const stop  = txUseCallback(() => { setStatus("stopped"); }, []);
  const reset = txUseCallback(() => { setStatus("idle"); setElapsed(0); setLines([]); setSummary(null); setSummaryErr(null); }, []);

  /* Hand the transcript to Claude. The prompt is tuned to match Method 8
     vocabulary — programmes, modules, actions — and produce a structured
     read-out the team can drop into the Results tab or share. */
  const summarize = txUseCallback(async () => {
    if (lines.length === 0) {
      setSummaryErr("No transcript captured yet — record something first.");
      setShowSummary(true);
      return;
    }
    setStatus("summarizing");
    setShowSummary(true);
    setSummary(null);
    setSummaryErr(null);

    const transcriptText = lines
      .map(l => `[${fmtElapsed(l.ts)}] ${TX_PEOPLE[l.who].name} (on ${l.itemId}): ${l.text}`)
      .join("\n");

    const prompt = [
      `You are summarising a live guided workshop session for the Method 8 platform.`,
      `Module: "${moduleName}". Two participants — a completer (Adaeze Nwosu) and a supporter who is the module creator (Adetola Okafor).`,
      ``,
      `Transcript (with timestamps and the question item being discussed):`,
      transcriptText,
      ``,
      `Produce a concise summary using exactly these sections, in plain text with bold section headers and short bullet lists. No preamble.`,
      ``,
      `**Headline**`,
      `One sentence — what got done.`,
      ``,
      `**Key decisions**`,
      `- 2 to 4 bullets, each tagged with the item id in [brackets].`,
      ``,
      `**Action items**`,
      `- 2 to 4 bullets, each starting with a verb, owner in (parentheses).`,
      ``,
      `**Open questions**`,
      `- 1 to 3 bullets, anything left unresolved. If none, write "None — clean session." and nothing else.`,
      ``,
      `Keep the whole thing under 180 words. Use the Method 8 vocabulary: modules, programmes, actions, completers.`,
    ].join("\n");

    try {
      const text = await window.claude.complete({
        messages: [{ role: "user", content: prompt }],
      });
      setSummary(text);
    } catch (e) {
      setSummaryErr(e?.message || String(e) || "Couldn't reach the AI service.");
    } finally {
      setStatus("stopped");
    }
  }, [lines, moduleName]);

  const openDrawer  = txUseCallback(() => setDrawerOpen(true), []);
  const closeDrawer = txUseCallback(() => setDrawerOpen(false), []);
  const openSummary  = txUseCallback(() => setShowSummary(true), []);
  const closeSummary = txUseCallback(() => setShowSummary(false), []);

  return {
    status, elapsed, lines, drawerOpen, summary, summaryErr, showSummary,
    moduleName,
    start, pause, stop, reset, summarize,
    openDrawer, closeDrawer, openSummary, closeSummary,
    setStatus,
  };
}

/* ---------- Icons (subset, reuse SupIcon when available) ---------- */
function TxIcon({ name, size = 16 }) {
  const s = { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round" };
  switch (name) {
    case "mic":       return <svg {...s}><path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/><path d="M19 10v2a7 7 0 0 1-14 0v-2M12 19v4M8 23h8"/></svg>;
    case "micOff":    return <svg {...s}><line x1="1" y1="1" x2="23" y2="23"/><path d="M9 9v3a3 3 0 0 0 5.12 2.12M15 9.34V4a3 3 0 0 0-5.94-.6"/><path d="M17 16.95A7 7 0 0 1 5 12v-2m14 0v2a7 7 0 0 1-.11 1.23M12 19v4M8 23h8"/></svg>;
    case "stop":      return <svg {...s}><rect x="6" y="6" width="12" height="12" rx="1.5"/></svg>;
    case "pause":     return <svg {...s}><rect x="6" y="4" width="4" height="16"/><rect x="14" y="4" width="4" height="16"/></svg>;
    case "play":      return <svg {...s}><polygon points="6 4 20 12 6 20 6 4" fill="currentColor"/></svg>;
    case "sparkle":   return <svg {...s}><path d="M12 3l1.8 4.7L18 9l-4.2 1.3L12 15l-1.8-4.7L6 9l4.2-1.3z"/><path d="M5 18l.6 1.4L7 20l-1.4.6L5 22l-.6-1.4L3 20l1.4-.6z"/><path d="M19 16l.6 1.4L21 18l-1.4.6L19 20l-.6-1.4L17 18l1.4-.6z"/></svg>;
    case "transcript":return <svg {...s}><rect x="4" y="3" width="16" height="18" rx="2"/><line x1="8" y1="8"  x2="16" y2="8"/><line x1="8" y1="12" x2="16" y2="12"/><line x1="8" y1="16" x2="13" y2="16"/></svg>;
    case "close":     return <svg {...s}><line x1="18" y1="6" x2="6"  y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>;
    case "download":  return <svg {...s}><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>;
    case "copy":      return <svg {...s}><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>;
    case "retry":     return <svg {...s}><polyline points="23 4 23 10 17 10"/><path d="M20.49 15A9 9 0 1 1 18.36 5.64L23 10"/></svg>;
    default: return null;
  }
}

/* ============================================================
   Button — the main "Record" / "Recording 02:14" / "Stop" pill.
   Lives in the page header / topbar. Single source of truth for
   recording state.
   ============================================================ */
function TranscribeButton({ tx, variant = "v1" }) {
  if (tx.status === "idle") {
    return (
      <button className={`tx-btn tx-btn-idle tx-${variant}`} type="button" onClick={tx.start}>
        <TxIcon name="mic" size={14} />
        <span>Record session</span>
      </button>
    );
  }
  if (tx.status === "recording" || tx.status === "paused") {
    return (
      <div className={`tx-btn-group tx-${variant}`}>
        <button
          className={`tx-btn tx-btn-live ${tx.status === "paused" ? "is-paused" : ""}`}
          type="button"
          onClick={tx.openDrawer}
          title="Open live transcript"
        >
          <span className="tx-live-dot" aria-hidden="true" />
          <span className="tx-live-text">{tx.status === "paused" ? "Paused" : "REC"}</span>
          <span className="tx-elapsed">{fmtElapsed(tx.elapsed)}</span>
          <span className="tx-divider" />
          <span className="tx-line-count">{tx.lines.length} lines</span>
        </button>
        <button
          className="tx-icon-step"
          type="button"
          onClick={() => tx.status === "recording" ? tx.pause() : tx.setStatus("recording")}
          title={tx.status === "recording" ? "Pause" : "Resume"}
        >
          <TxIcon name={tx.status === "recording" ? "pause" : "play"} size={14} />
        </button>
        <button className="tx-icon-step tx-icon-stop" type="button" onClick={tx.stop} title="Stop recording">
          <TxIcon name="stop" size={14} />
        </button>
      </div>
    );
  }
  /* stopped or summarizing */
  return (
    <div className={`tx-btn-group tx-${variant}`}>
      <button className="tx-btn tx-btn-summary" type="button" onClick={tx.summarize} disabled={tx.status === "summarizing"}>
        <TxIcon name="sparkle" size={14} />
        <span>{tx.status === "summarizing" ? "Summarising…" : "AI summary"}</span>
      </button>
      <button className="tx-icon-step" type="button" onClick={tx.openDrawer} title="Open transcript">
        <TxIcon name="transcript" size={14} />
      </button>
      <button className="tx-icon-step" type="button" onClick={tx.reset} title="Discard & re-record">
        <TxIcon name="retry" size={14} />
      </button>
    </div>
  );
}

/* ============================================================
   Drawer — right-side slide-over showing the live transcript.
   Shows per-line speaker + item chip + relative timestamp.
   ============================================================ */
function TranscribeDrawer({ tx, variant = "v1" }) {
  const listRef = txUseRef(null);
  /* Auto-scroll to bottom when new lines arrive */
  txUseEffect(() => {
    if (!tx.drawerOpen || !listRef.current) return;
    const el = listRef.current;
    el.scrollTop = el.scrollHeight;
  }, [tx.lines.length, tx.drawerOpen]);

  if (!tx.drawerOpen) return null;

  const downloadTranscript = () => {
    const text = tx.lines.map(l => `[${fmtElapsed(l.ts)}] ${TX_PEOPLE[l.who].name} (on ${l.itemId}): ${l.text}`).join("\n");
    const blob = new Blob([text], { type: "text/plain;charset=utf-8" });
    const a = document.createElement("a");
    a.href = URL.createObjectURL(blob);
    a.download = `${tx.moduleName.replace(/\s+/g, "-").toLowerCase()}-transcript.txt`;
    document.body.appendChild(a); a.click(); a.remove();
  };

  return (
    <div className={`tx-drawer-overlay tx-${variant}`} onClick={tx.closeDrawer}>
      <aside className="tx-drawer" role="dialog" aria-label="Workshop transcript" onClick={(e) => e.stopPropagation()}>
        <header className="tx-drawer-head">
          <div className="tx-drawer-headline">
            <div className="tx-drawer-eyebrow">
              {tx.status === "recording"   ? <><span className="tx-live-dot" /> Recording live</> :
               tx.status === "paused"      ? <>Paused</> :
               tx.status === "summarizing" ? <>Summarising</> :
                                             <>Recording stopped</>}
            </div>
            <h2>Session transcript</h2>
            <div className="tx-drawer-sub">{fmtElapsed(tx.elapsed)} elapsed · {tx.lines.length} {tx.lines.length === 1 ? "line" : "lines"}</div>
          </div>
          <button className="tx-icon-btn" type="button" onClick={tx.closeDrawer} aria-label="Close">
            <TxIcon name="close" size={14} />
          </button>
        </header>

        <div className="tx-drawer-toolbar">
          {tx.status === "recording" && (
            <button className="tx-chip" type="button" onClick={tx.pause}>
              <TxIcon name="pause" size={12} /> Pause
            </button>
          )}
          {tx.status === "paused" && (
            <button className="tx-chip" type="button" onClick={() => tx.setStatus("recording")}>
              <TxIcon name="play" size={12} /> Resume
            </button>
          )}
          {(tx.status === "recording" || tx.status === "paused") && (
            <button className="tx-chip tx-chip-stop" type="button" onClick={tx.stop}>
              <TxIcon name="stop" size={12} /> Stop
            </button>
          )}
          {tx.status === "stopped" && (
            <button className="tx-chip tx-chip-primary" type="button" onClick={tx.summarize}>
              <TxIcon name="sparkle" size={12} /> Summarise with AI
            </button>
          )}
          <span className="tx-toolbar-spacer" />
          <button className="tx-chip" type="button" onClick={downloadTranscript} disabled={tx.lines.length === 0}>
            <TxIcon name="download" size={12} /> Export
          </button>
        </div>

        <div className="tx-drawer-body" ref={listRef}>
          {tx.lines.length === 0 ? (
            <div className="tx-empty">
              <div className="tx-empty-glyph"><TxIcon name="mic" size={20} /></div>
              <p className="tx-empty-title">Listening for the workshop…</p>
              <p className="tx-empty-sub">Transcribed lines will appear here as the conversation unfolds, anchored to the question being discussed.</p>
            </div>
          ) : (
            <ol className="tx-list">
              {tx.lines.map((l, i) => {
                const p = TX_PEOPLE[l.who];
                return (
                  <li key={i} className={`tx-line who-${l.who}`}>
                    <div className="tx-line-head">
                      <span className="tx-line-ts">{fmtElapsed(l.ts)}</span>
                      <span className="tx-line-who" style={{ color: p.hue }}>
                        <img src={`https://i.pravatar.cc/40?img=${p.avatar}`} alt="" />
                        <b>{p.short}</b>
                      </span>
                      <span className="tx-line-anchor">on {l.itemId}</span>
                    </div>
                    <div className="tx-line-text">{l.text}</div>
                  </li>
                );
              })}
            </ol>
          )}
        </div>
      </aside>
    </div>
  );
}

/* ============================================================
   Summary modal — shows the Claude output. Plain text from the
   model is rendered through a tiny markdown-ish formatter (just
   bold headers + bullets, nothing fancy).
   ============================================================ */
function renderAiText(text) {
  if (!text) return null;
  const blocks = [];
  const lines = text.replace(/\r/g, "").split("\n");
  let bulletBuf = [];
  const flushBullets = () => {
    if (bulletBuf.length) {
      blocks.push(<ul key={"ul-" + blocks.length} className="tx-ai-list">{bulletBuf.map((b, i) => <li key={i}>{renderInline(b)}</li>)}</ul>);
      bulletBuf = [];
    }
  };
  lines.forEach((raw) => {
    const line = raw.trim();
    if (!line) { flushBullets(); return; }
    /* Bold header like "**Headline**" — render as h4 */
    const hdr = line.match(/^\*\*(.+?)\*\*\s*:?$/);
    if (hdr) { flushBullets(); blocks.push(<h4 key={"h-" + blocks.length} className="tx-ai-h">{hdr[1]}</h4>); return; }
    /* Bullet */
    const bul = line.match(/^[-*\u2022]\s+(.*)$/);
    if (bul) { bulletBuf.push(bul[1]); return; }
    flushBullets();
    blocks.push(<p key={"p-" + blocks.length} className="tx-ai-p">{renderInline(line)}</p>);
  });
  flushBullets();
  return blocks;
}
function renderInline(text) {
  /* Replace **bold** runs with <b>, leave the rest as-is. */
  const parts = [];
  const re = /\*\*([^*]+)\*\*/g;
  let last = 0, m;
  while ((m = re.exec(text)) !== null) {
    if (m.index > last) parts.push(text.slice(last, m.index));
    parts.push(<b key={parts.length}>{m[1]}</b>);
    last = m.index + m[0].length;
  }
  if (last < text.length) parts.push(text.slice(last));
  return parts;
}

function TranscribeSummaryModal({ tx, variant = "v1" }) {
  if (!tx.showSummary) return null;
  const copy = async () => {
    if (!tx.summary) return;
    try { await navigator.clipboard.writeText(tx.summary); } catch {}
  };
  return (
    <div className={`tx-modal-overlay tx-${variant}`} onClick={tx.closeSummary}>
      <div className="tx-modal" role="dialog" aria-label="AI session summary" onClick={(e) => e.stopPropagation()}>
        <header className="tx-modal-head">
          <div className="tx-modal-headline">
            <span className="tx-modal-badge"><TxIcon name="sparkle" size={12} /> AI summary</span>
            <h2>{tx.moduleName} — session readout</h2>
            <div className="tx-modal-sub">Generated from {fmtElapsed(tx.elapsed)} of transcribed audio · {tx.lines.length} lines</div>
          </div>
          <button className="tx-icon-btn" type="button" onClick={tx.closeSummary} aria-label="Close">
            <TxIcon name="close" size={14} />
          </button>
        </header>

        <div className="tx-modal-body">
          {tx.status === "summarizing" && (
            <div className="tx-loading">
              <div className="tx-loading-shimmer" />
              <p>Reading the transcript, weighing each item, drafting the summary…</p>
            </div>
          )}
          {tx.summary && (
            <div className="tx-ai-output">{renderAiText(tx.summary)}</div>
          )}
          {tx.summaryErr && (
            <div className="tx-error">
              <b>Couldn't generate a summary.</b>
              <p>{tx.summaryErr}</p>
              <button className="tx-chip tx-chip-primary" type="button" onClick={tx.summarize}>
                <TxIcon name="retry" size={12} /> Try again
              </button>
            </div>
          )}
        </div>

        <footer className="tx-modal-foot">
          <span className="tx-modal-disclaimer">AI summaries can miss nuance — review before sharing.</span>
          <div className="tx-modal-actions">
            <button className="tx-chip" type="button" onClick={copy} disabled={!tx.summary}>
              <TxIcon name="copy" size={12} /> Copy
            </button>
            <button className="tx-chip tx-chip-primary" type="button" onClick={tx.closeSummary}>Close</button>
          </div>
        </footer>
      </div>
    </div>
  );
}

/* ---------- Export ---------- */
Object.assign(window, {
  useTranscribe,
  TX_PEOPLE,
  TX_DIALOGUE,
  TxIcon,
  TranscribeButton,
  TranscribeDrawer,
  TranscribeSummaryModal,
});
