/* portfolio-admin.jsx — slide-in CMS panel
   Operational Intelligence edition */

const { useState, useRef } = React;

// =========================================================
// Reusable form atoms
// =========================================================
const TextField = ({ label, value, onChange, type = "text", hint, ...rest }) => (
  <div className="form-row">
    <label className="lab">{label}</label>
    <input type={type} value={value || ""} onChange={(e) => onChange(e.target.value)} {...rest} />
    {hint && <div className="hint">{hint}</div>}
  </div>
);
const TextArea = ({ label, value, onChange, hint, rows = 3 }) => (
  <div className="form-row">
    <label className="lab">{label}</label>
    <textarea value={value || ""} onChange={(e) => onChange(e.target.value)} rows={rows} />
    {hint && <div className="hint">{hint}</div>}
  </div>
);
// Inline images are stored as base64 in localStorage, so they must stay small
// or they fill the store and break saving. Videos must NEVER be inlined — they
// belong on a host (YouTube/Loom/Vimeo) and we keep only the URL.
const MAX_INLINE_IMAGE_BYTES = 1.5 * 1024 * 1024; // 1.5 MB
const MediaPicker = ({ label, value, onChange, accept = "image/*", hint }) => {
  const ref = useRef();
  const [err, setErr] = useState("");
  const isData = value && value.startsWith("data:");
  const isVideo = value && (value.startsWith("data:video") || /youtu\.?be|vimeo|loom|\.mp4($|\?)/i.test(value));
  const isLink = value && !isData;
  return (
    <div className="form-row">
      <label className="lab">{label}</label>
      <div className={"upload-tile" + (value ? " has-media" : "")} onClick={() => ref.current?.click()}>
        {value
          ? (isVideo
              ? (isData ? <video src={value} muted autoPlay loop playsInline />
                        : <div style={{padding:14, fontSize:12, textAlign:"center"}}><Icon name="globe" size={18} /><div style={{marginTop:6, wordBreak:"break-all"}}>{value}</div></div>)
              : (isLink ? <img src={value} alt="" onError={(e)=>{e.target.style.display="none";}} />
                        : <img src={value} alt="" />))
          : <div><Icon name="image" size={18} /> <div style={{marginTop:8, fontSize:12}}>Click to upload an image (≤1.5&nbsp;MB)</div></div>
        }
      </div>
      <input ref={ref} type="file" accept={accept} style={{display:"none"}}
        onChange={async (e) => {
          const f = e.target.files?.[0];
          if (!f) return;
          setErr("");
          if (f.type.startsWith("video")) {
            setErr("Videos can't be stored in the browser. Host it on YouTube/Loom and paste the link below.");
            e.target.value = ""; return;
          }
          if (f.size > MAX_INLINE_IMAGE_BYTES) {
            setErr(`That image is ${(f.size/1024/1024).toFixed(1)} MB — too big to store. Compress it (e.g. squoosh.app) to under 1.5 MB, or paste a link below.`);
            e.target.value = ""; return;
          }
          const url = await fileToDataURL(f);
          onChange(url);
        }} />
      <input
        type="url"
        placeholder="…or paste an image/video link (https://)"
        value={isLink ? value : ""}
        onChange={(e) => { setErr(""); onChange(e.target.value); }}
        style={{ marginTop: 6 }}
      />
      {hint && <div className="hint">{hint}</div>}
      {err && <div className="hint" style={{color:"#be123c"}}>{err}</div>}
      {value && <button className="btn btn-sm btn-ghost" style={{marginTop:6}} onClick={() => { setErr(""); onChange(""); }}><Icon name="trash" size={12}/> Remove</button>}
    </div>
  );
};

const ICONS = ["compass","bolt","code","chart","spark","layers","shield","blueprint","database","stack","globe","check"];

// =========================================================
// HERO
// =========================================================
const HeroEditor = ({ data, update }) => {
  const h = data.hero;
  const set = (k, v) => update({ ...data, hero: { ...h, [k]: v } });
  const setStat = (i, k, v) => set("stats", h.stats.map((s, j) => j === i ? { ...s, [k]: v } : s));
  return (
    <>
      <MediaPicker label="Profile photo (square works best)" value={h.avatar} onChange={(v) => set("avatar", v)} accept="image/*" />
      <TextField label="Name" value={h.name} onChange={(v) => set("name", v)} />
      <TextField label="Kicker" value={h.kicker} onChange={(v) => set("kicker", v)} hint="The small line above the headline." />
      <TextField label="Subtitle (the role line)" value={h.subtitle} onChange={(v) => set("subtitle", v)} />
      <TextArea label="Intro paragraph" value={h.intro} onChange={(v) => set("intro", v)} rows={3} />
      <div className="form-row">
        <label className="lab">Hero stats</label>
        {h.stats.map((s, i) => (
          <div key={i} className="form-grid-2" style={{marginBottom:8}}>
            <input value={s.num} placeholder="Number" onChange={(e) => setStat(i, "num", e.target.value)} />
            <input value={s.lab} placeholder="Label" onChange={(e) => setStat(i, "lab", e.target.value)} />
          </div>
        ))}
      </div>
    </>
  );
};

// =========================================================
// CAPABILITIES (Signature Venn + 3 circle-tag groups)
// =========================================================
const CapabilitiesEditor = ({ data, update }) => {
  const c = data.capabilities;
  const set = (k, v) => update({ ...data, capabilities: { ...c, [k]: v } });
  const setVenn = (k, v) => set("venn", { ...c.venn, [k]: v });
  const setCircle = (k, sub, v) => setVenn(k, { ...c.venn[k], [sub]: v });
  const setCenter = (sub, v) => setVenn("center", { ...c.venn.center, [sub]: v });
  const circles = [
    { k: "left",   lab: "Top circle" },
    { k: "right",  lab: "Bottom-left circle" },
    { k: "bottom", lab: "Bottom-right circle" },
  ];
  return (
    <>
      <TextField label="Title" value={c.title} onChange={(v) => set("title", v)} />
      <TextArea label="Lead paragraph" value={c.lead} onChange={(v) => set("lead", v)} rows={3} />

      <label className="lab" style={{display:"block", marginTop:6, marginBottom:8}}>Centre pill (synthesis point)</label>
      <div className="admin-item-card">
        <div className="form-grid-2">
          <div className="form-row" style={{margin:0}}>
            <label className="lab">Title</label>
            <input value={c.venn.center?.title || ""} onChange={(e) => setCenter("title", e.target.value)} />
          </div>
          <div className="form-row" style={{margin:0}}>
            <label className="lab">Subtitle (small)</label>
            <input value={c.venn.center?.sub || ""} onChange={(e) => setCenter("sub", e.target.value)} />
          </div>
        </div>
      </div>

      <label className="lab" style={{display:"block", marginTop:14, marginBottom:8}}>Three discipline circles</label>
      {circles.map(({ k, lab }) => {
        const circ = c.venn[k] || {};
        return (
          <div className="admin-item-card" key={k}>
            <div className="admin-item-head">
              <div className="ttl">{lab} · <span style={{color: circ.color || "var(--accent)"}}>{circ.title}</span></div>
            </div>
            <div className="form-grid-3">
              <div className="form-row" style={{margin:0}}>
                <label className="lab">Title</label>
                <input value={circ.title || ""} onChange={(e) => setCircle(k, "title", e.target.value)} />
              </div>
              <div className="form-row" style={{margin:0}}>
                <label className="lab">Icon</label>
                <select value={circ.icon || "spark"} onChange={(e) => setCircle(k, "icon", e.target.value)}>
                  {ICONS.map(o => <option key={o}>{o}</option>)}
                </select>
              </div>
              <div className="form-row" style={{margin:0}}>
                <label className="lab">Color (hex)</label>
                <input value={circ.color || ""} onChange={(e) => setCircle(k, "color", e.target.value)} placeholder="#1e3a8a" />
              </div>
            </div>
            <div className="form-row" style={{marginTop:10, marginBottom:0}}>
              <label className="lab">Micro-tags (comma-separated)</label>
              <input value={(circ.tags || []).join(", ")} onChange={(e) => setCircle(k, "tags", e.target.value.split(",").map(t => t.trim()).filter(Boolean))} />
            </div>
          </div>
        );
      })}
    </>
  );
};

// =========================================================
// PROCESS (How I Build Systems — 6 steps)
// =========================================================
const ProcessEditor = ({ data, update }) => {
  const p = data.process || { title: "", lead: "", steps: [] };
  const set = (k, v) => update({ ...data, process: { ...p, [k]: v } });
  const setStep = (i, k, v) => set("steps", p.steps.map((s, j) => j === i ? { ...s, [k]: v } : s));
  const addStep = () => set("steps", [...p.steps, { icon: "spark", title: "New Step", body: "" }]);
  const removeStep = (i) => set("steps", p.steps.filter((_, j) => j !== i));
  return (
    <>
      <TextField label="Title" value={p.title} onChange={(v) => set("title", v)} />
      <TextArea label="Lead paragraph" value={p.lead} onChange={(v) => set("lead", v)} rows={3} />
      <label className="lab" style={{display:"block", marginBottom:8}}>Build steps (Business Problem → Scalable Execution)</label>
      {p.steps.map((s, i) => (
        <div className="admin-item-card" key={i}>
          <div className="admin-item-head">
            <div className="ttl">{i+1}. {s.title}</div>
            <button className="btn btn-sm btn-ghost" onClick={() => removeStep(i)}><Icon name="trash" size={12} /></button>
          </div>
          <div className="form-grid-2">
            <div className="form-row" style={{margin:0}}>
              <label className="lab">Icon</label>
              <select value={s.icon} onChange={(e) => setStep(i, "icon", e.target.value)}>
                {ICONS.map(o => <option key={o}>{o}</option>)}
              </select>
            </div>
            <div className="form-row" style={{margin:0}}>
              <label className="lab">Title</label>
              <input value={s.title} onChange={(e) => setStep(i, "title", e.target.value)} />
            </div>
          </div>
          <div className="form-row" style={{marginTop:10, marginBottom:0}}>
            <label className="lab">Body</label>
            <textarea rows={2} value={s.body} onChange={(e) => setStep(i, "body", e.target.value)} />
          </div>
        </div>
      ))}
      <button className="row-add" onClick={addStep}><Icon name="plus" size={14} /> Add step</button>
    </>
  );
};

