/* global React, Icon, Button, Chip, ScreenHeader, Panel, SectionLabel, AgentNote, Dropzone, TONES, MEMORY_ITEMS, MEMORY_NUDGES */
const { useState: useMem } = React;

const MEM_STEPS_KEY = "offerroom.memory.steps";
const MEM_VIEW_KEY = "offerroom.memory.view";

const loadMemSteps = () => { try { return JSON.parse(localStorage.getItem(MEM_STEPS_KEY)) || {}; } catch { return {}; } };

// The strict, sequential order of operations for building memory.
const BUILD_STEPS = [
  {
    key: "files", icon: "folder", title: "Drop in your materials",
    sub: "Start here. Decks, docs, old résumés, code, transcripts. This is the raw material every résumé and answer is built from.",
  },
  {
    key: "voice", icon: "mic", title: "Say it out loud",
    sub: "Record the stories you'd never write in a doc. Offerroom transcribes it and adds it to your memory. Optional, but it's where the good detail lives.",
  },
  {
    key: "nudges", icon: "lightbulb", title: "Answer the nudges",
    sub: "A few quick prompts. The personal stuff is what makes outreach and interviews feel human.",
  },
  {
    key: "note", icon: "edit", title: "Anything else worth knowing",
    sub: "One last brain-dump. A constraint you're navigating, the team you do your best work on. Then Offerroom builds the graph.",
  },
];

function ScrMemory({ onDone }) {
  const [view, setView] = useMem(() => localStorage.getItem(MEM_VIEW_KEY) || "guided"); // guided | populated
  const [done, setDone] = useMem(loadMemSteps); // { files: {label}, voice: {...}, ... }

  const setStep = (key, payload) => {
    const next = { ...done, [key]: payload };
    setDone(next);
    localStorage.setItem(MEM_STEPS_KEY, JSON.stringify(next));
  };
  const toView = (v) => { setView(v); localStorage.setItem(MEM_VIEW_KEY, v); };

  if (view === "populated") return <MemoryPopulated onReset={() => toView("guided")}/>;

  // active = first step not yet addressed; -1 when all done
  const activeIdx = BUILD_STEPS.findIndex(s => !done[s.key]);
  const allDone = activeIdx === -1;

  return (
    <div style={{ maxWidth: 1080, margin: "0 auto", padding: "8px 0 40px" }}>
      <ScreenHeader
        eyebrow="Step 2 · Memory"
        title="Let's build your memory, Maya"
        lede="Everything Offerroom writes for you starts here. Work through these 4 steps in order, then it becomes a graph of your stories and outcomes."
        actions={<Button variant="ghost" size="sm" icon="layers" onClick={() => toView("populated")}>I've done this before</Button>}
      />

      <AgentNote time="now" working={true}>
        New here? Do these in order. Each one builds on the last, materials first, then the stories behind them. Don't worry about getting it complete, you can always add to or update any of this later.
      </AgentNote>

      <div style={{ display: "flex", flexDirection: "column", gap: 12, marginTop: 16 }}>
        {BUILD_STEPS.map((s, i) => (
          <GuidedStep key={s.key} n={i + 1} step={s}
            state={done[s.key] ? "done" : i === activeIdx ? "active" : "locked"}
            summary={done[s.key]?.label}
            onReopen={() => setStep(s.key, undefined)}>
            <StepBody stepKey={s.key} onComplete={(payload) => setStep(s.key, payload)} done={done[s.key]}/>
          </GuidedStep>
        ))}
      </div>

      {allDone && (
        <div className="cad-rise" style={{ marginTop: 16 }}>
          <Panel pad={20} style={{ display: "flex", alignItems: "center", gap: 16, borderColor: "var(--sage-line)", background: "var(--sage-tint)" }}>
            <span style={{ width: 44, height: 44, borderRadius: 999, background: "#5A7150", color: "#fff", display: "grid", placeItems: "center", flexShrink: 0 }}>
              <Icon name="check" size={22}/>
            </span>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontFamily: "var(--font-display)", fontSize: 19, fontWeight: 500, color: "var(--sage-text)" }}>Your memory is ready</div>
              <div style={{ fontSize: 13, color: "var(--sage-text)", opacity: 0.85, marginTop: 2, display: "flex", alignItems: "center", gap: 7 }}>
                <span className="cad-pulse-dot"/> Offerroom is linking your stories and outcomes into a graph. You can keep adding any time.
              </div>
            </div>
            <Button variant="secondary" size="sm" icon="layers" onClick={() => toView("populated")}>See my memory</Button>
          </Panel>
        </div>
      )}
    </div>
  );
}

