// JEP — Lock Loop interactive demo

const { useState, useEffect, useRef } = React;

const ORIGINAL_FILES = [
  { name: "journal-2025.md", size: "12 KB", kind: "Markdown" },
  { name: "tax-return-2024.pdf", size: "318 KB", kind: "PDF" },
  { name: "IMG_4401.jpg", size: "2.4 MB", kind: "JPEG" },
  { name: "IMG_4402.jpg", size: "2.1 MB", kind: "JPEG" },
  { name: "savings-plan.numbers", size: "184 KB", kind: "Numbers" },
  { name: "letter-to-mom.docx", size: "44 KB", kind: "Word" },
];

// Deterministic-looking ciphered names
const CIPHERED = [
  "R8UGLHespS4XeJX6sDCGDuZTR",
  "K2nTbxQ91vMZ6yLpHfWcAdRsT",
  "P7vYnL3kBxQs8eMtRfH2cKyAj",
  "M4dXcVbN5pRtY9wQzKfL8jHsE",
  "T6yHnGfBvCxZ2lQpWmRsKdJaY",
  "L9pQwErTyUiOaSdFgHjK3mNbV",
];

const PHASES = [
  { id: "idle", label: "00 / Unlocked", title: "Folder is open and usable.", body: "Files have their original names and contents. JEP is doing nothing until you ask it to lock." },
  { id: "rename-files", label: "01 / Rename files", title: "Filenames become unrecognizable.", body: "Each filename is encoded with a deterministic cipher seeded by your PIN. Same input + same PIN always produces the same output, so it's reversible without a manifest entry per file." },
  { id: "flip-headers", label: "02 / Flip headers", title: "File headers get scrambled.", body: "JEP XORs the first N bytes of each file with a key derived from your PIN. Enough to break previews, thumbnails, and file-type detection. The number of bytes depends on the concealment level you chose." },
  { id: "rename-root", label: "03 / Hide the folder", title: "The folder vanishes from Finder.", body: "JEP renames the root with a leading dot and a .noindex suffix. Finder hides dotfiles. Spotlight refuses to index .noindex paths. The folder is still there — it just stops showing up." },
  { id: "locked", label: "04 / Locked", title: "Folder is locked.", body: "From the outside it looks like a hidden temp directory full of junk. From your perspective, you've made one click and it took roughly as long as a rename — because that's mostly what it was." },
];

function Finder({ phase, headlineFolderName }) {
  const showFolder = phase === "idle" || phase === "rename-files" || phase === "flip-headers";
  const folderHidden = phase === "rename-root" || phase === "locked";

  const renameNames = phase !== "idle";
  const flipHeaders = phase === "flip-headers" || phase === "rename-root" || phase === "locked";

  const folderLabel = phase === "idle"
    ? "Personal"
    : phase === "rename-files" || phase === "flip-headers"
      ? "Personal"
      : ".R8UGLHespS4XeJX6.noindex";

  return (
    <div className="finder">
      <div className="finder-chrome">
        <div className="finder-dot"></div>
        <div className="finder-dot"></div>
        <div className="finder-dot"></div>
        <div className="finder-path">
          <span>~ / Documents / </span>
          <span className="crumb-active">{folderHidden ? "Documents" : folderLabel}</span>
        </div>
      </div>

      {!folderHidden ? (
        <div className="finder-list">
          {ORIGINAL_FILES.map((f, i) => (
            <div key={i} className="finder-row">
              <div className={`finder-icon`}>
                {flipHeaders ? "??" : f.kind.slice(0, 2).toUpperCase()}
              </div>
              <div className={`finder-name ${renameNames ? "scrambled" : ""}`}>
                {renameNames ? CIPHERED[i] : f.name}
              </div>
              <div className="finder-meta">{f.size}</div>
              <div className="finder-meta">{flipHeaders ? "—" : f.kind}</div>
            </div>
          ))}
        </div>
      ) : (
        <div className="finder-list">
          <div className="finder-row">
            <div className="finder-icon folder" style={{ opacity: 0.4 }}></div>
            <div className="finder-name" style={{ color: "var(--ink-3)", fontStyle: "italic" }}>
              ( folder hidden — leading dot )
            </div>
            <div className="finder-meta">—</div>
            <div className="finder-meta">—</div>
          </div>
          <div className="finder-empty-note">
            Finder hides dotfiles by default. Spotlight skips <span className="inline-mono">.noindex</span> paths. The folder is still on disk at its original location — it just doesn't appear here.
          </div>
        </div>
      )}
    </div>
  );
}