// =========================================================
// PRINCIPLES (7 engineering principles)
// =========================================================
const PrinciplesEditor = ({ data, update }) => {
  const p = data.principles || { title: "", lead: "", items: [] };
  const set = (k, v) => update({ ...data, principles: { ...p, [k]: v } });
  const setItem = (i, k, v) => set("items", p.items.map((x, j) => j === i ? { ...x, [k]: v } : x));
  const addItem = () => set("items", [...p.items, { icon: "spark", title: "New Principle", body: "" }]);
  const removeItem = (i) => set("items", p.items.filter((_, j) => j !== i));
  return (
    <>
      <TextField label="Title" value={p.title} onChange={(v) => set("title", v)} />
      <TextArea label="Lead paragraph" value={p.lead} onChange={(v) => set("lead", v)} rows={3} />
      <label className="lab" style={{display:"block", marginBottom:8}}>Principles</label>
      {p.items.map((it, i) => (
        <div className="admin-item-card" key={i}>
          <div className="admin-item-head">
            <div className="ttl">{it.title || `Principle ${i+1}`}</div>
            <button className="btn btn-sm btn-ghost" onClick={() => removeItem(i)}><Icon name="trash" size={12} /></button>
          </div>
          <div className="form-grid-2">
            <div className="form-row" style={{margin:0}}>
              <label className="lab">Icon (diagram)</label>
              <select value={it.icon} onChange={(e) => setItem(i, "icon", e.target.value)}>
                {ICONS.map(o => <option key={o}>{o}</option>)}
              </select>
            </div>
            <div className="form-row" style={{margin:0}}>
              <label className="lab">Title</label>
              <input value={it.title} onChange={(e) => setItem(i, "title", e.target.value)} />
            </div>
          </div>
          <div className="form-row" style={{marginTop:10, marginBottom:0}}>
            <label className="lab">Body</label>
            <textarea rows={2} value={it.body} onChange={(e) => setItem(i, "body", e.target.value)} />
          </div>
        </div>
      ))}
      <button className="row-add" onClick={addItem}><Icon name="plus" size={14} /> Add principle</button>
    </>
  );
};

// =========================================================
// FRAMEWORKS
// =========================================================
const FrameworksEditor = ({ data, update }) => {
  const f = data.frameworks || { title: "", lead: "", items: [] };
  const set = (k, v) => update({ ...data, frameworks: { ...f, [k]: v } });
  const setItem = (i, k, v) => set("items", f.items.map((x, j) => j === i ? { ...x, [k]: v } : x));
  const addItem = () => set("items", [...f.items, { id: uid("fw"), name: "New Framework", icon: "blueprint", summary: "", pillars: [], linkedTo: "", tags: [] }]);
  const removeItem = (i) => set("items", f.items.filter((_, j) => j !== i));
  return (
    <>
      <TextField label="Title" value={f.title} onChange={(v) => set("title", v)} />
      <TextArea label="Lead paragraph" value={f.lead} onChange={(v) => set("lead", v)} rows={3} />
      <label className="lab" style={{display:"block", marginBottom:8}}>Frameworks</label>
      {f.items.map((it, i) => (
        <details className="admin-item-card" key={it.id} open={i === 0}>
          <summary style={{display:"flex", alignItems:"center", justifyContent:"space-between", cursor:"pointer", listStyle:"none"}}>
            <div className="ttl">{it.name}</div>
            <button className="btn btn-sm btn-ghost" onClick={(e) => { e.preventDefault(); removeItem(i); }}><Icon name="trash" size={12} /></button>
          </summary>
          <div style={{marginTop:14}}>
            <div className="form-grid-2">
              <div className="form-row" style={{margin:0}}>
                <label className="lab">Name</label>
                <input value={it.name} onChange={(e) => setItem(i, "name", e.target.value)} />
              </div>
              <div className="form-row" style={{margin:0}}>
                <label className="lab">Icon</label>
                <select value={it.icon} onChange={(e) => setItem(i, "icon", e.target.value)}>
                  {ICONS.map(o => <option key={o}>{o}</option>)}
                </select>
              </div>
            </div>
            <TextArea label="Summary" value={it.summary} onChange={(v) => setItem(i, "summary", v)} rows={2} />
            <div className="form-row">
              <label className="lab">Pillars (comma-separated)</label>
              <input value={(it.pillars || []).join(", ")} onChange={(e) => setItem(i, "pillars", e.target.value.split(",").map(t => t.trim()).filter(Boolean))} />
            </div>
            <TextField label="Linked to (projects)" value={it.linkedTo} onChange={(v) => setItem(i, "linkedTo", v)} hint="e.g. AP Invoice · TSP Logistics" />
            <MediaPicker label="Framework poster image (optional)" value={it.poster} onChange={(v) => setItem(i, "poster", v)} accept="image/*" />
            <TextField label="Poster caption" value={it.posterCaption} onChange={(v) => setItem(i, "posterCaption", v)} />
            <div className="form-row" style={{marginBottom:0}}>
              <label className="lab">Tags (comma-separated)</label>
              <input value={(it.tags || []).join(", ")} onChange={(e) => setItem(i, "tags", e.target.value.split(",").map(t => t.trim()).filter(Boolean))} />
            </div>
          </div>
        </details>
      ))}
      <button className="row-add" onClick={addItem}><Icon name="plus" size={14} /> Add framework</button>
    </>
  );
};

// =========================================================
// LEARNING PORTAL (episodes)
// =========================================================
const LearningEditor = ({ data, update }) => {
  const l = data.learning || { title: "", lead: "", episodes: [] };
  const set = (k, v) => update({ ...data, learning: { ...l, [k]: v } });
  const setEp = (i, k, v) => set("episodes", l.episodes.map((x, j) => j === i ? { ...x, [k]: v } : x));
  const addEp = () => set("episodes", [...l.episodes, { id: uid("ep"), number: String(l.episodes.length + 1).padStart(2, "0"), title: "New Episode", framework: "", duration: "", summary: "", tags: [], thumb: "" }]);
  const removeEp = (i) => set("episodes", l.episodes.filter((_, j) => j !== i));
  return (
    <>
      <TextField label="Title" value={l.title} onChange={(v) => set("title", v)} />
      <TextArea label="Lead paragraph" value={l.lead} onChange={(v) => set("lead", v)} rows={3} />
      <label className="lab" style={{display:"block", marginBottom:8}}>Episodes</label>
      {l.episodes.map((ep, i) => (
        <details className="admin-item-card" key={ep.id} open={i === 0}>
          <summary style={{display:"flex", alignItems:"center", justifyContent:"space-between", cursor:"pointer", listStyle:"none"}}>
            <div className="ttl">EP · {ep.number} — {ep.title}</div>
            <button className="btn btn-sm btn-ghost" onClick={(e) => { e.preventDefault(); removeEp(i); }}><Icon name="trash" size={12} /></button>
          </summary>
          <div style={{marginTop:14}}>
            <MediaPicker label="Banner / thumbnail" value={ep.thumb} onChange={(v) => setEp(i, "thumb", v)} accept="image/*" />
            <div className="form-grid-3">
              <div className="form-row" style={{margin:0}}>
                <label className="lab">Number</label>
                <input value={ep.number} onChange={(e) => setEp(i, "number", e.target.value)} placeholder="01" />
              </div>
              <div className="form-row" style={{margin:0}}>
                <label className="lab">Duration</label>
                <input value={ep.duration} onChange={(e) => setEp(i, "duration", e.target.value)} placeholder="10 min read" />
              </div>
              <div className="form-row" style={{margin:0}}>
                <label className="lab">Framework</label>
                <input value={ep.framework} onChange={(e) => setEp(i, "framework", e.target.value)} />
              </div>
            </div>
            <TextField label="Title" value={ep.title} onChange={(v) => setEp(i, "title", v)} />
            <TextArea label="Summary" value={ep.summary} onChange={(v) => setEp(i, "summary", v)} rows={3} />
            <div className="form-row" style={{marginBottom:0}}>
              <label className="lab">Tags (comma-separated)</label>
              <input value={(ep.tags || []).join(", ")} onChange={(e) => setEp(i, "tags", e.target.value.split(",").map(t => t.trim()).filter(Boolean))} />
            </div>
          </div>
        </details>
      ))}
      <button className="row-add" onClick={addEp}><Icon name="plus" size={14} /> Add episode</button>
    </>
  );
};

// =========================================================
// DOWNLOAD CENTER
// =========================================================
const DownloadsEditor = ({ data, update }) => {
  const d = data.downloads || { title: "", lead: "", items: [] };
  const set = (k, v) => update({ ...data, downloads: { ...d, [k]: v } });
  const setItem = (i, k, v) => set("items", d.items.map((x, j) => j === i ? { ...x, [k]: v } : x));
  const addItem = () => set("items", [...d.items, { id: uid("dl"), name: "New Resource", type: "PDF", size: "", description: "", tags: [], file: "#" }]);
  const removeItem = (i) => set("items", d.items.filter((_, j) => j !== i));
  const types = ["PDF", "Markdown", "Code", "ZIP", "Doc"];
  return (
    <>
      <TextField label="Title" value={d.title} onChange={(v) => set("title", v)} />
      <TextArea label="Lead paragraph" value={d.lead} onChange={(v) => set("lead", v)} rows={3} />
      <label className="lab" style={{display:"block", marginBottom:8}}>Downloadable resources</label>
      {d.items.map((it, i) => (
        <div className="admin-item-card" key={it.id}>
          <div className="admin-item-head">
            <div className="ttl">{it.name}</div>
            <button className="btn btn-sm btn-ghost" onClick={() => removeItem(i)}><Icon name="trash" size={12} /></button>
          </div>
          <TextField label="Name" value={it.name} onChange={(v) => setItem(i, "name", v)} />
          <div className="form-grid-2">
            <div className="form-row" style={{margin:0}}>
              <label className="lab">Type</label>
              <select value={it.type} onChange={(e) => setItem(i, "type", e.target.value)}>
                {types.map(t => <option key={t}>{t}</option>)}
              </select>
            </div>
            <div className="form-row" style={{margin:0}}>
              <label className="lab">Size</label>
              <input value={it.size} onChange={(e) => setItem(i, "size", e.target.value)} placeholder="1.2 MB" />
            </div>
          </div>
          <TextArea label="Description" value={it.description} onChange={(v) => setItem(i, "description", v)} rows={2} />
          <TextField label="File URL" value={it.file} onChange={(v) => setItem(i, "file", v)} hint="Use a public URL or upload to /assets and paste the path." />
          <div className="form-row" style={{marginBottom:0}}>
            <label className="lab">Tags (comma-separated)</label>
            <input value={(it.tags || []).join(", ")} onChange={(e) => setItem(i, "tags", e.target.value.split(",").map(t => t.trim()).filter(Boolean))} />
          </div>
        </div>
      ))}
      <button className="row-add" onClick={addItem}><Icon name="plus" size={14} /> Add resource</button>
    </>
  );
};

// =========================================================
// JOURNEY (timeline)
// =========================================================
const JourneyEditor = ({ data, update }) => {
  const j = data.journey || { title: "", lead: "", milestones: [] };
  const set = (k, v) => update({ ...data, journey: { ...j, [k]: v } });
  const setMS = (i, k, v) => set("milestones", j.milestones.map((x, idx) => idx === i ? { ...x, [k]: v } : x));
  const addMS = () => set("milestones", [...j.milestones, { year: String(new Date().getFullYear()), title: "New milestone", where: "", summary: "" }]);
  const removeMS = (i) => set("milestones", j.milestones.filter((_, idx) => idx !== i));
  return (
    <>
      <TextField label="Title" value={j.title} onChange={(v) => set("title", v)} />
      <TextArea label="Lead paragraph" value={j.lead} onChange={(v) => set("lead", v)} rows={3} />
      <label className="lab" style={{display:"block", marginBottom:8}}>Milestones</label>
      {j.milestones.map((ms, i) => (
        <div className="admin-item-card" key={i}>
          <div className="admin-item-head">
            <div className="ttl">{ms.year} · {ms.title}</div>
            <button className="btn btn-sm btn-ghost" onClick={() => removeMS(i)}><Icon name="trash" size={12} /></button>
          </div>
          <div className="form-grid-3">
            <div className="form-row" style={{margin:0}}>
              <label className="lab">Year</label>
              <input value={ms.year} onChange={(e) => setMS(i, "year", e.target.value)} />
            </div>
            <div className="form-row" style={{margin:0, gridColumn:"span 2"}}>
              <label className="lab">Title</label>
              <input value={ms.title} onChange={(e) => setMS(i, "title", e.target.value)} />
            </div>
          </div>
          <TextField label="Where" value={ms.where} onChange={(v) => setMS(i, "where", v)} />
          <TextArea label="Summary" value={ms.summary} onChange={(v) => setMS(i, "summary", v)} rows={2} />
        </div>
      ))}
      <button className="row-add" onClick={addMS}><Icon name="plus" size={14} /> Add milestone</button>
    </>
  );
};