// ---- One step in the sequential guide ----
function GuidedStep({ n, step, state, summary, children, onReopen }) {
  const active = state === "active", isDone = state === "done", locked = state === "locked";
  return (
    <Panel pad={0} style={{
      borderColor: active ? "rgba(140,21,21,0.22)" : "rgba(31,27,22,0.08)",
      boxShadow: active ? "0 8px 24px rgba(31,27,22,0.08)" : "0 1px 2px rgba(31,27,22,0.04)",
      opacity: locked ? 0.6 : 1, transition: "opacity 160ms",
    }}>
      <div style={{ display: "flex", gap: 14, padding: active ? "16px 18px 4px" : "15px 18px", alignItems: "flex-start" }}>
        <span style={{
          width: 28, height: 28, borderRadius: 999, flexShrink: 0, display: "grid", placeItems: "center",
          fontSize: 13, fontWeight: 600, fontVariantNumeric: "tabular-nums", marginTop: 1,
          background: active ? "#8C1515" : isDone ? "#5A7150" : "#fff",
          color: active || isDone ? "#fff" : "var(--fg-2)",
          border: active || isDone ? "1px solid transparent" : "1px solid var(--ink-100)",
        }}>{isDone ? <Icon name="check" size={14}/> : n}</span>

        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 9 }}>
            <Icon name={step.icon} size={16} style={{ color: active ? "var(--cardinal)" : "var(--fg-2)", flexShrink: 0 }}/>
            <span style={{ fontSize: 15.5, fontWeight: 600, color: "var(--fg-1)" }}>{step.title}</span>
            <span style={{ fontSize: 11, color: "var(--fg-3)", fontFamily: "var(--font-mono)", marginLeft: 2, whiteSpace: "nowrap" }}>Step {n} of 4</span>
            {isDone && <span style={{ marginLeft: "auto" }}><Chip tone="offer">Done</Chip></span>}
            {locked && <span style={{ marginLeft: "auto", fontSize: 11.5, color: "var(--fg-3)" }}>Up next</span>}
          </div>
          {(active || locked) && <div style={{ fontSize: 13, color: "var(--fg-2)", lineHeight: 1.5, marginTop: 6, maxWidth: 620 }}>{step.sub}</div>}
          {isDone && (
            <div style={{ display: "flex", alignItems: "center", gap: 10, marginTop: 5 }}>
              <span style={{ fontSize: 13, color: "var(--fg-2)" }}>{summary}</span>
              <button onClick={onReopen} style={{ background: "transparent", border: "none", cursor: "pointer", color: "var(--fg-2)", fontSize: 12, fontFamily: "var(--font-sans)", display: "inline-flex", alignItems: "center", gap: 4, padding: 0 }}>
                <Icon name="edit" size={12}/> Change
              </button>
            </div>
          )}
        </div>
      </div>
      {active && <div className="cad-fade" style={{ padding: "8px 18px 18px 60px" }}>{children}</div>}
    </Panel>
  );
}

// ---- The interactive body for whichever step is active ----
function StepBody({ stepKey, onComplete }) {
  if (stepKey === "files") return <FilesStep onComplete={onComplete}/>;
  if (stepKey === "voice") return <VoiceStep onComplete={onComplete}/>;
  if (stepKey === "nudges") return <NudgesStep onComplete={onComplete}/>;
  return <NoteStep onComplete={onComplete}/>;
}

function FilesStep({ onComplete }) {
  const [files, setFiles] = useMem([]);
  const add = () => {
    const pool = ["Plaid_Growth_QBR_Q3.pptx", "checkout-experiment-writeup.md", "Resume — Okonkwo 2026.pdf", "Case studies / 2024"];
    setFiles(f => f.length < pool.length ? [...f, pool[f.length]] : f);
  };
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
      <Dropzone icon="folder" title="Drop files or a whole folder" onClick={add}
        sub="Presentations, code, writeups, transcripts, old résumés. Audio and video get transcribed automatically. Nothing is shared, this is yours."/>
      {files.length > 0 && (
        <div className="cad-fade" style={{ display: "flex", flexDirection: "column", gap: 6 }}>
          {files.map((f, i) => (
            <div key={i} style={{ display: "flex", alignItems: "center", gap: 10, padding: "8px 12px", borderRadius: 8, background: "var(--paper)", border: "1px solid var(--ink-100)" }}>
              <Icon name="fileText" size={15} style={{ color: "var(--fg-2)", flexShrink: 0 }}/>
              <span style={{ fontSize: 13, flex: 1, minWidth: 0, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{f}</span>
              <span style={{ fontSize: 11, color: "var(--sage-text)", display: "inline-flex", alignItems: "center", gap: 4 }}><span style={{ width: 6, height: 6, borderRadius: 999, background: "#5A7150" }}/>Indexed</span>
            </div>
          ))}
        </div>
      )}
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
        <button onClick={add} style={ghostLink}><Icon name="plus" size={14}/> Add more</button>
        <Button variant="primary" size="sm" icon="arrow"
          onClick={() => onComplete({ label: files.length ? `${files.length} ${files.length === 1 ? "source" : "sources"} added · Offerroom is indexing` : "Skipped for now" })}>
          Continue
        </Button>
      </div>
    </div>
  );
}

function VoiceStep({ onComplete }) {
  const [recording, setRecording] = useMem(false);
  const [secs, setSecs] = useMem(0);
  React.useEffect(() => {
    if (!recording) return;
    const t = setInterval(() => setSecs(s => s + 1), 1000);
    return () => clearInterval(t);
  }, [recording]);
  const mmss = `${Math.floor(secs / 60)}:${String(secs % 60).padStart(2, "0")}`;
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
      <div style={{ display: "flex", alignItems: "center", gap: 14, padding: "12px 14px", borderRadius: 10, background: "var(--paper)", border: "1px solid var(--ink-100)" }}>
        <button onClick={() => setRecording(r => !r)} style={{
          width: 52, height: 52, borderRadius: 999, border: "none", cursor: "pointer", flexShrink: 0,
          background: recording ? "#8C1515" : "#fff", color: recording ? "#fff" : "var(--cardinal)",
          boxShadow: recording ? "0 0 0 6px rgba(140,21,21,0.14)" : "inset 0 0 0 1px var(--ink-100)",
          display: "grid", placeItems: "center", transition: "all 160ms cubic-bezier(0.2,0.7,0.1,1)",
        }}><Icon name="mic" size={22}/></button>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 14, fontWeight: 500 }}>{recording ? `Listening… ${mmss}` : secs > 0 ? `Recorded · ${mmss}` : "Record a voice note"}</div>
          <div style={{ fontSize: 12, color: "var(--fg-2)", marginTop: 2 }}>Transcription only, not a voice agent. The transcript joins your memory.</div>
        </div>
        {recording && (
          <div className="cad-fade" style={{ display: "flex", alignItems: "center", gap: 3, height: 28, width: 120 }}>
            {Array.from({ length: 22 }).map((_, i) => (
              <span key={i} style={{ flex: 1, borderRadius: 999, background: "var(--cardinal-100)",
                height: (8 + Math.abs(Math.sin(i * 0.9)) * 16) + "px", animation: `cad-pulse ${0.7 + (i % 5) * 0.12}s ease-in-out infinite` }}/>
            ))}
          </div>
        )}
      </div>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
        <button onClick={() => onComplete({ label: "Skipped for now" })} style={ghostLink}>Skip for now</button>
        <Button variant="primary" size="sm" icon="arrow"
          onClick={() => { setRecording(false); onComplete({ label: secs > 0 ? `Voice note added · ${mmss}` : "Skipped for now" }); }}>
          {secs > 0 ? "Save & continue" : "Continue"}
        </Button>
      </div>
    </div>
  );
}