function Narration({ phase, currentIndex }) {
  const p = PHASES[currentIndex];
  return (
    <div className="narration">
      <div>
        <div className="narration-step">{p.label}</div>
        <h3>{p.title}</h3>
        <p>{p.body}</p>
      </div>
      {p.id !== "idle" && (
        <dl className="kv">
          <dt>example</dt>
          <dd>
            {p.id === "rename-files" && (<><span className="diff-out">IMG_4401.jpg</span> → <span className="diff-in">K2nTbxQ91vMZ6yLpHfWcAdRsT</span></>)}
            {p.id === "flip-headers" && (<><span className="diff-out">FF D8 FF E0 00 10 4A 46</span> → <span className="diff-in">A3 71 9E 4C 8B 22 D7 1F</span></>)}
            {(p.id === "rename-root" || p.id === "locked") && (<><span className="diff-out">~/Documents/Personal</span> → <span className="diff-in">~/Documents/.R8UGLHespS4XeJX6.noindex</span></>)}
          </dd>
          <dt>cipher</dt>
          <dd>SHA-256(PIN) → XOR → Base64url</dd>
          <dt>reversible</dt>
          <dd>yes — same PIN, same key, self-inverse</dd>
        </dl>
      )}
    </div>
  );
}

function LockLoopDemo() {
  const [idx, setIdx] = useState(0);
  const [auto, setAuto] = useState(false);
  const timer = useRef(null);

  useEffect(() => {
    if (!auto) return;
    timer.current = setInterval(() => {
      setIdx(i => {
        if (i >= PHASES.length - 1) {
          setAuto(false);
          return i;
        }
        return i + 1;
      });
    }, 1600);
    return () => clearInterval(timer.current);
  }, [auto]);

  const phase = PHASES[idx].id;

  return (
    <div className="demo">
      <div className="demo-head">
        <span>jep — lock loop demo · phase {String(idx).padStart(2, "0")} / 04</span>
        <div className="demo-tabs">
          {PHASES.map((p, i) => (
            <button
              key={p.id}
              className={`demo-tab ${i === idx ? "active" : ""}`}
              onClick={() => { setAuto(false); setIdx(i); }}
            >
              {String(i).padStart(2, "0")}
            </button>
          ))}
        </div>
      </div>

      <div className="demo-body">
        <Finder phase={phase} />
        <Narration phase={phase} currentIndex={idx} />
      </div>

      <div className="demo-controls">
        <button className="action-btn ghost" onClick={() => { setAuto(false); setIdx(0); }}>
          ‹ reset
        </button>
        <button
          className="action-btn ghost"
          onClick={() => { setAuto(false); setIdx(i => Math.max(0, i - 1)); }}
          disabled={idx === 0}
        >
          step back
        </button>
        <button
          className="action-btn"
          onClick={() => { setAuto(false); setIdx(i => Math.min(PHASES.length - 1, i + 1)); }}
          disabled={idx === PHASES.length - 1}
        >
          step forward ›
        </button>
        <div className="spacer"></div>
        <button
          className="action-btn ghost"
          onClick={() => { setIdx(0); setAuto(a => !a); }}
        >
          {auto ? "■ stop" : "▶ play full sequence"}
        </button>
      </div>
    </div>
  );
}

window.LockLoopDemo = LockLoopDemo;