// =========================================================
// APPROACH (legacy — kept for backwards-compat with v3 stores)
// =========================================================
const ApproachEditor = ({ data, update }) => {
  const a = data.approach;
  const set = (k, v) => update({ ...data, approach: { ...a, [k]: v } });
  const setItem = (i, k, v) => set("principles", a.principles.map((p, j) => j === i ? { ...p, [k]: v } : p));
  const addItem = () => set("principles", [...a.principles, { icon: "spark", title: "New Principle", body: "Describe…" }]);
  const removeItem = (i) => set("principles", a.principles.filter((_, j) => j !== i));
  return (
    <>
      <TextField label="Title" value={a.title} onChange={(v) => set("title", v)} />
      <TextArea label="Lead paragraph" value={a.lead} onChange={(v) => set("lead", v)} rows={3} />
      <label className="lab" style={{display:"block", marginBottom:8}}>Principles</label>
      {a.principles.map((p, i) => (
        <div className="admin-item-card" key={i}>
          <div className="admin-item-head">
            <div className="ttl">{p.title || `Principle ${i+1}`}</div>
            <button className="btn btn-sm btn-ghost" onClick={() => removeItem(i)}><Icon name="trash" size={12} /></button>
          </div>
          <div className="form-grid-2">
            <div className="form-row" style={{margin:0}}>
              <label className="lab">Icon (diagram)</label>
              <select value={p.icon} onChange={(e) => setItem(i, "icon", e.target.value)}>
                {ICONS.map(o => <option key={o} value={o}>{o}</option>)}
              </select>
            </div>
            <div className="form-row" style={{margin:0}}>
              <label className="lab">Title</label>
              <input value={p.title} onChange={(e) => setItem(i, "title", e.target.value)} />
            </div>
          </div>
          <div className="form-row" style={{marginTop:10, marginBottom:0}}>
            <label className="lab">Body</label>
            <textarea rows={2} value={p.body} onChange={(e) => setItem(i, "body", e.target.value)} />
          </div>
        </div>
      ))}
      <button className="row-add" onClick={addItem}><Icon name="plus" size={14} /> Add principle</button>
    </>
  );
};

// =========================================================
// PROJECTS (with caseStudy)
// =========================================================
const ProjectsEditor = ({ data, update }) => {
  const set = (projects) => update({ ...data, projects });
  const setOne = (i, k, v) => set(data.projects.map((p, j) => j === i ? { ...p, [k]: v } : p));
  const setLink = (i, k, v) => setOne(i, "links", { ...(data.projects[i].links || {}), [k]: v });
  const setMetric = (i, mi, k, v) => setOne(i, "metrics", (data.projects[i].metrics || []).map((m, j) => j === mi ? { ...m, [k]: v } : m));
  const addMetric = (i) => setOne(i, "metrics", [...(data.projects[i].metrics || []), { num: "", lab: "" }]);
  const removeMetric = (i, mi) => setOne(i, "metrics", (data.projects[i].metrics || []).filter((_, j) => j !== mi));
  const setCS = (i, k, v) => setOne(i, "caseStudy", { ...(data.projects[i].caseStudy || {}), [k]: v });
  const add = () => set([{ id: uid("proj"), name: "New Project", category: "Category", status: "Draft", tagline: "", description: "", bullets: [], stack: [], metrics: [], links: {}, thumb: "", featured: false }, ...data.projects]);
  const remove = (i) => set(data.projects.filter((_, j) => j !== i));
  const move = (i, dir) => {
    const arr = [...data.projects];
    const ni = i + dir;
    if (ni < 0 || ni >= arr.length) return;
    [arr[i], arr[ni]] = [arr[ni], arr[i]];
    set(arr);
  };
  return (
    <>
      {data.projects.map((p, i) => (
        <details className="admin-item-card" key={p.id} open={i === 0}>
          <summary style={{display:"flex", alignItems:"center", justifyContent:"space-between", cursor:"pointer", listStyle:"none"}}>
            <div className="ttl">{p.name}</div>
            <div className="admin-item-actions" onClick={(e) => e.stopPropagation()}>
              <button className="btn btn-sm btn-ghost" onClick={() => move(i, -1)} title="Move up"><Icon name="arrow-down" size={12} style={{transform:"rotate(180deg)"}} /></button>
              <button className="btn btn-sm btn-ghost" onClick={() => move(i, 1)} title="Move down"><Icon name="arrow-down" size={12} /></button>
              <button className="btn btn-sm btn-ghost" onClick={() => remove(i)}><Icon name="trash" size={12} /></button>
            </div>
          </summary>
          <div style={{marginTop:14}}>
            <MediaPicker label="Thumbnail / video" value={p.thumb} onChange={(v) => setOne(i, "thumb", v)} />
            <div className="form-grid-2">
              <div className="form-row" style={{margin:0}}><label className="lab">Name</label><input value={p.name} onChange={(e) => setOne(i, "name", e.target.value)} /></div>
              <div className="form-row" style={{margin:0}}><label className="lab">Category</label><input value={p.category} onChange={(e) => setOne(i, "category", e.target.value)} /></div>
            </div>
            <div className="form-grid-2" style={{marginTop:10}}>
              <div className="form-row" style={{margin:0}}><label className="lab">Status</label><input value={p.status} onChange={(e) => setOne(i, "status", e.target.value)} placeholder="Live / In Build / Draft" /></div>
              <div className="form-row" style={{margin:0}}><label className="lab">Featured</label>
                <select value={p.featured ? "yes" : "no"} onChange={(e) => setOne(i, "featured", e.target.value === "yes")}>
                  <option value="no">No</option><option value="yes">Yes</option>
                </select>
              </div>
            </div>
            <div className="form-row"><label className="lab">Tagline</label><input value={p.tagline} onChange={(e) => setOne(i, "tagline", e.target.value)} /></div>
            <TextArea label="Description" value={p.description} onChange={(v) => setOne(i, "description", v)} rows={4} />
            <div className="form-row">
              <label className="lab">Bullets (one per line)</label>
              <textarea rows={4} value={(p.bullets || []).join("\n")} onChange={(e) => setOne(i, "bullets", e.target.value.split("\n").filter(Boolean))} />
            </div>
            <div className="form-row">
              <label className="lab">Stack (comma-separated)</label>
              <input value={(p.stack || []).join(", ")} onChange={(e) => setOne(i, "stack", e.target.value.split(",").map(s => s.trim()).filter(Boolean))} />
            </div>
            <div className="form-row">
              <label className="lab">Metrics</label>
              {(p.metrics || []).map((m, mi) => (
                <div key={mi} className="form-grid-2" style={{marginBottom:6}}>
                  <input value={m.num} placeholder="Number" onChange={(e) => setMetric(i, mi, "num", e.target.value)} />
                  <div style={{display:"flex", gap:6}}>
                    <input value={m.lab} placeholder="Label" onChange={(e) => setMetric(i, mi, "lab", e.target.value)} style={{flex:1}} />
                    <button className="btn btn-sm btn-ghost" onClick={() => removeMetric(i, mi)}><Icon name="trash" size={12} /></button>
                  </div>
                </div>
              ))}
              <button className="row-add" onClick={() => addMetric(i)}><Icon name="plus" size={12} /> Add metric</button>
            </div>
            <div className="form-grid-2">
              <TextField label="GitHub URL" value={p.links?.github} onChange={(v) => setLink(i, "github", v)} />
              <TextField label="Demo URL" value={p.links?.demo} onChange={(v) => setLink(i, "demo", v)} />
            </div>
            <div className="form-grid-2">
              <TextField label="Video URL" value={p.links?.video} onChange={(v) => setLink(i, "video", v)} />
              <TextField label="PDF / Case study URL" value={p.links?.pdf} onChange={(v) => setLink(i, "pdf", v)} />
            </div>

            {/* Case study fields */}
            <details className="admin-item-card" style={{marginTop:14, background:"var(--surface-2)"}}>
              <summary style={{cursor:"pointer", fontWeight:600, fontSize:13, listStyle:"none"}}>
                Case study fields {p.caseStudy ? "· ✓ has detail" : "(empty — fill to make this a case study)"}
              </summary>
              <div style={{marginTop:12}}>
                <TextArea label="Problem"        value={p.caseStudy?.problem}        onChange={(v) => setCS(i, "problem", v)} rows={2} />
                <TextArea label="Workflow"       value={p.caseStudy?.workflow}       onChange={(v) => setCS(i, "workflow", v)} rows={2} />
                <TextArea label="Architecture"   value={p.caseStudy?.architecture}   onChange={(v) => setCS(i, "architecture", v)} rows={3} />
                <TextArea label="Implementation" value={p.caseStudy?.implementation} onChange={(v) => setCS(i, "implementation", v)} rows={3} />
                <div className="form-row">
                  <label className="lab">Impact metrics (num · label, one per line)</label>
                  <textarea rows={3}
                    value={(p.caseStudy?.impact || []).map(m => `${m.num} · ${m.lab}`).join("\n")}
                    onChange={(e) => setCS(i, "impact", e.target.value.split("\n").filter(Boolean).map(s => {
                      const [num, ...rest] = s.split("·");
                      return { num: (num || "").trim(), lab: rest.join("·").trim() };
                    }))}
                  />
                </div>
                <div className="form-row">
                  <label className="lab">Lessons (one per line)</label>
                  <textarea rows={3}
                    value={(p.caseStudy?.lessons || []).join("\n")}
                    onChange={(e) => setCS(i, "lessons", e.target.value.split("\n").filter(Boolean))}
                  />
                </div>
              </div>
            </details>
          </div>
        </details>
      ))}
      <button className="row-add" onClick={add}><Icon name="plus" size={14} /> Add project</button>
    </>
  );
};