function NudgesStep({ onComplete }) {
  return (
    <NudgeList renderFooter={(count) => (
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginTop: 12 }}>
        <button onClick={() => onComplete({ label: "Skipped for now" })} style={ghostLink}>Skip for now</button>
        <Button variant="primary" size="sm" icon="arrow"
          onClick={() => onComplete({ label: count ? `${count} answered` : "Skipped for now" })}>
          Continue
        </Button>
      </div>
    )}/>
  );
}

function NoteStep({ onComplete }) {
  const [text, setText] = useMem("");
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
      <textarea value={text} onChange={e => setText(e.target.value)} rows={4}
        placeholder="A win that never made it onto a résumé. A constraint you're navigating. The kind of team you do your best work on. Type or dictate, it all helps."
        style={{ width: "100%", boxSizing: "border-box", resize: "vertical", padding: "11px 12px", borderRadius: 8,
          border: "1px solid var(--ink-100)", background: "#fff", fontFamily: "var(--font-sans)", fontSize: 13.5, lineHeight: 1.5, color: "var(--fg-1)", outline: "none" }}/>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
        <button style={ghostLink}><Icon name="mic" size={14}/> Dictate instead</button>
        <Button variant="primary" size="sm" icon="check"
          onClick={() => onComplete({ label: text.trim() ? "Note added to memory" : "Skipped for now" })}>
          {text.trim() ? "Add & finish" : "Finish"}
        </Button>
      </div>
    </div>
  );
}

const ghostLink = {
  display: "inline-flex", alignItems: "center", gap: 6, background: "transparent", border: "none",
  cursor: "pointer", color: "var(--fg-2)", fontSize: 12.5, fontFamily: "var(--font-sans)", padding: 0,
};

// ============================================================
// Nudge card — answer a prompt by text, voice, or files.
// ============================================================
const NUDGE_MODES = [
  { key: "text", icon: "edit", label: "Write" },
  { key: "voice", icon: "mic", label: "Record" },
  { key: "files", icon: "upload", label: "Attach" },
];
const fmtDur = (s) => Math.floor(s / 60) + ":" + String(s % 60).padStart(2, "0");
const nudgeShell = { display: "flex", gap: 10, alignItems: "flex-start", padding: "11px 13px", borderRadius: 10, border: "1px solid var(--ink-100)", background: "var(--paper)", fontFamily: "var(--font-sans)" };
const nudgeDot = { width: 18, height: 18, borderRadius: 999, flexShrink: 0, marginTop: 1, display: "grid", placeItems: "center", border: "1.5px solid var(--ink-300)" };
const iconBtn = { display: "grid", placeItems: "center", width: 26, height: 26, borderRadius: 6, cursor: "pointer", border: "1px solid var(--ink-100)", background: "#fff", color: "var(--fg-2)" };