// =========================================================
// SHOWCASE (mockups by type)
// =========================================================
const ShowcaseEditor = ({ data, update }) => {
  const set = (showcase) => update({ ...data, showcase });
  const setOne = (i, k, v) => set(data.showcase.map((p, j) => j === i ? { ...p, [k]: v } : p));
  const add = () => set([...data.showcase, { id: uid("show"), type: "windows", title: "New mockup", category: "Category", description: "", lines: [] }]);
  const remove = (i) => set(data.showcase.filter((_, j) => j !== i));
  const types = ["windows", "phone", "dashboard", "workflow"];
  return (
    <>
      <div className="hint" style={{marginBottom:14, color:"var(--text-3)", fontSize:12}}>
        Each card renders a different kind of mockup. For deep customisation,
        use <em>Settings → Export JSON</em>, edit type-specific fields by hand
        (lines / rows / kpis / bars / nodes), then re-import.
      </div>
      {data.showcase.map((p, i) => (
        <div className="admin-item-card" key={p.id}>
          <div className="admin-item-head">
            <div className="ttl">{p.title} · <span style={{color:"var(--accent)"}}>{p.type}</span></div>
            <button className="btn btn-sm btn-ghost" onClick={() => remove(i)}><Icon name="trash" size={12} /></button>
          </div>
          <div className="form-grid-2">
            <div className="form-row" style={{margin:0}}>
              <label className="lab">Type</label>
              <select value={p.type} onChange={(e) => setOne(i, "type", e.target.value)}>
                {types.map(t => <option key={t}>{t}</option>)}
              </select>
            </div>
            <div className="form-row" style={{margin:0}}>
              <label className="lab">Category</label>
              <input value={p.category} onChange={(e) => setOne(i, "category", e.target.value)} />
            </div>
          </div>
          <div className="form-row" style={{marginTop:10}}>
            <label className="lab">Title</label>
            <input value={p.title} onChange={(e) => setOne(i, "title", e.target.value)} />
          </div>
          <TextArea label="Description" value={p.description} onChange={(v) => setOne(i, "description", v)} rows={2} />
          <MediaPicker label="Real screenshot (optional — replaces the CSS mockup)" value={p.image} onChange={(v) => setOne(i, "image", v)} accept="image/*" />
        </div>
      ))}
      <button className="row-add" onClick={add}><Icon name="plus" size={14} /> Add mockup</button>
    </>
  );
};

// =========================================================
// TECH STACK (categorized)
// =========================================================
const StackEditor = ({ data, update }) => {
  const set = (techStack) => update({ ...data, techStack });
  const setOne = (i, k, v) => set(data.techStack.map((s, j) => j === i ? { ...s, [k]: v } : s));
  const add = () => set([...data.techStack, { category: "New Category", icon: "spark", items: [] }]);
  const remove = (i) => set(data.techStack.filter((_, j) => j !== i));
  return (
    <>
      {data.techStack.map((s, i) => (
        <div className="admin-item-card" key={i}>
          <div className="admin-item-head">
            <div className="ttl">{s.category}</div>
            <button className="btn btn-sm btn-ghost" onClick={() => remove(i)}><Icon name="trash" size={12} /></button>
          </div>
          <div className="form-grid-2">
            <div className="form-row" style={{margin:0}}>
              <label className="lab">Category</label>
              <input value={s.category} onChange={(e) => setOne(i, "category", e.target.value)} />
            </div>
            <div className="form-row" style={{margin:0}}>
              <label className="lab">Icon</label>
              <select value={s.icon} onChange={(e) => setOne(i, "icon", e.target.value)}>
                {ICONS.map(o => <option key={o}>{o}</option>)}
              </select>
            </div>
          </div>
          <div className="form-row" style={{marginTop:10, marginBottom:0}}>
            <label className="lab">Items (comma-separated)</label>
            <input value={(s.items || []).join(", ")} onChange={(e) => setOne(i, "items", e.target.value.split(",").map(t => t.trim()).filter(Boolean))} />
          </div>
        </div>
      ))}
      <button className="row-add" onClick={add}><Icon name="plus" size={14} /> Add category</button>
    </>
  );
};

// =========================================================
// RESUME
// =========================================================
const ResumeEditor = ({ data, update }) => {
  const r = data.resume;
  const set = (k, v) => update({ ...data, resume: { ...r, [k]: v } });
  return (
    <>
      <TextField label="Title" value={r.title} onChange={(v) => set("title", v)} />
      <TextArea label="Subline" value={r.subline} onChange={(v) => set("subline", v)} />
      <div className="form-grid-3">
        <TextField label="Version" value={r.version} onChange={(v) => set("version", v)} />
        <TextField label="Updated" value={r.updated} onChange={(v) => set("updated", v)} />
        <TextField label="Pages" value={r.pages} onChange={(v) => set("pages", v)} />
      </div>
      <TextField label="Resume file URL" value={r.file} onChange={(v) => set("file", v)} hint="Filename or URL — defaults to LAKSHMAN_OPTIMIZED_RESUME_2026.html." />
    </>
  );
};

// =========================================================
// CONTACT
// =========================================================
const ContactEditor = ({ data, update }) => {
  const c = data.contact;
  const set = (k, v) => update({ ...data, contact: { ...c, [k]: v } });
  const setCh = (i, k, v) => set("channels", c.channels.map((x, j) => j === i ? { ...x, [k]: v } : x));
  const add = () => set("channels", [...c.channels, { type: "email", label: "Label", value: "", href: "" }]);
  const remove = (i) => set("channels", c.channels.filter((_, j) => j !== i));
  const types = ["email","phone","linkedin","github","location","external"];
  return (
    <>
      <TextField label="Headline" value={c.headline} onChange={(v) => set("headline", v)} />
      <TextArea label="Subline" value={c.subline} onChange={(v) => set("subline", v)} />
      <label className="lab" style={{display:"block", marginTop:6, marginBottom:8}}>Channels</label>
      {c.channels.map((ch, i) => (
        <div className="admin-item-card" key={i}>
          <div className="admin-item-head">
            <div className="ttl">{ch.label}</div>
            <button className="btn btn-sm btn-ghost" onClick={() => remove(i)}><Icon name="trash" size={12} /></button>
          </div>
          <div className="form-grid-2">
            <div className="form-row" style={{margin:0}}>
              <label className="lab">Type</label>
              <select value={ch.type} onChange={(e) => setCh(i, "type", e.target.value)}>
                {types.map(t => <option key={t}>{t}</option>)}
              </select>
            </div>
            <div className="form-row" style={{margin:0}}>
              <label className="lab">Label</label>
              <input value={ch.label} onChange={(e) => setCh(i, "label", e.target.value)} />
            </div>
          </div>
          <div className="form-grid-2" style={{marginTop:10}}>
            <div className="form-row" style={{margin:0}}>
              <label className="lab">Value (shown)</label>
              <input value={ch.value} onChange={(e) => setCh(i, "value", e.target.value)} />
            </div>
            <div className="form-row" style={{margin:0}}>
              <label className="lab">Href</label>
              <input value={ch.href} onChange={(e) => setCh(i, "href", e.target.value)} placeholder="mailto:… / https:// …" />
            </div>
          </div>
        </div>
      ))}
      <button className="row-add" onClick={add}><Icon name="plus" size={14} /> Add channel</button>
    </>
  );
};

// =========================================================
// SETTINGS
// =========================================================
const SettingsEditor = ({ data, update, onReset }) => {
  const s = data.settings;
  const { show } = React.useContext(ToastContext);
  const setVis = (k, v) => update({ ...data, settings: { ...s, showSections: { ...s.showSections, [k]: v } } });
  const sections = ["capabilities","process","principles","products","frameworks","learning","showcase","stack","cases","downloads","social","evolution","journey","resumeEngine","resume","contact"];
  return (
    <>
      <div style={{padding:"14px 16px", marginBottom:18, border:"1px solid var(--accent)", background:"var(--accent-soft)", borderRadius:10}}>
        <label className="lab" style={{display:"block", marginBottom:4}}>Publish to live site</label>
        <p style={{margin:"0 0 10px", color:"var(--text-2)", fontSize:12.5}}>
          Writes your current content to <code>content/content.json</code> — the file the public site reads.
          Running locally it saves to disk; otherwise it downloads the file to commit. <strong>Visitors only ever see published content.</strong>
        </p>
        <button className="btn btn-accent" onClick={async () => {
          let res = await publishContent(data);
          if (res.reason === "auth") {
            const pw = window.prompt("Enter your edit password (the ADMIN_PASSWORD you set in Cloudflare) to publish live:");
            if (!pw) { show("Publish cancelled"); return; }
            setAdminToken(pw);
            res = await publishContent(data);
            if (res.reason === "auth") { setAdminToken(""); show("Wrong password — try again"); return; }
          }
          show(res.mode === "cloud" ? "✓ Published live — your site is updated"
             : res.mode === "disk" ? "Saved to disk (content/content.json)"
             : "content.json downloaded — commit/upload it to deploy");
        }}><Icon name="check" size={13} /> Publish content</button>
      </div>

      <label className="lab" style={{display:"block", marginBottom:8}}>Section visibility</label>
      {sections.map(k => (
        <label key={k} style={{display:"flex", justifyContent:"space-between", alignItems:"center", padding:"10px 12px", background:"var(--bg-2)", border:"1px solid var(--border)", borderRadius:8, marginBottom:6, fontSize:13}}>
          <span style={{textTransform:"capitalize"}}>{k}</span>
          <input type="checkbox" checked={!!s.showSections[k]} onChange={(e) => setVis(k, e.target.checked)} />
        </label>
      ))}
      <div style={{height:18}}></div>
      <button className="btn" onClick={() => {
        const blob = new Blob([JSON.stringify(data, null, 2)], { type: "application/json" });
        const a = document.createElement("a");
        a.href = URL.createObjectURL(blob);
        a.download = "portfolio-data.json";
        a.click();
      }}><Icon name="download" size={13} /> Export data (JSON)</button>
      <button className="btn" style={{marginLeft:8}} onClick={() => {
        const input = document.createElement("input");
        input.type = "file"; input.accept = "application/json";
        input.onchange = async (e) => {
          const f = e.target.files?.[0]; if (!f) return;
          const text = await f.text();
          try { update(JSON.parse(text)); } catch {}
        };
        input.click();
      }}><Icon name="external" size={13} /> Import data</button>
      <div style={{height:14}}></div>
      <label className="lab" style={{display:"block", marginBottom:6}}>Publish ingested projects</label>
      <p style={{margin:"0 0 8px", color:"var(--text-3)", fontSize:12.5}}>
        Import a <code>portfolio-products.json</code> from the ingestion tool. Projects are
        <strong> merged by id</strong> — new ones added, existing ones updated; nothing else is touched.
      </p>
      <button className="btn" onClick={() => {
        const input = document.createElement("input");
        input.type = "file"; input.accept = "application/json";
        input.onchange = async (e) => {
          const f = e.target.files?.[0]; if (!f) return;
          try {
            const parsed = JSON.parse(await f.text());
            const incoming = Array.isArray(parsed) ? parsed
              : Array.isArray(parsed.products) ? parsed.products
              : Array.isArray(parsed.products?.items) ? parsed.products.items
              : [];
            if (!incoming.length) { show("No products found in that file"); return; }
            const items = [...(data.products?.items || [])];
            let added = 0, updated = 0;
            for (const p of incoming) {
              if (!p || !p.id) continue;
              const idx = items.findIndex(x => x.id === p.id);
              if (idx >= 0) { items[idx] = { ...items[idx], ...p }; updated++; }
              else { items.push(p); added++; }
            }
            update({ ...data, products: { ...(data.products || {}), items } });
            show(`Projects merged: ${added} added, ${updated} updated`);
          } catch { show("Could not read that file"); }
        };
        input.click();
      }}><Icon name="plus" size={13} /> Import projects (merge)</button>

      <div style={{height:18}}></div>
      <label className="lab" style={{display:"block", marginBottom:6}}>Backup &amp; recovery</label>
      <p style={{margin:"0 0 8px", color:"var(--text-3)", fontSize:12.5}}>A snapshot bundles your full content + config + theme with a timestamp. Keep one before big edits.</p>
      <button className="btn" onClick={() => {
        const snapshot = { _snapshot: { at: new Date().toISOString(), app: "novaflow", version: 1 }, data };
        downloadJSON(`portfolio-snapshot-${new Date().toISOString().slice(0,10)}.json`, snapshot);
        show("Snapshot downloaded");
      }}><Icon name="download" size={13} /> Export snapshot</button>
      <button className="btn" style={{marginLeft:8}} onClick={() => {
        const input = document.createElement("input");
        input.type = "file"; input.accept = "application/json";
        input.onchange = async (e) => {
          const f = e.target.files?.[0]; if (!f) return;
          try {
            const parsed = JSON.parse(await f.text());
            const restored = parsed && parsed._snapshot && parsed.data ? parsed.data : parsed;
            if (!restored || typeof restored !== "object") { show("Not a valid snapshot"); return; }
            if (!confirm("Restore this snapshot? It replaces your current working content.")) return;
            update(restored); show("Snapshot restored");
          } catch { show("Could not read that snapshot"); }
        };
        input.click();
      }}><Icon name="external" size={13} /> Restore snapshot</button>

      <div style={{height:18}}></div>
      <button className="btn btn-ghost" style={{color:"var(--danger)"}} onClick={onReset}><Icon name="trash" size={13} /> Reset to defaults</button>
    </>
  );
};

// =========================================================
// =========================================================
// V5 JSON Editor — quick scaffold for new sections
// =========================================================
const JSONSectionEditor = ({ data, update, dataKey, label, hint }) => {
  const [text, setText] = React.useState(() => JSON.stringify(data[dataKey] || {}, null, 2));
  const [err, setErr] = React.useState("");
  const onApply = () => {
    try {
      const parsed = JSON.parse(text);
      update({ ...data, [dataKey]: parsed });
      setErr("");
    } catch (e) { setErr(e.message); }
  };
  React.useEffect(() => {
    setText(JSON.stringify(data[dataKey] || {}, null, 2));
  }, [dataKey]); // eslint-disable-line
  return (
    <div>
      <h4 style={{margin:"0 0 6px"}}>{label}</h4>
      <p style={{margin:"0 0 14px", color:"var(--text-3)", fontSize:13}}>{hint}</p>
      <textarea
        value={text}
        onChange={(e) => setText(e.target.value)}
        spellCheck={false}
        style={{
          width:"100%", minHeight:480,
          fontFamily:"var(--mono)", fontSize:12, lineHeight:1.5,
          background:"var(--bg-2)", border:"1px solid var(--border)",
          borderRadius:"var(--radius)", padding:"14px 16px"
        }}
      />
      {err && (
        <div style={{padding:"10px 14px", marginTop:10, background:"rgba(239,68,68,0.08)",
                     border:"1px solid rgba(239,68,68,0.2)", borderRadius:8, color:"#be123c", fontSize:12.5, fontFamily:"var(--mono)"}}>
          {err}
        </div>
      )}
      <div style={{marginTop:12, display:"flex", gap:8}}>
        <button className="btn btn-accent btn-sm" onClick={onApply}>
          <Icon name="check" size={13} /> Apply changes
        </button>
        <button className="btn btn-sm" onClick={() => setText(JSON.stringify(data[dataKey] || {}, null, 2))}>
          <Icon name="close" size={13} /> Revert
        </button>
      </div>
    </div>
  );
};

// =========================================================
// PRODUCTS EDITOR (v5 structured)
// =========================================================
const ProductsEditor = ({ data, update }) => {
  const p = data.products || { title: "", lead: "", statuses: {}, items: [] };
  const set = (k, v) => update({ ...data, products: { ...p, [k]: v } });
  const setItem = (i, k, v) => set("items", p.items.map((it, j) => j === i ? { ...it, [k]: v } : it));
  const setLink = (i, k, v) => setItem(i, "links", { ...(p.items[i].links || {}), [k]: v });
  const setMetric = (i, mi, k, v) => setItem(i, "metrics", (p.items[i].metrics || []).map((m, j) => j === mi ? { ...m, [k]: v } : m));
  const addMetric = (i) => setItem(i, "metrics", [...(p.items[i].metrics || []), { num: "", lab: "" }]);
  const removeMetric = (i, mi) => setItem(i, "metrics", (p.items[i].metrics || []).filter((_, j) => j !== mi));
  const setRoad = (i, ri, k, v) => setItem(i, "roadmap", (p.items[i].roadmap || []).map((r, j) => j === ri ? { ...r, [k]: v } : r));
  const addRoad = (i) => setItem(i, "roadmap", [...(p.items[i].roadmap || []), { phase: "", item: "" }]);
  const removeRoad = (i, ri) => setItem(i, "roadmap", (p.items[i].roadmap || []).filter((_, j) => j !== ri));
  const moveItem = (i, dir) => {
    const arr = [...p.items];
    const j = i + dir;
    if (j < 0 || j >= arr.length) return;
    [arr[i], arr[j]] = [arr[j], arr[i]];
    set("items", arr);
  };
  const removeItem = (i) => set("items", p.items.filter((_, j) => j !== i));
  const addItem = () => set("items", [...p.items, {
    id: uid("prod"),
    name: "New product",
    kicker: "",
    tagline: "",
    status: Object.keys(p.statuses || {})[0] || "active-development",
    domain: "",
    logo: "NP",
    color: "#2563eb",
    screenshotSlot: "",
    hero: "",
    businessProblem: "",
    operationalWorkflow: "",
    engineeringGoals: [],
    stack: [],
    metrics: [],
    roadmap: [],
    links: { github: "", demo: "", pdf: "" },
    frameworks: [],
    featured: false
  }]);

  const statusOptions = Object.entries(p.statuses || {});

  return (
    <>
      <TextField label="Section title" value={p.title} onChange={(v) => set("title", v)} />
      <TextArea label="Lead paragraph" value={p.lead} onChange={(v) => set("lead", v)} rows={3} />

      <details className="prod-statuses-editor" style={{marginTop:18, marginBottom:18, padding:"12px 14px", border:"1px solid var(--border)", borderRadius:10}}>
        <summary style={{cursor:"pointer", fontWeight:600, fontSize:13}}>
          Status definitions <span style={{color:"var(--fg-muted)", fontWeight:400}}>· {statusOptions.length} statuses</span>
        </summary>
        <div style={{marginTop:12}}>
          {statusOptions.map(([key, def]) => (
            <div key={key} className="form-grid-3" style={{alignItems:"end", gap:10, marginBottom:8}}>
              <div className="form-row" style={{margin:0}}>
                <label className="lab">Key</label>
                <input value={key} disabled style={{opacity:0.6}} />
              </div>
              <div className="form-row" style={{margin:0}}>
                <label className="lab">Label</label>
                <input value={def.label} onChange={(e) => set("statuses", { ...p.statuses, [key]: { ...def, label: e.target.value } })} />
              </div>
              <div className="form-row" style={{margin:0}}>
                <label className="lab">Dot color</label>
                <input type="color" value={def.dot} onChange={(e) => set("statuses", { ...p.statuses, [key]: { ...def, dot: e.target.value } })} />
              </div>
            </div>
          ))}
        </div>
      </details>

      <label className="lab" style={{display:"block", marginBottom:8}}>Products ({p.items.length})</label>
      {p.items.map((it, i) => (
        <details key={it.id || i} className="admin-item" style={{marginBottom:10}}>
          <summary style={{display:"flex", alignItems:"center", justifyContent:"space-between", cursor:"pointer", listStyle:"none", padding:"4px 0"}}><span style={{display:"inline-flex", alignItems:"center", gap:8}}>
              <span className="ec-logo-mini" style={{width:24, height:24, borderRadius:6, background: it.color || "#2563eb", color:"white", fontWeight:700, fontSize:10, display:"inline-flex", alignItems:"center", justifyContent:"center"}}>{it.logo || "?"}</span>
              <strong>{it.name || "Untitled product"}</strong>
              <span style={{color:"var(--fg-muted)", fontSize:11}}>· {p.statuses?.[it.status]?.label || it.status}</span>
            </span>
            <div className="ec-row-actions" style={{display:"inline-flex", gap:4}}>
              <button className="btn btn-sm btn-ghost" onClick={(e) => { e.preventDefault(); moveItem(i, -1); }} title="Move up"><Icon name="arrow-down" size={11} style={{transform:"rotate(180deg)"}} /></button>
              <button className="btn btn-sm btn-ghost" onClick={(e) => { e.preventDefault(); moveItem(i, 1); }} title="Move down"><Icon name="arrow-down" size={11} /></button>
              <button className="btn btn-sm btn-ghost" onClick={(e) => { e.preventDefault(); if (confirm(`Remove ${it.name}?`)) removeItem(i); }} title="Remove"><Icon name="trash" size={11} /></button>
            </div>
          </summary>
          <div style={{marginTop:14}}>
            <div className="form-grid-2">
              <div className="form-row" style={{margin:0}}>
                <label className="lab">Name</label>
                <input value={it.name || ""} onChange={(e) => setItem(i, "name", e.target.value)} />
              </div>
              <div className="form-row" style={{margin:0}}>
                <label className="lab">Logo (2–3 chars)</label>
                <input value={it.logo || ""} maxLength="3" onChange={(e) => setItem(i, "logo", e.target.value)} />
              </div>
            </div>
            <div className="form-grid-3">
              <div className="form-row" style={{margin:0}}>
                <label className="lab">Status</label>
                <select value={it.status || ""} onChange={(e) => setItem(i, "status", e.target.value)}>
                  {statusOptions.map(([key, def]) => <option key={key} value={key}>{def.label}</option>)}
                </select>
              </div>
              <div className="form-row" style={{margin:0}}>
                <label className="lab">Publish state</label>
                <select value={it.publishStatus || "published"} onChange={(e) => setItem(i, "publishStatus", e.target.value)}>
                  {["draft", "review", "published", "archived"].map(o => <option key={o} value={o}>{o}</option>)}
                </select>
              </div>
              <div className="form-row" style={{margin:0}}>
                <label className="lab">Domain</label>
                <input value={it.domain || ""} onChange={(e) => setItem(i, "domain", e.target.value)} placeholder="Fintech · Mobile" />
              </div>
              <div className="form-row" style={{margin:0}}>
                <label className="lab">Card color</label>
                <input type="color" value={it.color || "#2563eb"} onChange={(e) => setItem(i, "color", e.target.value)} />
              </div>
            </div>
            <TextField label="Kicker (audience tag)" value={it.kicker} onChange={(v) => setItem(i, "kicker", v)} hint="One-line audience badge." />
            <TextArea label="Tagline" value={it.tagline} onChange={(v) => setItem(i, "tagline", v)} rows={2} />
            <TextArea label="Hero blurb" value={it.hero} onChange={(v) => setItem(i, "hero", v)} rows={3} hint="Longer description used in the product modal." />

            <TextArea label="Business problem" value={it.businessProblem} onChange={(v) => setItem(i, "businessProblem", v)} rows={3} />
            <TextArea label="Operational workflow" value={it.operationalWorkflow} onChange={(v) => setItem(i, "operationalWorkflow", v)} rows={3} />

            <div className="form-row">
              <label className="lab">Engineering goals (one per line)</label>
              <textarea rows={4} value={(it.engineeringGoals || []).join("\n")} onChange={(e) => setItem(i, "engineeringGoals", e.target.value.split("\n").filter(Boolean))} />
            </div>
            <div className="form-row">
              <label className="lab">Tech stack (comma-separated)</label>
              <input value={(it.stack || []).join(", ")} onChange={(e) => setItem(i, "stack", e.target.value.split(",").map(t => t.trim()).filter(Boolean))} />
            </div>
            <div className="form-row">
              <label className="lab">Frameworks applied (comma-separated)</label>
              <input value={(it.frameworks || []).join(", ")} onChange={(e) => setItem(i, "frameworks", e.target.value.split(",").map(t => t.trim()).filter(Boolean))} placeholder="e.g. Config-Driven Architecture, AI-Assisted Workflow" />
            </div>

            <div className="form-row">
              <label className="lab" style={{display:"flex", justifyContent:"space-between", alignItems:"center"}}>
                <span>Metrics</span>
                <button className="btn btn-sm btn-ghost" onClick={() => addMetric(i)}><Icon name="plus" size={10} /> Add</button>
              </label>
              {(it.metrics || []).map((m, mi) => (
                <div key={mi} className="form-grid-3" style={{gap:8, marginBottom:6, alignItems:"end"}}>
                  <input placeholder="70%" value={m.num} onChange={(e) => setMetric(i, mi, "num", e.target.value)} />
                  <input placeholder="Touchless processing" value={m.lab} onChange={(e) => setMetric(i, mi, "lab", e.target.value)} />
                  <button className="btn btn-sm btn-ghost" onClick={() => removeMetric(i, mi)}><Icon name="trash" size={11} /></button>
                </div>
              ))}
            </div>

            <div className="form-row">
              <label className="lab" style={{display:"flex", justifyContent:"space-between", alignItems:"center"}}>
                <span>Roadmap</span>
                <button className="btn btn-sm btn-ghost" onClick={() => addRoad(i)}><Icon name="plus" size={10} /> Add phase</button>
              </label>
              {(it.roadmap || []).map((r, ri) => (
                <div key={ri} className="form-grid-3" style={{gap:8, marginBottom:6, alignItems:"end"}}>
                  <input placeholder="Now / Next / Later" value={r.phase} onChange={(e) => setRoad(i, ri, "phase", e.target.value)} />
                  <input placeholder="What ships in this phase" value={r.item} onChange={(e) => setRoad(i, ri, "item", e.target.value)} style={{gridColumn:"span 1"}} />
                  <button className="btn btn-sm btn-ghost" onClick={() => removeRoad(i, ri)}><Icon name="trash" size={11} /></button>
                </div>
              ))}
            </div>

            <div className="form-grid-2">
              <TextField label="GitHub URL" value={it.links?.github} onChange={(v) => setLink(i, "github", v)} />
              <TextField label="Demo URL" value={it.links?.demo} onChange={(v) => setLink(i, "demo", v)} />
            </div>
            <div className="form-grid-2">
              <TextField label="Architecture PDF URL" value={it.links?.pdf} onChange={(v) => setLink(i, "pdf", v)} />
              <TextField label="Screenshot slot ID" value={it.screenshotSlot} onChange={(v) => setItem(i, "screenshotSlot", v)} hint="Stable id for the drag-drop image slot." />
            </div>

            <div className="form-row" style={{marginBottom:0}}>
              <label style={{display:"inline-flex", alignItems:"center", gap:8, fontSize:13}}>
                <input type="checkbox" checked={!!it.featured} onChange={(e) => setItem(i, "featured", e.target.checked)} />
                <span>Featured product (pinned in resume + hero summaries)</span>
              </label>
            </div>
          </div>
        </details>
      ))}
      <button className="btn btn-sm" onClick={addItem}><Icon name="plus" size={11} /> Add product</button>
    </>
  );
};