function NudgeCard({ q, answer, onSave, onClear }) {
  const [mode, setMode] = useMem(null);   // null collapsed, or text|voice|files
  const [text, setText] = useMem("");
  const [recording, setRecording] = useMem(false);
  const [secs, setSecs] = useMem(0);
  const [files, setFiles] = useMem([]);
  const fileRef = React.useRef(null);

  React.useEffect(() => {
    if (!recording) return;
    const id = setInterval(() => setSecs(s => s + 1), 1000);
    return () => clearInterval(id);
  }, [recording]);

  const reset = () => { setMode(null); setText(""); setRecording(false); setSecs(0); setFiles([]); };
  const open = (m) => { setText(""); setRecording(false); setSecs(0); setFiles([]); setMode(m); };
  const saveText = () => { if (!text.trim()) return; onSave({ type: "text", summary: text.trim().split(/\s+/).length + " words", detail: text.trim() }); reset(); };
  const saveVoice = () => { onSave({ type: "voice", summary: "Voice note · " + fmtDur(secs || 1) }); reset(); };
  const addFiles = (e) => { const names = [...(e.target.files || [])].map(f => f.name); if (names.length) setFiles(f => [...f, ...names]); };
  const saveFiles = () => { if (!files.length) return; onSave({ type: "files", summary: files.length + (files.length === 1 ? " file" : " files"), detail: files.join(", ") }); reset(); };

  // Answered & collapsed
  if (answer && mode == null) {
    const ic = answer.type === "voice" ? "mic" : answer.type === "files" ? "fileText" : "edit";
    return (
      <div style={{ ...nudgeShell, background: "var(--sage-tint)", border: "1px solid var(--sage-line)" }}>
        <span style={{ ...nudgeDot, background: "#5A7150", border: "none", color: "#fff" }}><Icon name="check" size={11}/></span>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 13, lineHeight: 1.45, color: "var(--sage-text)" }}>{q}</div>
          <div style={{ display: "flex", alignItems: "center", gap: 6, marginTop: 5, fontSize: 11.5, color: "var(--sage-text)", fontWeight: 500 }}>
            <Icon name={ic} size={12}/> {answer.summary}
          </div>
          {answer.detail && (
            <div style={{ fontSize: 12, color: "var(--fg-2)", marginTop: 4, lineHeight: 1.5, whiteSpace: "pre-wrap", display: "-webkit-box", WebkitLineClamp: 2, WebkitBoxOrient: "vertical", overflow: "hidden" }}>{answer.detail}</div>
          )}
        </div>
        <div style={{ display: "flex", gap: 4, flexShrink: 0 }}>
          <button onClick={() => open(answer.type)} style={iconBtn} title="Edit answer"><Icon name="edit" size={13}/></button>
          <button onClick={onClear} style={iconBtn} title="Remove answer"><Icon name="close" size={13}/></button>
        </div>
      </div>
    );
  }

  return (
    <div style={{ ...nudgeShell, flexDirection: "column", alignItems: "stretch" }}>
      <div style={{ display: "flex", gap: 10, alignItems: "flex-start" }}>
        <span style={nudgeDot}><Icon name="plus" size={11} style={{ color: "var(--fg-3)" }}/></span>
        <div style={{ flex: 1, fontSize: 13, lineHeight: 1.45, color: "var(--fg-1)" }}>{q}</div>
      </div>

      <div style={{ display: "flex", gap: 6, marginTop: 11, marginLeft: 28, flexWrap: "wrap" }}>
        {NUDGE_MODES.map(md => {
          const on = mode === md.key;
          return (
            <button key={md.key} onClick={() => (on ? reset() : open(md.key))} style={{
              display: "inline-flex", alignItems: "center", gap: 5, padding: "5px 10px", fontSize: 12, fontWeight: 500,
              fontFamily: "var(--font-sans)", cursor: "pointer", borderRadius: 7, transition: "all 120ms",
              border: on ? "1px solid var(--cardinal)" : "1px solid var(--ink-100)",
              background: on ? "var(--cardinal-tint, rgba(140,21,21,0.06))" : "#fff",
              color: on ? "var(--cardinal)" : "var(--fg-2)",
            }}><Icon name={md.icon} size={13}/> {md.label}</button>
          );
        })}
      </div>

      {mode === "text" && (
        <div className="cad-fade" style={{ marginTop: 10, marginLeft: 28 }}>
          <textarea autoFocus value={text} onChange={e => setText(e.target.value)} rows={3}
            placeholder="Type your answer. A sentence or two is plenty."
            style={{ width: "100%", boxSizing: "border-box", resize: "vertical", padding: "10px 11px", borderRadius: 8,
              border: "1px solid var(--ink-100)", background: "#fff", fontFamily: "var(--font-sans)", fontSize: 13, lineHeight: 1.5, color: "var(--fg-1)", outline: "none" }}/>
          <div style={{ display: "flex", justifyContent: "flex-end", gap: 8, marginTop: 8 }}>
            <button onClick={reset} style={ghostLink}>Cancel</button>
            <Button variant="primary" size="sm" icon="check" disabled={!text.trim()} onClick={saveText}>Save answer</Button>
          </div>
        </div>
      )}

      {mode === "voice" && (
        <div className="cad-fade" style={{ marginTop: 10, marginLeft: 28 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 14, padding: "12px 14px", borderRadius: 10, border: "1px solid var(--ink-100)", background: "#fff" }}>
            <button onClick={() => setRecording(r => !r)} style={{
              width: 44, height: 44, borderRadius: 999, border: "none", cursor: "pointer", flexShrink: 0,
              background: recording ? "#8C1515" : "#fff", color: recording ? "#fff" : "var(--cardinal)",
              boxShadow: recording ? "0 0 0 5px rgba(140,21,21,0.14)" : "inset 0 0 0 1px var(--ink-100)",
              display: "grid", placeItems: "center", transition: "all 160ms cubic-bezier(0.2,0.7,0.1,1)",
            }}><Icon name={recording ? "close" : "mic"} size={18}/></button>
            {recording ? (
              <div style={{ flex: 1, display: "flex", alignItems: "center", gap: 3, height: 24 }}>
                {Array.from({ length: 28 }).map((_, i) => (
                  <span key={i} style={{ flex: 1, borderRadius: 999, background: "var(--cardinal-100)",
                    height: (6 + Math.abs(Math.sin(i * 0.9 + secs)) * 16) + "px", animation: `cad-pulse ${0.7 + (i % 5) * 0.12}s ease-in-out infinite` }}/>
                ))}
              </div>
            ) : (
              <div style={{ flex: 1, fontSize: 12.5, color: "var(--fg-2)" }}>{secs ? "Recorded — tap mic to redo" : "Tap the mic and talk. We transcribe it into memory."}</div>
            )}
            <span style={{ fontFamily: "var(--font-mono)", fontSize: 12.5, color: recording ? "var(--cardinal)" : "var(--fg-3)", fontVariantNumeric: "tabular-nums" }}>{fmtDur(secs)}</span>
          </div>
          <div style={{ display: "flex", justifyContent: "flex-end", gap: 8, marginTop: 8 }}>
            <button onClick={reset} style={ghostLink}>Cancel</button>
            <Button variant="primary" size="sm" icon="check" disabled={!secs} onClick={saveVoice}>Save voice note</Button>
          </div>
        </div>
      )}

      {mode === "files" && (
        <div className="cad-fade" style={{ marginTop: 10, marginLeft: 28 }}>
          <input ref={fileRef} type="file" multiple style={{ display: "none" }} onChange={addFiles}/>
          <button onClick={() => fileRef.current && fileRef.current.click()} style={{
            width: "100%", display: "flex", alignItems: "center", justifyContent: "center", gap: 8, padding: "14px",
            borderRadius: 10, border: "1.5px dashed var(--ink-300)", background: "#fff", cursor: "pointer",
            fontFamily: "var(--font-sans)", fontSize: 13, color: "var(--fg-2)",
          }}><Icon name="upload" size={15}/> Choose files to attach</button>
          {files.length > 0 && (
            <div style={{ display: "flex", flexDirection: "column", gap: 6, marginTop: 8 }}>
              {files.map((f, i) => (
                <div key={i} style={{ display: "flex", alignItems: "center", gap: 8, padding: "7px 10px", borderRadius: 7, background: "#fff", border: "1px solid var(--ink-100)", fontSize: 12.5 }}>
                  <Icon name="fileText" size={14} style={{ color: "var(--fg-2)", flexShrink: 0 }}/>
                  <span style={{ flex: 1, minWidth: 0, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{f}</span>
                  <button onClick={() => setFiles(list => list.filter((_, x) => x !== i))} style={{ ...iconBtn, width: 22, height: 22, border: "none" }}><Icon name="close" size={12}/></button>
                </div>
              ))}
            </div>
          )}
          <div style={{ display: "flex", justifyContent: "flex-end", gap: 8, marginTop: 8 }}>
            <button onClick={reset} style={ghostLink}>Cancel</button>
            <Button variant="primary" size="sm" icon="check" disabled={!files.length} onClick={saveFiles}>Attach to memory</Button>
          </div>
        </div>
      )}
    </div>
  );
}

// A rotating set of nudges with per-nudge answers and a refresh button.
function NudgeList({ batch = 2, label, lede, renderFooter }) {
  const [answers, setAnswers] = useMem({});      // nudge text -> answer
  const [shown, setShown] = useMem(() => MEMORY_NUDGES.slice(0, batch));
  const save = (text, a) => setAnswers(p => ({ ...p, [text]: a }));
  const clear = (text) => setAnswers(p => { const n = { ...p }; delete n[text]; return n; });
  const refresh = () => setShown(cur => {
    const pool = MEMORY_NUDGES.filter(n => !answers[n]);        // unanswered
    const notShown = pool.filter(n => !cur.includes(n));
    const queue = notShown.length ? notShown : pool;            // wrap if exhausted
    let qi = 0;
    return cur.map(n => answers[n] ? n : (queue[qi++] ?? n));   // keep answered pinned, swap the rest
  });
  const count = Object.keys(answers).length;
  return (
    <>
      <div style={{ display: "flex", alignItems: "flex-start", justifyContent: "space-between", gap: 12, marginBottom: lede ? 4 : 10 }}>
        {label ? <SectionLabel>{label}</SectionLabel> : <span/>}
        <button onClick={refresh} title="Show me different prompts" style={{
          display: "inline-flex", alignItems: "center", gap: 6, padding: "5px 10px", fontSize: 12, fontWeight: 500,
          fontFamily: "var(--font-sans)", cursor: "pointer", borderRadius: 7, flexShrink: 0,
          border: "1px solid var(--ink-100)", background: "#fff", color: "var(--cardinal)",
        }}><Icon name="refresh" size={13}/> New nudges</button>
      </div>
      {lede && <div style={{ fontSize: 12.5, color: "var(--fg-2)", marginBottom: 12 }}>{lede}</div>}
      <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
        {shown.map((n) => (
          <NudgeCard key={n} q={n} answer={answers[n]} onSave={a => save(n, a)} onClear={() => clear(n)}/>
        ))}
      </div>
      {renderFooter && renderFooter(count)}
    </>
  );
}

// ============================================================
// Populated state — the returning-user manage view.
// ============================================================
function MemoryPopulated({ onReset }) {
  const [recording, setRecording] = useMem(false);
  return (
    <div style={{ maxWidth: 1080, margin: "0 auto", padding: "8px 0 40px" }}>
      <ScreenHeader
        eyebrow="Step 2 · Memory"
        title="Dump everything. Offerroom sorts it out."
        lede="Decks, docs, code, voice notes, the half-story you'd tell a friend. It all goes into your private memory and powers every résumé and answer from here on."
        actions={<>
          <Button variant="ghost" size="sm" icon="rotate" onClick={onReset}>Guided setup</Button>
          <Button variant="secondary" size="sm" icon="eye">Storage · 2.4 GB of 10 GB</Button>
        </>}
      />

      <div style={{ display: "grid", gridTemplateColumns: "1.25fr 1fr", gap: 16, alignItems: "start" }}>
        <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
          <Dropzone icon="folder" tall title="Drop files or a whole folder"
            sub="Presentations, code, writeups, transcripts, old résumés. Audio and video get transcribed automatically. Nothing is shared, this is yours."/>

          <MemoryStore/>
        </div>

        <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
          <Panel pad={18}>
            <SectionLabel style={{ marginBottom: 12 }}>Say it out loud</SectionLabel>
            <div style={{ display: "flex", alignItems: "center", gap: 14 }}>
              <button onClick={() => setRecording(r => !r)} style={{
                width: 52, height: 52, borderRadius: 999, border: "none", cursor: "pointer", flexShrink: 0,
                background: recording ? "#8C1515" : "#fff", color: recording ? "#fff" : "var(--cardinal)",
                boxShadow: recording ? "0 0 0 6px rgba(140,21,21,0.14)" : "inset 0 0 0 1px var(--ink-100)",
                display: "grid", placeItems: "center", transition: "all 160ms cubic-bezier(0.2,0.7,0.1,1)",
              }}><Icon name="mic" size={22}/></button>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 14, fontWeight: 500 }}>{recording ? "Listening… talk freely" : "Record a voice note"}</div>
                <div style={{ fontSize: 12, color: "var(--fg-2)", marginTop: 2 }}>Transcription only, not a voice agent. The transcript joins your memory.</div>
              </div>
            </div>
            {recording && (
              <div className="cad-fade" style={{ marginTop: 14, display: "flex", alignItems: "center", gap: 3, height: 28 }}>
                {Array.from({ length: 40 }).map((_, i) => (
                  <span key={i} style={{ flex: 1, borderRadius: 999, background: "var(--cardinal-100)",
                    height: (8 + Math.abs(Math.sin(i * 0.9)) * 18) + "px", animation: `cad-pulse ${0.7 + (i % 5) * 0.12}s ease-in-out infinite` }}/>
                ))}
              </div>
            )}
          </Panel>

          <Panel pad={18}>
            <NudgeList label="Nudges"
              lede="The personal stuff makes outreach and interviews feel human. Answer any that spark something — type it, say it, or attach a file."/>
          </Panel>

          <Panel pad={18}>
            <SectionLabel style={{ marginBottom: 10 }}>Anything else worth knowing</SectionLabel>
            <textarea placeholder="A win that never made it onto a résumé. A constraint you're navigating. The kind of team you do your best work on. Type or dictate, it all helps."
              rows={4} style={{
                width: "100%", boxSizing: "border-box", resize: "vertical", padding: "11px 12px", borderRadius: 8,
                border: "1px solid var(--ink-100)", background: "#fff", fontFamily: "var(--font-sans)",
                fontSize: 13.5, lineHeight: 1.5, color: "var(--fg-1)", outline: "none",
              }}/>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginTop: 10 }}>
              <button style={ghostLink}><Icon name="mic" size={14}/> Dictate instead</button>
              <Button variant="secondary" size="sm" icon="plus">Add to memory</Button>
            </div>
          </Panel>
        </div>
      </div>
    </div>
  );
}