// =========================================================
// EVOLUTION EDITOR (v5 structured) — 6 phase timeline
// =========================================================
const EvolutionEditor = ({ data, update }) => {
  const e = data.evolution || { title: "", lead: "", phases: [] };
  const set = (k, v) => update({ ...data, evolution: { ...e, [k]: v } });
  const setPh = (i, k, v) => set("phases", e.phases.map((p, j) => j === i ? { ...p, [k]: v } : p));
  const move = (i, dir) => {
    const arr = [...e.phases];
    const j = i + dir;
    if (j < 0 || j >= arr.length) return;
    [arr[i], arr[j]] = [arr[j], arr[i]];
    set("phases", arr);
  };
  const remove = (i) => set("phases", e.phases.filter((_, j) => j !== i));
  const add = () => set("phases", [...e.phases, { id: uid("ph"), label: "New phase", years: "", icon: "blueprint", summary: "", exemplars: "" }]);

  return (
    <>
      <TextField label="Section title" value={e.title} onChange={(v) => set("title", v)} />
      <TextArea label="Lead paragraph" value={e.lead} onChange={(v) => set("lead", v)} rows={3} />
      <label className="lab" style={{display:"block", marginBottom:8}}>Phases ({e.phases.length})</label>
      {e.phases.map((ph, i) => (
        <details key={ph.id || i} className="admin-item" style={{marginBottom:10}}>
          <summary style={{display:"flex", alignItems:"center", justifyContent:"space-between", cursor:"pointer", listStyle:"none", padding:"4px 0"}}><span><strong>0{i+1} · {ph.label}</strong> <span style={{color:"var(--fg-muted)", fontSize:11}}>· {ph.years}</span></span>
            <div className="ec-row-actions" style={{display:"inline-flex", gap:4}}>
              <button className="btn btn-sm btn-ghost" onClick={(e) => { e.preventDefault(); move(i, -1); }}><Icon name="arrow-down" size={11} style={{transform:"rotate(180deg)"}} /></button>
              <button className="btn btn-sm btn-ghost" onClick={(e) => { e.preventDefault(); move(i, 1); }}><Icon name="arrow-down" size={11} /></button>
              <button className="btn btn-sm btn-ghost" onClick={(e) => { e.preventDefault(); if (confirm(`Remove ${ph.label}?`)) remove(i); }}><Icon name="trash" size={11} /></button>
            </div>
          </summary>
          <div style={{marginTop:14}}>
            <div className="form-grid-3">
              <div className="form-row" style={{margin:0}}>
                <label className="lab">Label</label>
                <input value={ph.label} onChange={(ev) => setPh(i, "label", ev.target.value)} />
              </div>
              <div className="form-row" style={{margin:0}}>
                <label className="lab">Years</label>
                <input value={ph.years} onChange={(ev) => setPh(i, "years", ev.target.value)} placeholder="2018 – 2020" />
              </div>
              <div className="form-row" style={{margin:0}}>
                <label className="lab">Icon</label>
                <input value={ph.icon} onChange={(ev) => setPh(i, "icon", ev.target.value)} placeholder="blueprint, bolt, spark…" />
              </div>
            </div>
            <TextArea label="Summary" value={ph.summary} onChange={(v) => setPh(i, "summary", v)} rows={3} />
            <TextArea label="Exemplar work" value={ph.exemplars} onChange={(v) => setPh(i, "exemplars", v)} rows={2} hint="The standout work that defined this phase." />
          </div>
        </details>
      ))}
      <button className="btn btn-sm" onClick={add}><Icon name="plus" size={11} /> Add phase</button>
    </>
  );
};

// =========================================================
// SOCIAL EDITOR (v5 structured) — shareable OG cards
// =========================================================
const SocialEditor = ({ data, update }) => {
  const s = data.social || { title: "", lead: "", cards: [] };
  const set = (k, v) => update({ ...data, social: { ...s, [k]: v } });
  const setCard = (i, k, v) => set("cards", s.cards.map((c, j) => j === i ? { ...c, [k]: v } : c));
  const move = (i, dir) => {
    const arr = [...s.cards];
    const j = i + dir;
    if (j < 0 || j >= arr.length) return;
    [arr[i], arr[j]] = [arr[j], arr[i]];
    set("cards", arr);
  };
  const remove = (i) => set("cards", s.cards.filter((_, j) => j !== i));
  const add = () => set("cards", [...s.cards, { id: uid("og"), kind: "insight", tag: "INSIGHT", channel: "LinkedIn", headline: "New share-ready block", body: "" }]);

  return (
    <>
      <TextField label="Section title" value={s.title} onChange={(v) => set("title", v)} />
      <TextArea label="Lead paragraph" value={s.lead} onChange={(v) => set("lead", v)} rows={3} />
      <label className="lab" style={{display:"block", marginBottom:8}}>Share-ready blocks ({s.cards.length})</label>
      {s.cards.map((c, i) => (
        <details key={c.id || i} className="admin-item" style={{marginBottom:10}}>
          <summary style={{display:"flex", alignItems:"center", justifyContent:"space-between", cursor:"pointer", listStyle:"none", padding:"4px 0"}}><span><strong>{c.tag || c.kind}</strong> · {c.headline?.slice(0, 60) || "Untitled card"}</span>
            <div className="ec-row-actions" style={{display:"inline-flex", gap:4}}>
              <button className="btn btn-sm btn-ghost" onClick={(e) => { e.preventDefault(); move(i, -1); }}><Icon name="arrow-down" size={11} style={{transform:"rotate(180deg)"}} /></button>
              <button className="btn btn-sm btn-ghost" onClick={(e) => { e.preventDefault(); move(i, 1); }}><Icon name="arrow-down" size={11} /></button>
              <button className="btn btn-sm btn-ghost" onClick={(e) => { e.preventDefault(); if (confirm("Remove this card?")) remove(i); }}><Icon name="trash" size={11} /></button>
            </div>
          </summary>
          <div style={{marginTop:14}}>
            <div className="form-grid-3">
              <div className="form-row" style={{margin:0}}>
                <label className="lab">Kind</label>
                <select value={c.kind} onChange={(e) => setCard(i, "kind", e.target.value)}>
                  <option value="framework">Framework</option>
                  <option value="insight">Insight</option>
                  <option value="diagram">Diagram</option>
                  <option value="operational">Operational</option>
                  <option value="career">Career marker</option>
                </select>
              </div>
              <div className="form-row" style={{margin:0}}>
                <label className="lab">Tag (pre-headline)</label>
                <input value={c.tag} onChange={(e) => setCard(i, "tag", e.target.value)} />
              </div>
              <div className="form-row" style={{margin:0}}>
                <label className="lab">Channel</label>
                <select value={c.channel} onChange={(e) => setCard(i, "channel", e.target.value)}>
                  <option>LinkedIn</option>
                  <option>Twitter/X</option>
                  <option>WhatsApp</option>
                  <option>All</option>
                </select>
              </div>
            </div>
            <TextArea label="Headline" value={c.headline} onChange={(v) => setCard(i, "headline", v)} rows={2} />
            <TextArea label="Body" value={c.body} onChange={(v) => setCard(i, "body", v)} rows={4} hint="What appears below the headline on the 1200×630 share card." />
          </div>
        </details>
      ))}
      <button className="btn btn-sm" onClick={add}><Icon name="plus" size={11} /> Add card</button>
    </>
  );
};

// =========================================================
// RESUME ENGINE EDITOR (v5 structured) — shared block + 5 variants + ATS body
// =========================================================
const ResumeEngineEditor = ({ data, update }) => {
  const r = data.resumeEngine || { title: "", lead: "", shared: {}, variants: [], atsBody: { skillTiers: [], experience: [] } };
  const set = (k, v) => update({ ...data, resumeEngine: { ...r, [k]: v } });
  const setShared = (k, v) => set("shared", { ...(r.shared || {}), [k]: v });
  const setContact = (k, v) => setShared("contact", { ...(r.shared?.contact || {}), [k]: v });
  const setVariant = (i, k, v) => set("variants", r.variants.map((x, j) => j === i ? { ...x, [k]: v } : x));
  const setTier = (i, k, v) => set("atsBody", { ...r.atsBody, skillTiers: r.atsBody.skillTiers.map((t, j) => j === i ? { ...t, [k]: v } : t) });
  const addTier = () => set("atsBody", { ...r.atsBody, skillTiers: [...(r.atsBody.skillTiers || []), { tier: "", items: [] }] });
  const removeTier = (i) => set("atsBody", { ...r.atsBody, skillTiers: r.atsBody.skillTiers.filter((_, j) => j !== i) });
  const setExp = (i, k, v) => set("atsBody", { ...r.atsBody, experience: r.atsBody.experience.map((e, j) => j === i ? { ...e, [k]: v } : e) });
  const addExp = () => set("atsBody", { ...r.atsBody, experience: [...(r.atsBody.experience || []), { role: "", when: "", where: "", bullets: [] }] });
  const removeExp = (i) => set("atsBody", { ...r.atsBody, experience: r.atsBody.experience.filter((_, j) => j !== i) });

  return (
    <>
      <TextField label="Section title" value={r.title} onChange={(v) => set("title", v)} />
      <TextArea label="Lead paragraph" value={r.lead} onChange={(v) => set("lead", v)} rows={3} />

      <details className="admin-item" style={{marginBottom:14}} open>
        <summary style={{display:"flex", alignItems:"center", justifyContent:"space-between", cursor:"pointer", listStyle:"none", padding:"4px 0"}}><strong>Shared block</strong> <span style={{color:"var(--fg-muted)", fontSize:11}}>· identity used by every variant</span></summary>
        <div style={{marginTop:14}}>
          <div className="form-grid-2">
            <TextField label="Name" value={r.shared?.name} onChange={(v) => setShared("name", v)} />
            <TextField label="Headline" value={r.shared?.headline} onChange={(v) => setShared("headline", v)} />
          </div>
          <div className="form-grid-2">
            <TextField label="Location" value={r.shared?.location} onChange={(v) => setShared("location", v)} />
            <TextField label="Years experience" value={r.shared?.yearsExperience} onChange={(v) => setShared("yearsExperience", v)} />
          </div>
          <div className="form-grid-2">
            <TextField label="Email" value={r.shared?.contact?.email} onChange={(v) => setContact("email", v)} />
            <TextField label="Phone" value={r.shared?.contact?.phone} onChange={(v) => setContact("phone", v)} />
          </div>
          <div className="form-grid-2">
            <TextField label="LinkedIn handle" value={r.shared?.contact?.linkedin} onChange={(v) => setContact("linkedin", v)} />
            <TextField label="GitHub handle" value={r.shared?.contact?.github} onChange={(v) => setContact("github", v)} />
          </div>
        </div>
      </details>

      <label className="lab" style={{display:"block", marginBottom:8}}>Variants ({r.variants?.length || 0})</label>
      {(r.variants || []).map((v, i) => (
        <details key={v.id} className="admin-item" style={{marginBottom:10}}>
          <summary style={{display:"flex", alignItems:"center", justifyContent:"space-between", cursor:"pointer", listStyle:"none", padding:"4px 0"}}><span><strong>{v.name}</strong> <span style={{color:"var(--fg-muted)", fontSize:11}}>· {v.audience}</span></span>
          </summary>
          <div style={{marginTop:14}}>
            <div className="form-grid-2">
              <TextField label="Name" value={v.name} onChange={(val) => setVariant(i, "name", val)} />
              <TextField label="Audience" value={v.audience} onChange={(val) => setVariant(i, "audience", val)} />
            </div>
            <div className="form-grid-2">
              <TextField label="Kicker" value={v.kicker} onChange={(val) => setVariant(i, "kicker", val)} />
              <div className="form-row" style={{margin:0}}>
                <label className="lab">Accent color</label>
                <input type="color" value={v.color || "#2563eb"} onChange={(e) => setVariant(i, "color", e.target.value)} />
              </div>
            </div>
            <TextArea label="Summary" value={v.summary} onChange={(val) => setVariant(i, "summary", val)} rows={3} />
            <div className="form-row">
              <label className="lab">Emphasis bullets (one per line)</label>
              <textarea rows={4} value={(v.emphasis || []).join("\n")} onChange={(e) => setVariant(i, "emphasis", e.target.value.split("\n").filter(Boolean))} />
            </div>
          </div>
        </details>
      ))}

      <details className="admin-item" style={{marginTop:14}}>
        <summary style={{display:"flex", alignItems:"center", justifyContent:"space-between", cursor:"pointer", listStyle:"none", padding:"4px 0"}}><strong>ATS body</strong> <span style={{color:"var(--fg-muted)", fontSize:11}}>· plain text for the scanner-friendly variant</span></summary>
        <div style={{marginTop:14}}>
          <label className="lab" style={{display:"flex", justifyContent:"space-between", alignItems:"center"}}>
            <span>Skill tiers</span>
            <button className="btn btn-sm btn-ghost" onClick={addTier}><Icon name="plus" size={10} /> Add tier</button>
          </label>
          {(r.atsBody?.skillTiers || []).map((t, i) => (
            <div key={i} style={{marginBottom:10, padding:"10px 12px", border:"1px solid var(--border)", borderRadius:8}}>
              <div className="form-grid-2" style={{alignItems:"end"}}>
                <div className="form-row" style={{margin:0}}>
                  <label className="lab">Tier name</label>
                  <input value={t.tier} onChange={(e) => setTier(i, "tier", e.target.value)} />
                </div>
                <button className="btn btn-sm btn-ghost" onClick={() => removeTier(i)} style={{justifySelf:"end"}}><Icon name="trash" size={11} /> Remove</button>
              </div>
              <div className="form-row" style={{marginBottom:0}}>
                <label className="lab">Items (comma-separated)</label>
                <input value={(t.items || []).join(", ")} onChange={(e) => setTier(i, "items", e.target.value.split(",").map(x => x.trim()).filter(Boolean))} />
              </div>
            </div>
          ))}

          <label className="lab" style={{display:"flex", justifyContent:"space-between", alignItems:"center", marginTop:18}}>
            <span>Experience</span>
            <button className="btn btn-sm btn-ghost" onClick={addExp}><Icon name="plus" size={10} /> Add role</button>
          </label>
          {(r.atsBody?.experience || []).map((e, i) => (
            <div key={i} style={{marginBottom:10, padding:"10px 12px", border:"1px solid var(--border)", borderRadius:8}}>
              <div className="form-grid-3" style={{alignItems:"end"}}>
                <div className="form-row" style={{margin:0}}>
                  <label className="lab">Role</label>
                  <input value={e.role} onChange={(ev) => setExp(i, "role", ev.target.value)} />
                </div>
                <div className="form-row" style={{margin:0}}>
                  <label className="lab">When</label>
                  <input value={e.when} onChange={(ev) => setExp(i, "when", ev.target.value)} />
                </div>
                <button className="btn btn-sm btn-ghost" onClick={() => removeExp(i)}><Icon name="trash" size={11} /> Remove</button>
              </div>
              <TextField label="Where" value={e.where} onChange={(val) => setExp(i, "where", val)} />
              <div className="form-row" style={{marginBottom:0}}>
                <label className="lab">Bullets (one per line)</label>
                <textarea rows={4} value={(e.bullets || []).join("\n")} onChange={(ev) => setExp(i, "bullets", ev.target.value.split("\n").filter(Boolean))} />
              </div>
            </div>
          ))}
        </div>
      </details>
    </>
  );
};

// =========================================================
// CONFIG / SETTINGS CENTER (operational config → content/settings.json)
// =========================================================
const ConfigEditor = ({ data, update }) => {
  const { show } = React.useContext(ToastContext);
  const c = data.config || {};
  const setGroup = (g, k, v) => update({ ...data, config: { ...c, [g]: { ...(c[g] || {}), [k]: v } } });
  const Group = ({ title, hint, children }) => (
    <details className="admin-item" style={{ marginBottom: 10 }} open>
      <summary style={{ cursor: "pointer", listStyle: "none", padding: "6px 0", fontWeight: 600, fontSize: 13 }}>
        {title} {hint && <span style={{ color: "var(--fg-muted)", fontWeight: 400, fontSize: 11 }}>· {hint}</span>}
      </summary>
      <div style={{ marginTop: 12 }}>{children}</div>
    </details>
  );
  const Field = ({ g, k, label, type = "text", hint, options }) => (
    <div className="form-row">
      <label className="lab">{label}</label>
      {options
        ? <select value={(c[g] || {})[k] ?? ""} onChange={(e) => setGroup(g, k, e.target.value)}>{options.map(o => <option key={o} value={o}>{o || "—"}</option>)}</select>
        : <input type={type} value={(c[g] || {})[k] ?? ""} onChange={(e) => setGroup(g, k, type === "number" ? Number(e.target.value) : e.target.value)} />}
      {hint && <div className="hint">{hint}</div>}
    </div>
  );
  return (
    <>
      <p style={{ margin: "0 0 14px", color: "var(--text-3)", fontSize: 13 }}>
        Operational config — separate from page content. Saved to <code>content/settings.json</code>
        (read by the ingestion tool + deployment). API keys are <strong>never stored here</strong>.
      </p>

      <Group title="AI provider (BYOK)" hint="keys come from environment only">
        <Field g="ai" k="provider" label="Primary provider" options={["openai", "anthropic", "gemini", "mock"]} />
        <Field g="ai" k="model" label="Model (blank = provider default)" hint="e.g. gpt-4o-mini · claude-3-5-haiku-latest · gemini-1.5-flash" />
        <Field g="ai" k="fallbackProvider" label="Fallback provider" options={["", "openai", "anthropic", "gemini"]} />
        <div className="form-grid-3">
          <Field g="ai" k="tokenLimit" label="Max output / call" type="number" hint="hard per-call cap" />
          <Field g="ai" k="budgetTokens" label="Budget (cumulative)" type="number" hint="0 = off; warns at 80%, blocks at 100%" />
          <Field g="ai" k="timeoutMs" label="Timeout (ms)" type="number" />
        </div>
        <div className="hint" style={{ color: "var(--accent)" }}>Set <code>OPENAI_API_KEY</code> / <code>ANTHROPIC_API_KEY</code> / <code>GEMINI_API_KEY</code> in your shell, never here.</div>
      </Group>

      <Group title="Portfolio">
        <Field g="portfolio" k="ownerName" label="Owner name" />
        <Field g="portfolio" k="tagline" label="Tagline" />
      </Group>

      <Group title="Publishing">
        <Field g="publishing" k="defaultStatus" label="Default status for new items" options={["draft", "review", "published", "archived"]} />
        <Field g="publishing" k="showOnPublic" label="Statuses shown on public site (comma-sep)" hint="e.g. published" />
      </Group>

      <Group title="Ingestion">
        <Field g="ingestion" k="defaultStatus" label="Default publish status for ingested projects" options={["draft", "review", "published"]} />
        <Field g="ingestion" k="defaultRole" label="Default résumé target role" />
      </Group>

      <Group title="Résumé">
        <Field g="resume" k="defaultVariant" label="Default variant" />
        <Field g="resume" k="pdfFile" label="Resume file" />
      </Group>

      <Group title="Deployment">
        <Field g="deployment" k="canonicalUrl" label="Canonical site URL" hint="e.g. https://yourname.dev — used for canonical + OG when Sync meta is on" />
        <Field g="deployment" k="ogImage" label="OG image path" hint="e.g. assets/og-card.png" />
        <div className="form-row">
          <label className="lab">Sync meta tags at runtime</label>
          <input type="checkbox" checked={!!(c.deployment || {}).syncMeta} onChange={(e) => setGroup("deployment", "syncMeta", e.target.checked)} />
          <div className="hint">Updates canonical/OG tags in-browser from this URL. Note: social scrapers read the static HTML — set the real domain there too before launch.</div>
        </div>
      </Group>

      <Group title="Analytics" hint="optional · privacy-friendly · off by default">
        <Field g="analytics" k="plausibleDomain" label="Plausible domain" hint="e.g. yourname.dev — leave blank to disable analytics entirely" />
      </Group>

      <div style={{ height: 8 }} />
      <button className="btn btn-accent" onClick={async () => {
        let res = await publishSettings(c);
        if (res.reason === "auth") {
          const pw = window.prompt("Enter your edit password to save config live:");
          if (!pw) { show("Save cancelled"); return; }
          setAdminToken(pw); res = await publishSettings(c);
          if (res.reason === "auth") { setAdminToken(""); show("Wrong password — try again"); return; }
        }
        update({ ...data, config: { ...c, backup: { ...(c.backup || {}), lastSnapshotAt: new Date().toISOString() } } });
        show(res.mode === "cloud" ? "✓ Config saved live" : res.mode === "disk" ? "Saved → content/settings.json" : "settings.json downloaded — commit it");
      }}><Icon name="check" size={13} /> Save config</button>
    </>
  );
};