// ============================================================
// Memory store — manage view with select, delete (single +
// bulk), and organisation by Type / Collection.
// ============================================================
const COLLECTION_OF = { resume: "Career docs", doc: "Career docs", folder: "Career docs", audio: "Stories & voice", life: "Personal" };
const TYPE_LABEL = { resume: "Résumés", doc: "Documents", folder: "Folders", audio: "Voice notes", life: "Personal" };
const NEW_COLLECTION = "＋ New collection…";

function MemoryStore() {
  const [items, setItems] = useMem(() => MEMORY_ITEMS.map((m, i) => ({ ...m, id: "m" + i, collection: COLLECTION_OF[m.kind] || "Career docs" })));
  const [collections, setCollections] = useMem(["Career docs", "Stories & voice", "Personal"]);
  const [selected, setSelected] = useMem(() => new Set());
  const [groupBy, setGroupBy] = useMem("none"); // none | type | collection
  const [query, setQuery] = useMem("");
  const [editing, setEditing] = useMem(null);   // collection name being renamed
  const [draft, setDraft] = useMem("");          // rename / create draft
  const [creating, setCreating] = useMem(false);

  const visible = items.filter(m => m.name.toLowerCase().includes(query.trim().toLowerCase()));
  const allChecked = visible.length > 0 && visible.every(m => selected.has(m.id));
  const someChecked = selected.size > 0;
  const chunks = items.reduce((s, m) => s + m.chunks, 0);

  const toggle = (id) => setSelected(s => { const n = new Set(s); n.has(id) ? n.delete(id) : n.add(id); return n; });
  const toggleAll = () => setSelected(s => allChecked ? new Set() : new Set(visible.map(m => m.id)));
  const clearSel = () => setSelected(new Set());
  const removeIds = (ids) => { setItems(list => list.filter(m => !ids.includes(m.id))); setSelected(s => { const n = new Set(s); ids.forEach(i => n.delete(i)); return n; }); };
  const deleteSelected = () => removeIds([...selected]);
  const moveSelected = (collection) => { const ids = new Set(selected); setItems(list => list.map(m => ids.has(m.id) ? { ...m, collection } : m)); clearSel(); };

  // Collection CRUD
  const addCollection = (name) => {
    const n = (name || "").trim();
    if (!n || collections.some(c => c.toLowerCase() === n.toLowerCase())) return false;
    setCollections(cs => [...cs, n]);
    return true;
  };
  const renameCollection = (oldName, next) => {
    const n = (next || "").trim();
    if (!n || (n.toLowerCase() !== oldName.toLowerCase() && collections.some(c => c.toLowerCase() === n.toLowerCase()))) return;
    setCollections(cs => cs.map(c => c === oldName ? n : c));
    setItems(list => list.map(m => m.collection === oldName ? { ...m, collection: n } : m));
  };
  const deleteCollection = (name) => {
    setCollections(cs => cs.filter(c => c !== name));
    setItems(list => list.map(m => m.collection === name ? { ...m, collection: null } : m));
  };
  const moveToNew = () => {
    const n = (window.prompt("Name the new collection") || "").trim();
    if (!n) return;
    if (!collections.some(c => c.toLowerCase() === n.toLowerCase())) setCollections(cs => [...cs, n]);
    moveSelected(n);
  };
  const startRename = (name) => { setEditing(name); setDraft(name); };
  const commitRename = () => { if (editing != null) renameCollection(editing, draft); setEditing(null); setDraft(""); };
  const startCreate = () => { setGroupBy("collection"); setCreating(true); setDraft(""); };
  const commitCreate = () => { if (draft.trim()) addCollection(draft); setCreating(false); setDraft(""); };

  // Build groups for rendering
  let groups;
  if (groupBy === "none") {
    groups = [{ label: null, rows: visible }];
  } else if (groupBy === "type") {
    const map = new Map();
    visible.forEach(m => { const k = TYPE_LABEL[m.kind] || "Other"; if (!map.has(k)) map.set(k, []); map.get(k).push(m); });
    groups = Object.values(TYPE_LABEL).filter(k => map.has(k)).map(k => ({ label: k, rows: map.get(k) }));
  } else {
    // collection — show every collection (even empty) so they can be managed, plus Unfiled
    const map = new Map();
    visible.forEach(m => { const k = m.collection || "__unfiled__"; if (!map.has(k)) map.set(k, []); map.get(k).push(m); });
    groups = collections.map(name => ({ label: name, collection: name, editable: true, rows: map.get(name) || [] }));
    if (map.has("__unfiled__")) groups.push({ label: "Unfiled", collection: null, editable: false, rows: map.get("__unfiled__") });
  }

  const segBtn = (val, label) => (
    <button onClick={() => setGroupBy(val)} style={{
      padding: "5px 11px", fontSize: 12, fontWeight: 500, cursor: "pointer", borderRadius: 6,
      fontFamily: "var(--font-sans)", border: "none", transition: "all 120ms",
      background: groupBy === val ? "#fff" : "transparent",
      color: groupBy === val ? "var(--fg-1)" : "var(--fg-2)",
      boxShadow: groupBy === val ? "0 1px 2px rgba(0,0,0,0.08), 0 0 0 1px var(--ink-100)" : "none",
    }}>{label}</button>
  );

  return (
    <Panel pad={0}>
      {/* Header / selection bar */}
      {someChecked ? (
        <div className="cad-fade" style={{ padding: "9px 16px", borderBottom: "1px solid var(--cardinal-line, rgba(140,21,21,0.18))", background: "var(--cardinal-tint, rgba(140,21,21,0.05))", display: "flex", alignItems: "center", gap: 12 }}>
          <Check on={allChecked} onClick={toggleAll}/>
          <span style={{ fontSize: 13, fontWeight: 600, color: "var(--cardinal)", whiteSpace: "nowrap" }}>{selected.size} selected</span>
          <div style={{ flex: 1 }}/>
          <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
            <span style={{ fontSize: 12, color: "var(--fg-2)" }}>Move to</span>
            <select value="" onChange={e => { if (e.target.value === NEW_COLLECTION) moveToNew(); else if (e.target.value) moveSelected(e.target.value); }} style={{
              fontFamily: "var(--font-sans)", fontSize: 12.5, color: "var(--fg-1)", padding: "6px 8px",
              borderRadius: 6, border: "1px solid var(--ink-100)", background: "#fff", cursor: "pointer",
            }}>
              <option value="" disabled>Collection…</option>
              {collections.map(c => <option key={c} value={c}>{c}</option>)}
              <option value={NEW_COLLECTION}>{NEW_COLLECTION}</option>
            </select>
          </div>
          <button onClick={deleteSelected} style={{
            display: "inline-flex", alignItems: "center", gap: 6, padding: "6px 11px", fontSize: 13, fontWeight: 500,
            fontFamily: "var(--font-sans)", cursor: "pointer", borderRadius: 6, border: "1px solid var(--cardinal)",
            background: "var(--cardinal)", color: "#fff",
          }}><Icon name="trash" size={14}/> Delete</button>
          <button onClick={clearSel} style={ghostLink}>Clear</button>
        </div>
      ) : (
        <div style={{ padding: "10px 16px", borderBottom: "1px solid var(--ink-100)", display: "flex", alignItems: "center", gap: 12 }}>
          <Check on={false} onClick={toggleAll} dim/>
          <SectionLabel>In your memory</SectionLabel>
          <div style={{ flex: 1 }}/>
          <span style={{ fontSize: 11.5, color: "var(--fg-2)", fontVariantNumeric: "tabular-nums", whiteSpace: "nowrap" }}>{items.length} sources · {chunks} chunks</span>
        </div>
      )}

      {/* Controls: search + group-by */}
      <div style={{ padding: "10px 16px", borderBottom: "1px solid var(--ink-50)", display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap" }}>
        <div style={{ position: "relative", flex: 1, minWidth: 160 }}>
          <span style={{ position: "absolute", left: 9, top: "50%", transform: "translateY(-50%)", color: "var(--fg-3)", display: "flex" }}><Icon name="search" size={14}/></span>
          <input value={query} onChange={e => setQuery(e.target.value)} placeholder="Search memory…" style={{
            width: "100%", boxSizing: "border-box", padding: "7px 10px 7px 30px", fontSize: 13, fontFamily: "var(--font-sans)",
            color: "var(--fg-1)", borderRadius: 7, border: "1px solid var(--ink-100)", background: "var(--paper)", outline: "none",
          }}/>
        </div>
        <div style={{ display: "flex", alignItems: "center", gap: 7 }}>
          <span style={{ fontSize: 11.5, color: "var(--fg-2)", whiteSpace: "nowrap" }}>Group by</span>
          <div style={{ display: "flex", gap: 2, padding: 3, borderRadius: 8, background: "var(--ink-50)" }}>
            {segBtn("none", "All")}
            {segBtn("type", "Type")}
            {segBtn("collection", "Collection")}
          </div>
        </div>
        <button onClick={startCreate} style={{
          display: "inline-flex", alignItems: "center", gap: 5, padding: "6px 10px", fontSize: 12.5, fontWeight: 500,
          fontFamily: "var(--font-sans)", cursor: "pointer", borderRadius: 7, whiteSpace: "nowrap",
          border: "1px solid var(--ink-100)", background: "#fff", color: "var(--fg-1)",
        }}><Icon name="plus" size={13}/> New collection</button>
      </div>

      {/* Inline collection creator */}
      {creating && (
        <div className="cad-fade" style={{ padding: "9px 16px", borderBottom: "1px solid var(--ink-50)", display: "flex", alignItems: "center", gap: 8, background: "var(--paper)" }}>
          <Icon name="folder" size={15} style={{ color: "var(--fg-2)" }}/>
          <input autoFocus value={draft} onChange={e => setDraft(e.target.value)} placeholder="Collection name…"
            onKeyDown={e => { if (e.key === "Enter") commitCreate(); if (e.key === "Escape") { setCreating(false); setDraft(""); } }}
            style={{ flex: 1, padding: "6px 9px", fontSize: 13, fontFamily: "var(--font-sans)", color: "var(--fg-1)",
              borderRadius: 6, border: "1px solid var(--ink-100)", background: "#fff", outline: "none" }}/>
          <Button variant="primary" size="sm" onClick={commitCreate}>Create</Button>
          <button onClick={() => { setCreating(false); setDraft(""); }} style={ghostLink}>Cancel</button>
        </div>
      )}

      {/* List */}
      {visible.length === 0 ? (
        <div style={{ padding: "34px 16px", textAlign: "center", color: "var(--fg-2)" }}>
          <div style={{ fontSize: 13.5, fontWeight: 500, color: "var(--fg-1)" }}>{items.length === 0 ? "Your memory is empty" : "Nothing matches that search"}</div>
          <div style={{ fontSize: 12, marginTop: 4 }}>{items.length === 0 ? "Drop files above to start building it back up." : "Try a different term."}</div>
        </div>
      ) : (
        <div>
          {groups.map((g, gi) => (
            <div key={g.label || "all"}>
              {g.label && (
                editing === g.label ? (
                  <div style={{ display: "flex", alignItems: "center", gap: 8, padding: "8px 16px", background: "var(--paper)", borderBottom: "1px solid var(--ink-50)", borderTop: gi === 0 ? "none" : "1px solid var(--ink-50)" }}>
                    <input autoFocus value={draft} onChange={e => setDraft(e.target.value)}
                      onKeyDown={e => { if (e.key === "Enter") commitRename(); if (e.key === "Escape") { setEditing(null); setDraft(""); } }}
                      style={{ flex: 1, padding: "5px 8px", fontSize: 12.5, fontFamily: "var(--font-sans)", color: "var(--fg-1)",
                        borderRadius: 6, border: "1px solid var(--ink-100)", background: "#fff", outline: "none" }}/>
                    <button onClick={commitRename} style={{ ...ghostLink, color: "var(--cardinal)", fontWeight: 600 }}>Save</button>
                    <button onClick={() => { setEditing(null); setDraft(""); }} style={ghostLink}>Cancel</button>
                  </div>
                ) : (
                  <GroupHeader g={g} first={gi === 0}
                    onRename={() => startRename(g.label)} onDelete={() => deleteCollection(g.label)}/>
                )
              )}
              {g.rows.map((m, i) => (
                <MemRow key={m.id} m={m} checked={selected.has(m.id)}
                  onToggle={() => toggle(m.id)} onDelete={() => removeIds([m.id])}
                  last={gi === groups.length - 1 && i === g.rows.length - 1}/>
              ))}
              {g.editable && g.rows.length === 0 && (
                <div style={{ padding: "10px 16px 12px 16px", fontSize: 12, color: "var(--fg-3)", fontStyle: "italic", borderBottom: "1px solid var(--ink-50)" }}>Empty — move items here to fill it.</div>
              )}
            </div>
          ))}
        </div>
      )}

      <div style={{ padding: "11px 16px", borderTop: "1px solid var(--ink-100)", display: "flex", alignItems: "center", gap: 8, fontSize: 12, color: "var(--fg-2)" }}>
        <span className="cad-pulse-dot"/> Offerroom is building a graph of stories and outcomes from these. Updates as you add more.
      </div>
    </Panel>
  );
}

// Group header — editable (rename/delete) for collections, static otherwise.
const GroupHeader = ({ g, first, onRename, onDelete }) => {
  const [hover, setHover] = useMem(false);
  return (
    <div onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
      style={{ display: "flex", alignItems: "center", gap: 8, padding: "8px 16px 7px", background: "var(--paper)",
        borderBottom: "1px solid var(--ink-50)", borderTop: first ? "none" : "1px solid var(--ink-50)" }}>
      <span style={{ fontSize: 10.5, fontWeight: 600, letterSpacing: "0.06em", textTransform: "uppercase", color: "var(--fg-2)" }}>{g.label}</span>
      <span style={{ fontSize: 10.5, color: "var(--fg-3)", fontVariantNumeric: "tabular-nums" }}>{g.rows.length}</span>
      <div style={{ flex: 1 }}/>
      {g.editable && hover && (
        <div className="cad-fade" style={{ display: "flex", alignItems: "center", gap: 4 }}>
          <button onClick={onRename} style={{ ...ghostLink, fontSize: 11.5, padding: "2px 6px" }}>Rename</button>
          <button onClick={onDelete} title="Delete collection" style={{
            display: "grid", placeItems: "center", width: 24, height: 24, borderRadius: 5, cursor: "pointer",
            border: "1px solid var(--ink-100)", background: "#fff", color: "var(--cardinal)",
          }}><Icon name="trash" size={13}/></button>
        </div>
      )}
    </div>
  );
};

// Square checkbox matching the kit.
const Check = ({ on, onClick, dim }) => (
  <button onClick={onClick} aria-pressed={on} style={{
    width: 18, height: 18, borderRadius: 5, flexShrink: 0, cursor: "pointer", padding: 0,
    display: "grid", placeItems: "center", transition: "all 120ms",
    background: on ? "var(--cardinal)" : "#fff",
    border: on ? "1px solid var(--cardinal)" : "1.5px solid var(--ink-300)",
    color: "#fff", opacity: dim && !on ? 0.7 : 1,
  }}>{on && <Icon name="check" size={12}/>}</button>
);

const MemRow = ({ m, last, checked, onToggle, onDelete }) => {
  const t = TONES[m.tone] || TONES.slate;
  const [hover, setHover] = useMem(false);
  return (
    <div onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
      style={{ display: "flex", alignItems: "center", gap: 12, padding: "11px 16px",
        borderBottom: last ? "none" : "1px solid var(--ink-50)",
        background: checked ? "var(--cardinal-tint, rgba(140,21,21,0.04))" : hover ? "var(--paper)" : "transparent", transition: "background 120ms" }}>
      <Check on={checked} onClick={onToggle}/>
      <span style={{ width: 34, height: 34, borderRadius: 8, background: t.tint, color: t.color, display: "grid", placeItems: "center", flexShrink: 0 }}>
        <Icon name={m.icon} size={17}/>
      </span>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 13.5, fontWeight: 500, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{m.name}</div>
        <div style={{ fontSize: 11.5, color: "var(--fg-2)" }}>{m.meta}</div>
      </div>
      {hover ? (
        <button onClick={onDelete} title="Delete from memory" style={{
          display: "grid", placeItems: "center", width: 28, height: 28, borderRadius: 6, flexShrink: 0,
          cursor: "pointer", border: "1px solid var(--ink-100)", background: "#fff", color: "var(--cardinal)", transition: "all 120ms",
        }}><Icon name="trash" size={15}/></button>
      ) : (
        <>
          <span style={{ fontSize: 11, color: "var(--fg-2)", fontFamily: "var(--font-mono)", fontVariantNumeric: "tabular-nums", flexShrink: 0 }}>{m.chunks} chunks</span>
          <span style={{ width: 7, height: 7, borderRadius: 999, background: "#5A7150", flexShrink: 0 }} title="Indexed"/>
        </>
      )}
    </div>
  );
};

window.ScrMemory = ScrMemory;