// =========================================================
// START HERE — guided onboarding + live completeness checklist
// The single biggest usability win: instead of 18 flat tabs, a new user
// lands here, sees what's done vs. missing, and jumps straight to the editor
// that matters. Recruiter-essential items first.
// =========================================================
const startChecks = (data) => {
  const h = data.hero || {};
  const products = (data.products?.items || []);
  const re = data.resumeEngine || {};
  const channels = (data.contact?.channels || []);
  const firstProd = products[0] || {};
  return [
    { tab: "hero",         label: "Add your profile photo",            done: !!h.avatar },
    { tab: "hero",         label: "Set your name + role line",         done: !!(h.name && h.subtitle) },
    { tab: "hero",         label: "Write your intro paragraph",        done: !!(h.intro && h.intro.length > 40) },
    { tab: "products",     label: "Add at least one project/product",  done: products.length > 0 },
    { tab: "products",     label: "Give your top project a screenshot or live link", done: !!(firstProd.image || firstProd.screenshotSlot || firstProd.links?.demo || firstProd.links?.github) },
    { tab: "resumeEngine", label: "Fill resume identity (name + email)", done: !!(re.shared?.name && re.shared?.contact?.email) },
    { tab: "contact",      label: "Add a way to reach you",            done: channels.some(c => c.value) },
  ];
};

const StartHere = ({ data, setTab, saveState }) => {
  const checks = startChecks(data);
  const done = checks.filter(c => c.done).length;
  const pct = Math.round((done / checks.length) * 100);
  return (
    <div className="start-here">
      <h4 style={{margin:"0 0 4px"}}>Welcome back, Lakshman</h4>
      <p style={{margin:"0 0 16px", color:"var(--text-3)", fontSize:13}}>
        Everything on your site is edited from this panel. You don’t need to touch every tab —
        finish the essentials below and you’re recruiter-ready.
      </p>

      {!saveState?.ok && (
        <div style={{padding:"10px 14px", marginBottom:14, background:"rgba(239,68,68,0.08)",
                     border:"1px solid rgba(239,68,68,0.25)", borderRadius:8, color:"#be123c", fontSize:12.5}}>
          ⚠ Your last change didn’t save{saveState?.reason === "quota" ? " — browser storage is full. Remove a large image or use a link, then export your data from Settings." : "."}
        </div>
      )}

      <div style={{display:"flex", alignItems:"center", gap:10, marginBottom:6}}>
        <strong style={{fontSize:13}}>Setup progress</strong>
        <span style={{color:"var(--text-3)", fontSize:12}}>{done}/{checks.length} · {pct}%</span>
      </div>
      <div style={{height:8, background:"var(--bg-2)", borderRadius:99, overflow:"hidden", marginBottom:18}}>
        <div style={{height:"100%", width:pct + "%", background:"var(--accent)", transition:"width .3s"}} />
      </div>

      <div className="start-checklist" style={{display:"flex", flexDirection:"column", gap:8, marginBottom:22}}>
        {checks.map((c, i) => (
          <button key={i} className="start-check-row" onClick={() => setTab(c.tab)}
            style={{display:"flex", alignItems:"center", gap:10, textAlign:"left", width:"100%",
                    padding:"10px 12px", border:"1px solid var(--border)", borderRadius:8,
                    background: c.done ? "rgba(16,185,129,0.06)" : "var(--bg)", cursor:"pointer"}}>
            <span style={{flexShrink:0, width:18, height:18, borderRadius:99, display:"grid", placeItems:"center",
                          background: c.done ? "var(--accent)" : "transparent",
                          border: c.done ? "none" : "1.5px solid var(--border)", color:"#fff"}}>
              {c.done && <Icon name="check" size={11} />}
            </span>
            <span style={{flex:1, fontSize:13, textDecoration: c.done ? "line-through" : "none", color: c.done ? "var(--text-3)" : "var(--text-1)"}}>{c.label}</span>
            <span style={{color:"var(--text-3)", fontSize:11}}>{c.done ? "Edit" : "Do this →"}</span>
          </button>
        ))}
      </div>

      <h4 style={{margin:"0 0 8px", fontSize:13}}>Two things to know</h4>
      <ul style={{margin:"0 0 10px", paddingLeft:18, color:"var(--text-2)", fontSize:12.5, lineHeight:1.7}}>
        <li><strong>One source of truth.</strong> Edit a project once — its card, modal, and matching résumé all update.</li>
        <li><strong>Back up regularly.</strong> Your content lives in this browser. Use <em>Settings → Export data</em> to save a copy you can re-import anywhere.</li>
      </ul>
    </div>
  );
};

// =========================================================
// Admin Panel shell — tabs grouped into a recruiter-first flow
// =========================================================
const TAB_GROUPS = [
  { group: null,        items: [{ id: "start", label: "Start here" }] },
  { group: "Essentials", items: [
    { id: "hero",         label: "Hero / intro" },
    { id: "products",     label: "Projects" },
    { id: "resumeEngine", label: "Résumé engine" },
    { id: "contact",      label: "Contact" },
  ]},
  { group: "Your story", items: [
    { id: "capabilities", label: "Capability" },
    { id: "process",      label: "Process" },
    { id: "principles",   label: "Principles" },
    { id: "evolution",    label: "Evolution" },
    { id: "journey",      label: "Journey" },
  ]},
  { group: "Proof & depth", items: [
    { id: "projects",     label: "Case studies" },
    { id: "frameworks",   label: "Frameworks" },
    { id: "learning",     label: "Learning" },
    { id: "showcase",     label: "Showcase" },
    { id: "stack",        label: "Tech stack" },
    { id: "downloads",    label: "Downloads" },
  ]},
  { group: "Share & export", items: [
    { id: "social",       label: "Social cards" },
    { id: "resume",       label: "Resume (legacy)" },
  ]},
  { group: "Operations", items: [
    { id: "config",   label: "Config" },
    { id: "settings", label: "Settings & publish" },
  ]},
];

const AdminPanel = ({ open, onClose, tab, setTab, data, update, onReset, saveState }) => {
  const renderTab = () => {
    switch (tab) {
      case "start":        return <StartHere          data={data} setTab={setTab} saveState={saveState} />;
      case "config":       return <ConfigEditor       data={data} update={update} />;
      case "hero":         return <HeroEditor         data={data} update={update} />;
      case "capabilities": return <CapabilitiesEditor data={data} update={update} />;
      case "process":      return <ProcessEditor      data={data} update={update} />;
      case "principles":   return <PrinciplesEditor   data={data} update={update} />;
      case "products":     return <ProductsEditor     data={data} update={update} />;
      case "projects":     return <ProjectsEditor     data={data} update={update} />;
      case "frameworks":   return <FrameworksEditor   data={data} update={update} />;
      case "learning":     return <LearningEditor     data={data} update={update} />;
      case "showcase":     return <ShowcaseEditor     data={data} update={update} />;
      case "stack":        return <StackEditor        data={data} update={update} />;
      case "downloads":    return <DownloadsEditor    data={data} update={update} />;
      case "social":       return <SocialEditor       data={data} update={update} />;
      case "evolution":    return <EvolutionEditor    data={data} update={update} />;
      case "journey":      return <JourneyEditor      data={data} update={update} />;
      case "resumeEngine": return <ResumeEngineEditor data={data} update={update} />;
      case "resume":       return <ResumeEditor       data={data} update={update} />;
      case "contact":      return <ContactEditor      data={data} update={update} />;
      case "settings":     return <SettingsEditor     data={data} update={update} onReset={onReset} />;
      default: return null;
    }
  };
  const saved = saveState?.ok !== false;
  return (
    <aside className={"admin-panel" + (open ? " open" : "")}>
      <div className="admin-head">
        <div>
          <h3>Portfolio CMS</h3>
          <div className="sub">Live · saved in this browser</div>
        </div>
        <button className="btn btn-icon btn-ghost" onClick={onClose}><Icon name="close" size={16} /></button>
      </div>
      <div className="admin-tabs admin-tabs-grouped">
        {TAB_GROUPS.map((g, gi) => (
          <div className="admin-tab-group" key={gi}>
            {g.group && <div className="admin-tab-group-label">{g.group}</div>}
            {g.items.map(t => (
              <button key={t.id} className={"admin-tab" + (tab === t.id ? " active" : "")} onClick={() => setTab(t.id)}>{t.label}</button>
            ))}
          </div>
        ))}
      </div>
      <div className="admin-body">{renderTab()}</div>
      <div className="admin-foot">
        <span>{saved ? "Changes save automatically" : "Last change not saved"}</span>
        <span style={{color: saved ? undefined : "#be123c"}}>
          <Icon name={saved ? "check" : "close"} size={12} /> {saved ? "Saved" : (saveState?.reason === "quota" ? "Storage full" : "Save failed")}
        </span>
      </div>
    </aside>
  );
};

Object.assign(window, { AdminPanel });
