/* editor.jsx — the live-editing form. One section visible at a time (chosen in nav). */
const { useState, useRef, useEffect } = React;
const uid = () => Math.random().toString(36).slice(2, 9);
const NOW_MY = new Date().toLocaleDateString("en-US", { month: "short", year: "numeric" });

const NAV_ORDER = ["basics","summary","experience","projects","education","skills","certs"];
const NAV_LABELS = { basics:"Personal details", summary:"Summary", experience:"Experience", projects:"Projects", education:"Education", skills:"Skills", certs:"Certifications" };

function NextBtn({ section, setSection }) {
  const idx = NAV_ORDER.indexOf(section);
  if (idx < 0 || idx >= NAV_ORDER.length - 1) return null;
  const next = NAV_ORDER[idx + 1];
  return (
    <div className="next-section-btn" style={{ marginTop: 28, paddingTop: 20, borderTop: "1px solid var(--slate-100)", justifyContent: "flex-end" }}>
      <button className="btn btn-soft btn-sm" onClick={() => setSection(next)} style={{ gap: 6 }}>
        Next: {NAV_LABELS[next]} <Icon name="chevR" size={14} />
      </button>
    </div>
  );
}
const autoSize = (el) => { el.style.height = 'auto'; el.style.height = el.scrollHeight + 'px'; };

function Field({ label, hint, children }) {
  return (
    <div className="field">
      {label && <label>{label}{hint && <span className="hint">{hint}</span>}</label>}
      {children}
    </div>);

}
function TextIn({ value, onChange, placeholder, type = "text" }) {
  return <input className="inp" type={type} value={value || ""} placeholder={placeholder}
  onChange={(e) => onChange(e.target.value)} />;
}
function Area({ value, onChange, placeholder }) {
  return <textarea className="ta" value={value || ""} placeholder={placeholder}
  onChange={(e) => onChange(e.target.value)} />;
}

/* Collapsible repeatable entry */
function Entry({ open, onToggle, title, sub, onDelete, onDuplicate, children }) {
  return (
    <div className={"entry" + (open ? " open" : "")}>
      <div className="entry-head" onClick={onToggle}>
        <span className="grip" onClick={(e) => e.stopPropagation()}><Icon name="grip" size={16} /></span>
        <div className="entry-info">
          <div className="ttl" title={title || "Untitled"}>{title || "Untitled"}</div>
          {sub && <div className="sub">{sub}</div>}
        </div>
        <div className="entry-actions" onClick={(e) => e.stopPropagation()}>
          {onDuplicate && <button className="icon-btn" title="Duplicate" onClick={onDuplicate}><Icon name="copy" size={16} /></button>}
          <button className="icon-btn danger" title="Delete" onClick={onDelete}><Icon name="trash" size={16} /></button>
          <button className="icon-btn"><Icon name="chev" size={16} style={{ transition: "transform .18s", transform: open ? "rotate(180deg)" : "" }} /></button>
        </div>
      </div>
      {open && <div className="entry-body">{children}</div>}
    </div>);

}

function splitBullets(text) {
  return (text || "")
    .split(/\r?\n/)
    .map((s) => s.replace(/^\s*([•\-\*–—·▪◦‣o]|\d+[.)])\s+/, "").trim())
    .filter(Boolean);
}

/* Reusable AI improve button for plain-text description/detail fields */
function AITextBtn({ value, onChange, prompt, aiHelpers }) {
  const [busy, setBusy] = React.useState(false);
  if (aiHelpers === false || !window.groqStream) return null;
  const run = async () => {
    if (busy || !value || !value.trim()) return;
    const orig = value;
    setBusy(true);
    await window.groqStream({
      messages: [
        { role: "system", content: window.GROQ_SYSTEM || "" },
        { role: "user", content: prompt + "\n\nReturn ONLY the improved text - no explanation, no quotes:\n\n" + orig },
      ],
      maxTokens: 200,
      onChunk: (_, full) => onChange(full),
      onDone: () => setBusy(false),
      onError: (e) => {
        onChange(orig);
        setBusy(false);
        if (aiHelpers && aiHelpers.showToast) aiHelpers.showToast(e === "free_limit_reached"
          ? "Free AI limit reached — upgrade to Pro for unlimited use."
          : (typeof e === "string" ? e : "AI error — couldn't improve text."));
      },
    });
  };
  return (
    <button className="icon-btn ai-spark rm" title="Improve with AI" disabled={busy || !value || !value.trim()} onClick={run}
      style={{ marginTop: 2 }}>
      {busy
        ? <span className="spin" style={{ width: 13, height: 13, borderColor: "rgba(28,155,230,.25)", borderTopColor: "var(--brand-blue)" }} />
        : <Icon name="writeai" size={13} />}
    </button>
  );
}

function BulletEditor({ bullets, onChange, aiCtx, aiHelpers }) {
  const [showPaste,    setShowPaste]    = useState(false);
  const [pasteText,    setPasteText]    = useState("");
  const [improvingIdx, setImprovingIdx] = useState(null);
  const bulletsRef = useRef(bullets);
  const listRef    = useRef(null);
  useEffect(() => { bulletsRef.current = bullets; }, [bullets]);
  useEffect(() => {
    if (!listRef.current) return;
    const el = listRef.current;
    requestAnimationFrame(() => el.querySelectorAll('textarea').forEach(autoSize));
  }, [bullets]);

  const doImprove = async (i) => {
    if (!window.groqStream || improvingIdx !== null) return;
    const text = (bulletsRef.current || [])[i];
    if (!text || !text.trim()) return;
    const orig = text;
    setImprovingIdx(i);
    await window.groqStream({
      messages: [
        { role: "system", content: window.GROQ_SYSTEM || "" },
        { role: "user", content: "Improve this résumé bullet for a " + ((aiCtx && aiCtx.role) || "professional") + " role at " + ((aiCtx && aiCtx.company) || "a company") + ". Stronger action verb, quantify if possible. Return ONLY the improved bullet — no explanation, no quotes:\n\n" + orig },
      ],
      maxTokens: 150,
      onChunk: (_, full) => {
        const n = [...(bulletsRef.current || [])];
        n[i] = full;
        onChange(n);
      },
      onDone: () => setImprovingIdx(null),
      onError: (e) => {
        const n = [...(bulletsRef.current || [])];
        n[i] = orig;
        onChange(n);
        setImprovingIdx(null);
        if (aiHelpers && aiHelpers.showToast) aiHelpers.showToast(e === "free_limit_reached"
          ? "Free AI limit reached — upgrade to Pro for unlimited use."
          : (typeof e === "string" ? e : "AI error — couldn't improve bullet."));
      },
    });
  };

  // Pasting multi-line text into a single bullet auto-splits into separate bullets.
  const handlePaste = (e, i) => {
    const text = e.clipboardData.getData("text");
    if (!/\r?\n/.test(text)) return; // single line — let it paste normally
    e.preventDefault();
    const parts = splitBullets(text);
    if (!parts.length) return;
    const n = [...bullets];
    const cur = (n[i] || "").trim();
    if (cur) n.splice(i + 1, 0, ...parts);
    else n.splice(i, 1, ...parts);
    onChange(n);
  };

  const applyPaste = () => {
    const parts = splitBullets(pasteText);
    if (!parts.length) { setShowPaste(false); return; }
    const existing = (bullets || []).filter((b) => b.trim());
    onChange([...existing, ...parts]);
    setPasteText("");
    setShowPaste(false);
  };

  return (
    <div style={{ marginTop: 6 }} ref={listRef} data-comment-anchor="16eddcc35f-div-45-5">
      <label style={{ fontSize: 12, fontWeight: 650, color: "var(--slate-600)", display: "block", marginBottom: 7 }}>Highlights</label>
      {(bullets || []).map((b, i) =>
      <div className="bullet" key={i}>
          <span className="dot" />
          <textarea className="ta" style={{ minHeight: 38 }} value={b}
        placeholder="Describe an accomplishment — start with an action verb, add a metric."
        onPaste={(e) => handlePaste(e, i)}
        onChange={(e) => {const n = [...bullets];n[i] = e.target.value;onChange(n);autoSize(e.target);}} />
          {aiHelpers !== false && (
            <button className="icon-btn ai-spark rm" title="Improve with AI"
              disabled={improvingIdx !== null} onClick={() => doImprove(i)}>
              {improvingIdx === i
                ? <span className="spin" style={{ width: 13, height: 13, borderColor: "rgba(28,155,230,.25)", borderTopColor: "var(--brand-blue)" }} />
                : <Icon name="writeai" size={13} />}
            </button>
          )}
          <button className="icon-btn danger rm" onClick={() => onChange(bullets.filter((_, j) => j !== i))}><Icon name="x" size={15} /></button>
        </div>
      )}

      {showPaste &&
      <div className="paste-box">
          <div className="paste-hint">
            <Icon name="text" size={14} style={{ color: "var(--brand-blue)" }} />
            Paste your bullets below — one per line. We'll clean up any <span className="kbd">•</span> <span className="kbd">-</span> <span className="kbd">1.</span> prefixes and split them into separate highlights.
          </div>
          <textarea className="ta" autoFocus style={{ minHeight: 116, marginTop: 9 }}
          value={pasteText} onChange={(e) => setPasteText(e.target.value)}
          placeholder={"• Led end-to-end redesign of onboarding, lifting activation 34%\n• Built a 60-component design system adopted by 4 squads\n• Ran 30+ usability sessions feeding a quarterly roadmap"} />
          <div style={{ display: "flex", alignItems: "center", gap: 9, marginTop: 10 }}>
            <button className="btn btn-grad btn-sm" onClick={applyPaste} disabled={!splitBullets(pasteText).length}
            style={{ opacity: splitBullets(pasteText).length ? 1 : .5 }}>
              <Icon name="plus" size={14} /> Add {splitBullets(pasteText).length || ""} {splitBullets(pasteText).length === 1 ? "highlight" : "highlights"}
            </button>
            <button className="btn btn-ghost btn-sm" onClick={() => { setShowPaste(false); setPasteText(""); }}>Cancel</button>
            <span style={{ marginLeft: "auto", fontSize: 11.5, color: "var(--slate-400)" }}>Replaces empty rows</span>
          </div>
        </div>
      }

      {!showPaste &&
      <div style={{ display: "flex", gap: 8, marginTop: 4, flexWrap: "wrap" }}>
          <button className="btn btn-soft btn-sm" onClick={() => onChange([...(bullets || []), ""])}>
            <Icon name="plus" size={14} /> Add highlight
          </button>
          <button className="btn btn-ghost btn-sm" onClick={() => setShowPaste(true)}>
            <Icon name="copy" size={14} /> Paste list
          </button>
          {aiHelpers !== false && (bullets || []).some(b => b.trim()) && (
            <button className="btn btn-ghost btn-sm ai-inline-btn" disabled={improvingIdx !== null}
              onClick={() => {
                var delay = 0;
                (bullets || []).forEach(function(b, i) {
                  if (b.trim()) { setTimeout(function() { doImprove(i); }, delay); delay += 1400; }
                });
              }}>
              <Icon name="writeai" size={13} /> Improve all
            </button>
          )}
        </div>
      }
    </div>);

}

function ChipEditor({ items, onChange }) {
  const [draft, setDraft] = useState("");
  const add = () => {const v = draft.trim();if (v) {onChange([...(items || []), v]);setDraft("");}};
  return (
    <div className="chips">
      {(items || []).map((it, i) =>
      <span className="chip" key={i}>{it}
          <button onClick={() => onChange(items.filter((_, j) => j !== i))}><Icon name="x" size={13} /></button>
        </span>
      )}
      <input className="chip-input" value={draft} placeholder="Type a skill, press Enter"
      onChange={(e) => setDraft(e.target.value)}
      onKeyDown={(e) => {if (e.key === "Enter") {e.preventDefault();add();}if (e.key === "Backspace" && !draft && items.length) onChange(items.slice(0, -1));}} />
    </div>);

}

function RichText({ value, onChange, placeholder }) {
  const ref = useRef(null);
  useEffect(() => { if (ref.current && ref.current.innerHTML !== (value || "")) ref.current.innerHTML = value || ""; }, []);
  const exec = (cmd) => { document.execCommand(cmd, false, null); if (ref.current) { ref.current.focus(); onChange(ref.current.innerHTML); } };
  return (
    <div className="rte-wrap">
      <div className="rte-toolbar">
        <button type="button" className="rte-btn" title="Bold" onMouseDown={(e) => { e.preventDefault(); exec("bold"); }}><b>B</b></button>
        <button type="button" className="rte-btn" title="Italic" onMouseDown={(e) => { e.preventDefault(); exec("italic"); }}><i>I</i></button>
        <button type="button" className="rte-btn" title="Underline" onMouseDown={(e) => { e.preventDefault(); exec("underline"); }}><u>U</u></button>
        <span className="rte-sep" />
        <button type="button" className="rte-btn wide" title="Bulleted list" onMouseDown={(e) => { e.preventDefault(); exec("insertUnorderedList"); }}><Icon name="text" size={13} /> List</button>
      </div>
      <div ref={ref} className="rte scroll" contentEditable suppressContentEditableWarning
        data-ph={placeholder} onInput={(e) => onChange(e.currentTarget.innerHTML)} />
    </div>
  );
}

function PhotoUpload({ value, onChange }) {
  const inputRef = useRef(null);
  const onFile = (e) => {
    const f = e.target.files && e.target.files[0];
    if (!f) return;
    const reader = new FileReader();
    reader.onload = () => onChange(reader.result);
    reader.readAsDataURL(f);
    e.target.value = "";
  };
  return (
    <div className="photo-field">
      <button className={"photo-prev" + (value ? " has" : "")} onClick={() => inputRef.current.click()} title="Upload photo">
        {value ? <img src={value} alt="" /> : <Icon name="image" size={24} />}
      </button>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
          <button className="btn btn-soft btn-sm" onClick={() => inputRef.current.click()}>
            <Icon name="upload" size={14} /> {value ? "Replace" : "Upload"} photo
          </button>
          {value && <button className="icon-btn danger" title="Remove photo" aria-label="Remove photo" onClick={() => onChange("")}><Icon name="trash" size={15} /></button>}
        </div>
        <p className="photo-note">Optional. Helpful in the EU, LATAM &amp; APAC. Leave blank for US/UK roles — most ATS can't read images.</p>
      </div>
      <input ref={inputRef} type="file" accept="image/*" onChange={onFile} style={{ display: "none" }} />
    </div>
  );
}

function Segmented({ value, options, onChange }) {
  return (
    <div className="seg">
      {options.map(([v, l]) => (
        <button key={v} className={value === v ? "on" : ""} onClick={() => onChange(v)}>{l}</button>
      ))}
    </div>
  );
}

function DesignPanel({ design, setDesign }) {
  const set = (k, v) => setDesign((d) => ({ ...d, [k]: v }));
  const fonts = window.FONTS || [];
  const accents = window.RESUME_ACCENTS || [];
  const checkColor = (hex) => {
    const n = parseInt((hex || "#000").replace("#",""), 16);
    const r=(n>>16)&255, g=(n>>8)&255, b=n&255;
    return (r*299+g*587+b*114)/1000 > 140 ? "#111" : "#fff";
  };
  return (
    <div className="editor-inner">
      <div className="ed-head"><h2>Design</h2><p>Fine-tune how your résumé looks. Everything here stays ATS-safe — standard fonts, real selectable text, high contrast.</p></div>

      <label className="dz-label">Font</label>
      <div className="font-grid">
        {fonts.map((ft) => (
          <button key={ft.key} className={"font-card" + (((design.font || "auto") === ft.key) ? " sel" : "")}
            onClick={() => set("font", ft.key)}>
            <span className="fc-aa" style={{ fontFamily: ft.stack || "var(--ui)" }}>Ag</span>
            <span className="fc-name">{ft.label}{ft.note && <em> · {ft.note}</em>}</span>
          </button>
        ))}
      </div>

      <label className="dz-label" style={{ marginTop: 22 }}>Accent color</label>
      <div className="swatches">
        {accents.map((c) => (
          <button key={c} className={"swatch" + ((design.accent === c) ? " sel" : "")} style={{ background: c }}
            onClick={() => set("accent", c)} title={c}>
            {design.accent === c && <Icon name="check" size={14} strokeWidth={2.6} style={{ color: checkColor(c) }} />}
          </button>
        ))}
        <label className={"swatch custom" + (!accents.includes(design.accent) && design.accent ? " sel" : "")}
          style={!accents.includes(design.accent) && design.accent ? { background: design.accent } : {}}
          title="Custom color">
          {!accents.includes(design.accent) && design.accent
            ? <Icon name="check" size={14} strokeWidth={2.6} style={{ color: checkColor(design.accent) }} />
            : <Icon name="plus" size={15} />}
          <input type="color" value={design.accent || "#1C9BE6"} onChange={(e) => set("accent", e.target.value)} />
        </label>
      </div>

      <label className="dz-label" style={{ marginTop: 22 }}>Text size</label>
      <Segmented value={design.scale || "normal"} onChange={(v) => set("scale", v)}
        options={[["small", "Small"], ["normal", "Normal"], ["large", "Large"]]} />

      <label className="dz-label" style={{ marginTop: 18 }}>Line spacing</label>
      <Segmented value={design.spacing || "normal"} onChange={(v) => set("spacing", v)}
        options={[["compact", "Compact"], ["normal", "Normal"], ["relaxed", "Relaxed"]]} />

      <button className="btn btn-ghost btn-sm" style={{ marginTop: 24 }}
        onClick={() => setDesign({ font: "auto", accent: "#1C9BE6", scale: "normal", spacing: "normal" })}>
        Reset to defaults
      </button>
    </div>
  );
}

const ALL_SECTIONS = [
  { id: "experience", label: "Experience",    icon: "briefcase" },
  { id: "projects",   label: "Projects",      icon: "folder"    },
  { id: "education",  label: "Education",     icon: "cap"       },
  { id: "skills",     label: "Skills",        icon: "sparkle"   },
  { id: "certs",      label: "Certifications",icon: "award"     },
];

function ColLayoutPanel({ sidebarSections, setSidebarSections, sectionOrder }) {
  const { useState: S } = React;
  const [dragId, setDragId]       = S(null);
  const [dragTarget, setDragTarget] = S(null); // "main" | "sidebar"

  const mainSections    = sectionOrder.filter(id => !sidebarSections.includes(id));
  const sidebarOrdered  = sectionOrder.filter(id => sidebarSections.includes(id));

  const moveTo = (id, col) => {
    setSidebarSections(prev => {
      if (col === "sidebar") return prev.includes(id) ? prev : [...prev, id];
      return prev.filter(x => x !== id);
    });
  };

  const handleDrop = (col) => {
    if (!dragId) return;
    moveTo(dragId, col);
    setDragId(null); setDragTarget(null);
  };

  const ColBox = ({ col, ids, label, hint }) => (
    <div
      onDragOver={e => { e.preventDefault(); setDragTarget(col); }}
      onDragLeave={() => setDragTarget(null)}
      onDrop={() => handleDrop(col)}
      style={{
        flex: 1, minHeight: 140, border: "2px dashed",
        borderColor: dragTarget === col ? "var(--brand-blue)" : "var(--slate-200)",
        borderRadius: 10, padding: "12px 10px",
        background: dragTarget === col ? "rgba(28,155,230,.05)" : "var(--slate-50,#f8f9fc)",
        transition: "border-color .15s, background .15s",
      }}>
      <div style={{ fontSize: 11, fontWeight: 700, letterSpacing: ".06em", textTransform: "uppercase", color: "var(--slate-500)", marginBottom: 10 }}>{label}</div>
      <div style={{ fontSize: 11, color: "var(--slate-400)", marginBottom: 8 }}>{hint}</div>
      {ids.length === 0 && (
        <div style={{ fontSize: 12, color: "var(--slate-300)", fontStyle: "italic", textAlign: "center", paddingTop: 12 }}>Drop sections here</div>
      )}
      {ids.map(id => {
        const s = ALL_SECTIONS.find(x => x.id === id);
        if (!s) return null;
        return (
          <div key={id}
            draggable
            onDragStart={() => setDragId(id)}
            onDragEnd={() => { setDragId(null); setDragTarget(null); }}
            style={{
              display: "flex", alignItems: "center", gap: 8, padding: "7px 10px",
              marginBottom: 5, borderRadius: 7, background: "#fff",
              border: "1px solid var(--slate-200)", cursor: "grab",
              opacity: dragId === id ? 0.4 : 1,
              boxShadow: "0 1px 3px rgba(0,0,0,.06)",
              fontSize: 13, fontWeight: 500, color: "var(--slate-700)",
            }}>
            <Icon name="grip" size={13} style={{ color: "var(--slate-300)", flexShrink: 0 }} />
            <Icon name={s.icon} size={14} style={{ color: "var(--slate-400)", flexShrink: 0 }} />
            <span style={{ flex: 1 }}>{s.label}</span>
            <button
              onClick={() => moveTo(id, col === "main" ? "sidebar" : "main")}
              title={col === "main" ? "Move to sidebar" : "Move to main column"}
              style={{ background: "none", border: "none", cursor: "pointer", padding: "0 2px", color: "var(--slate-400)", fontSize: 16, lineHeight: 1 }}>
              {col === "main" ? "→" : "←"}
            </button>
          </div>
        );
      })}
    </div>
  );

  return (
    <div className="editor-inner">
      <div className="ed-head">
        <h2>Column layout</h2>
        <p>Drag sections between columns to customise what appears in the main area and what goes in the sidebar.</p>
      </div>
      <div style={{ display: "flex", gap: 10 }}>
        <ColBox col="main"    ids={mainSections}   label="Main column"  hint="Wider — best for experience & projects" />
        <ColBox col="sidebar" ids={sidebarOrdered}  label="Sidebar"      hint="Narrower — best for skills & education" />
      </div>
      <p style={{ fontSize: 12, color: "var(--slate-400)", marginTop: 12 }}>
        Drag a section card or click the arrow to move it. Section order within each column follows the order set in Sections.
      </p>
    </div>
  );
}

function Editor({ data, patch, section, openIds, setOpenIds, setSection, design, setDesign, aiHelpers, sidebarSections, setSidebarSections, sectionOrder, template }) {
  const [hasTriedAI, setHasTriedAI] = React.useState(false);
  const [colTipDismissed, setColTipDismissed] = React.useState(() => { try { return !!localStorage.getItem("bdr_col_layout_seen"); } catch { return false; } });
  const toggle = (id) => setOpenIds((o) => ({ ...o, [id]: !o[id] }));
  const setBasics = (k, v) => patch((d) => ({ ...d, basics: { ...d.basics, [k]: v } }));

  // generic list helpers
  const listAdd = (key, item) => patch((d) => ({ ...d, [key]: [...(d[key] || []), item] }));
  const listSet = (key, id, k, v) => patch((d) => ({ ...d, [key]: (d[key] || []).map((x) => x.id === id ? { ...x, [k]: v } : x) }));
  const listDel = (key, id) => patch((d) => ({ ...d, [key]: (d[key] || []).filter((x) => x.id !== id) }));
  const listDup = (key, id) => patch((d) => {const arr = d[key] || [];const i = arr.findIndex((x) => x.id === id);const copy = { ...arr[i], id: uid() };const n = [...arr];n.splice(i + 1, 0, copy);return { ...d, [key]: n };});

  const isTwoCol = template === "split" || template === "sidebar";
  const ColLayoutTip = isTwoCol && !colTipDismissed ? (
    <div style={{ margin: "0 0 16px", padding: "11px 14px", background: "linear-gradient(135deg,#EEEDFE,#F0F9FF)", border: "1px solid #AFA9EC", borderRadius: 10, display: "flex", gap: 10, alignItems: "flex-start" }}>
      <span style={{ fontSize: 18, lineHeight: 1, flexShrink: 0 }}>🎨</span>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontWeight: 700, fontSize: 13, color: "#3C3489", marginBottom: 3 }}>Did you know?</div>
        <div style={{ fontSize: 12.5, color: "#534AB7", lineHeight: 1.5 }}>
          You can customise which sections appear in each column — move Skills, Education, or Experience between the main area and the sidebar.
        </div>
        <button
          onClick={() => { setSection("col-layout"); setColTipDismissed(true); try { localStorage.setItem("bdr_col_layout_seen","1"); } catch {} }}
          style={{ marginTop: 8, fontSize: 12, fontWeight: 600, color: "#fff", background: "#534AB7", border: "none", borderRadius: 6, padding: "5px 12px", cursor: "pointer" }}>
          Open Column layout →
        </button>
      </div>
      <button onClick={() => { setColTipDismissed(true); try { localStorage.setItem("bdr_col_layout_seen","1"); } catch {} }}
        style={{ background: "none", border: "none", cursor: "pointer", color: "#AFA9EC", fontSize: 16, lineHeight: 1, padding: 0, flexShrink: 0 }}>✕</button>
    </div>
  ) : null;

  if (section === "design") return <DesignPanel design={design} setDesign={setDesign} />;
  if (section === "col-layout") return <ColLayoutPanel sidebarSections={sidebarSections} setSidebarSections={setSidebarSections} sectionOrder={sectionOrder} />;

  if (section === "basics") return (
    <div className="editor-inner">
      {ColLayoutTip}
      <div className="ed-head"><h2>Personal details</h2><p>The header of your résumé. Keep it to the essentials a recruiter needs to reach you.</p></div>
      <Field label="Photo" hint="optional"><PhotoUpload value={data.basics.photo} onChange={(v) => setBasics("photo", v)} /></Field>
      <Field label="Full name"><TextIn value={data.basics.name} onChange={(v) => setBasics("name", v)} placeholder="Jane Doe" /></Field>
      <Field label="Job title / target role"><TextIn value={data.basics.title} onChange={(v) => setBasics("title", v)} placeholder="Senior Product Designer" /></Field>
      <div className="row2">
        <Field label="Email"><TextIn value={data.basics.email} onChange={(v) => setBasics("email", v)} placeholder="you@email.com" /></Field>
        <Field label="Phone"><TextIn value={data.basics.phone} onChange={(v) => setBasics("phone", v)} placeholder="(555) 000-0000" /></Field>
      </div>
      <Field label="Location"><TextIn value={data.basics.location} onChange={(v) => setBasics("location", v)} placeholder="City, State" /></Field>
      <Field label="Website / portfolio" hint="optional"><TextIn value={data.basics.website} onChange={(v) => setBasics("website", v)} placeholder="yoursite.com" /></Field>
      <Field label="LinkedIn" hint="optional"><TextIn value={data.basics.linkedin} onChange={(v) => setBasics("linkedin", v)} placeholder="linkedin.com/in/yourname" /></Field>
      <NextBtn section="basics" setSection={setSection} />
    </div>);


  if (section === "summary") return (
    <div className="editor-inner">
      <div className="ed-head"><h2>Professional summary</h2><p>2–4 sentences framing who you are, your seniority, and one or two proof points. Mirror the job description's language.</p></div>
      <Field><Area value={data.summary} onChange={(v) => patch((d) => ({ ...d, summary: v }))} placeholder="Product designer with 7+ years…" /></Field>
      {aiHelpers && (
        <>
          <button className="btn btn-soft btn-sm ai-inline-btn" style={{ marginTop: 8, opacity: (!data.summary ? 0.45 : 1) }}
            disabled={!!(aiHelpers && aiHelpers.summaryBusy) || !data.summary}
            onClick={() => { setHasTriedAI(true); aiHelpers && aiHelpers.rewriteSummary(); }}>
            {(aiHelpers && aiHelpers.summaryBusy)
              ? <><span className="spin" style={{ width: 13, height: 13, borderColor: "rgba(28,155,230,.25)", borderTopColor: "var(--brand-blue)" }} /> Rewriting…</>
              : <><Icon name="writeai" size={13} /> Rewrite with AI</>}

          </button>
        </>
      )}
      <div className="tip" style={{ marginTop: aiHelpers ? 10 : 4 }}>
        <div className="t"><Icon name="sparkle" size={15} style={{ color: "var(--brand-blue)" }} /> Tip</div>
        <p>Lead with your strongest, most quantified achievement. Avoid first-person pronouns and buzzwords like "results-driven."</p>
      </div>
      <NextBtn section="summary" setSection={setSection} />
    </div>);


  if (section === "experience") return (
    <div className="editor-inner">
      <div className="ed-head"><h2>Work experience</h2><p>List roles newest first. Each bullet should start with an action verb and, where possible, include a metric.</p></div>
      {(data.experience || []).map((x) =>
      <Entry key={x.id} open={!!openIds[x.id]} onToggle={() => toggle(x.id)}
      title={x.role || "New role"} sub={[x.company, x.start && `${x.start} – ${x.end}`].filter(Boolean).join(" · ")}
      onDelete={() => listDel("experience", x.id)} onDuplicate={() => listDup("experience", x.id)}>
          <div className="row2">
            <Field label="Job title"><TextIn value={x.role} onChange={(v) => listSet("experience", x.id, "role", v)} placeholder="Product Designer" /></Field>
            <Field label="Company"><TextIn value={x.company} onChange={(v) => listSet("experience", x.id, "company", v)} placeholder="Company" /></Field>
          </div>
          <div className="row3">
            <Field label="Location"><TextIn value={x.location} onChange={(v) => listSet("experience", x.id, "location", v)} placeholder="City" /></Field>
            <Field label="Start"><TextIn value={x.start} onChange={(v) => listSet("experience", x.id, "start", v)} placeholder={NOW_MY} /></Field>
            <Field label="End"><TextIn value={x.end} onChange={(v) => listSet("experience", x.id, "end", v)} placeholder="Present" /></Field>
          </div>
          <BulletEditor bullets={x.bullets} onChange={(n) => listSet("experience", x.id, "bullets", n)} aiCtx={{ role: x.role, company: x.company }} aiHelpers={aiHelpers} />
        </Entry>
      )}
      <button className="add-btn" onClick={() => {const id = uid();listAdd("experience", { id, role: "", company: "", location: "", start: "", end: "", bullets: [""] });setOpenIds({ [id]: true });}}>
        <Icon name="plus" size={16} /> Add role
      </button>
      <NextBtn section="experience" setSection={setSection} />
    </div>);


  if (section === "projects") return (
    <div className="editor-inner">
      <div className="ed-head"><h2>Projects</h2><p>Optional. Great for side projects, open source, or portfolio-worthy work that isn't a full job.</p></div>
      {(data.projects || []).map((x) =>
      <Entry key={x.id} open={!!openIds[x.id]} onToggle={() => toggle(x.id)}
      title={x.name || "New project"} sub={x.tech}
      onDelete={() => listDel("projects", x.id)} onDuplicate={() => listDup("projects", x.id)}>
          <div className="row2">
            <Field label="Project name"><TextIn value={x.name} onChange={(v) => listSet("projects", x.id, "name", v)} placeholder="Project" /></Field>
            <Field label="Tech / context" hint="optional"><TextIn value={x.tech} onChange={(v) => listSet("projects", x.id, "tech", v)} placeholder="React · Node" /></Field>
          </div>
          <Field label="One-line description">
            <div style={{ display: "flex", gap: 6, alignItems: "flex-start" }}>
              <TextIn value={x.detail} onChange={(v) => listSet("projects", x.id, "detail", v)} placeholder="What it is" />
              <AITextBtn value={x.detail} onChange={(v) => listSet("projects", x.id, "detail", v)}
                prompt={"Improve this one-line project description to be concise, specific, and impactful. Mention measurable outcomes if possible. Project: " + (x.name || "a project")}
                aiHelpers={aiHelpers} />
            </div>
          </Field>
          <BulletEditor bullets={x.bullets} onChange={(n) => listSet("projects", x.id, "bullets", n)} aiCtx={{ role: x.name, company: "a project" }} aiHelpers={aiHelpers} />
        </Entry>
      )}
      <button className="add-btn" onClick={() => {const id = uid();listAdd("projects", { id, name: "", tech: "", detail: "", bullets: [""] });setOpenIds({ [id]: true });}}>
        <Icon name="plus" size={16} /> Add project
      </button>
      <NextBtn section="projects" setSection={setSection} />
    </div>);


  if (section === "education") return (
    <div className="editor-inner">
      <div className="ed-head"><h2>Education</h2><p>Degrees, certifications-in-progress, or relevant coursework.</p></div>
      {(data.education || []).map((x) =>
      <Entry key={x.id} open={!!openIds[x.id]} onToggle={() => toggle(x.id)}
      title={x.school || "New school"} sub={x.degree}
      onDelete={() => listDel("education", x.id)} onDuplicate={() => listDup("education", x.id)}>
          <div className="row2">
            <Field label="School"><TextIn value={x.school} onChange={(v) => listSet("education", x.id, "school", v)} placeholder="University" /></Field>
            <Field label="Degree"><TextIn value={x.degree} onChange={(v) => listSet("education", x.id, "degree", v)} placeholder="BSc, Computer Science" /></Field>
          </div>
          <div className="row3">
            <Field label="Location"><TextIn value={x.location} onChange={(v) => listSet("education", x.id, "location", v)} placeholder="City" /></Field>
            <Field label="Start"><TextIn value={x.start} onChange={(v) => listSet("education", x.id, "start", v)} placeholder="2013" /></Field>
            <Field label="End"><TextIn value={x.end} onChange={(v) => listSet("education", x.id, "end", v)} placeholder="2017" /></Field>
          </div>
          <Field label="Details" hint="optional">
            <div style={{ display: "flex", gap: 6, alignItems: "flex-start" }}>
              <TextIn value={x.detail} onChange={(v) => listSet("education", x.id, "detail", v)} placeholder="Honors, GPA, awards" />
              <AITextBtn value={x.detail} onChange={(v) => listSet("education", x.id, "detail", v)}
                prompt={"Improve this education detail to highlight academic achievements, honors, or relevant coursework concisely. Degree: " + (x.degree || "") + " at " + (x.school || "")}
                aiHelpers={aiHelpers} />
            </div>
          </Field>
        </Entry>
      )}
      <button className="add-btn" onClick={() => {const id = uid();listAdd("education", { id, school: "", degree: "", location: "", start: "", end: "", detail: "" });setOpenIds({ [id]: true });}}>
        <Icon name="plus" size={16} /> Add education
      </button>
      <NextBtn section="education" setSection={setSection} />
    </div>);


  if (section === "skills") return (
    <div className="editor-inner">
      <div className="ed-head"><h2>Skills</h2><p>Group related skills. These are prime keyword real-estate for ATS matching — mirror the job posting.</p></div>
      {(data.skills || []).map((g) =>
      <div className="entry open" key={g.id} style={{ padding: "14px 15px 16px" }}>
          <div style={{ display: "flex", gap: 10, alignItems: "center", marginBottom: 12 }}>
            <input className="inp" style={{ maxWidth: 200, fontWeight: 650 }} value={g.group}
          placeholder='e.g. "Frontend"' onChange={(e) => listSet("skills", g.id, "group", e.target.value)} />
            <button className="icon-btn danger" style={{ marginLeft: "auto" }} onClick={() => listDel("skills", g.id)}><Icon name="trash" size={16} /></button>
          </div>
          <ChipEditor items={g.items} onChange={(n) => listSet("skills", g.id, "items", n)} />
        </div>
      )}
      <button className="add-btn" onClick={() => listAdd("skills", { id: uid(), group: "", items: [] })}>
        <Icon name="plus" size={16} /> Add skill group
      </button>
      <NextBtn section="skills" setSection={setSection} />
    </div>);


  if (section === "certs") return (
    <div className="editor-inner">
      <div className="ed-head"><h2>Certifications</h2><p>Professional certifications, licenses, or notable awards.</p></div>
      {(data.certs || []).map((c, i) =>
      <div className="bullet" key={i}>
          <span className="dot" />
          <input className="inp" value={c} placeholder="Certification — Issuer (Year)"
        onChange={(e) => patch((d) => {const n = [...(d.certs || [])];n[i] = e.target.value;return { ...d, certs: n };})} />
          <button className="icon-btn danger rm" onClick={() => patch((d) => ({ ...d, certs: (d.certs || []).filter((_, j) => j !== i) }))}><Icon name="x" size={15} /></button>
        </div>
      )}
      <button className="add-btn" style={{ marginTop: 6 }} onClick={() => patch((d) => ({ ...d, certs: [...(d.certs || []), ""] }))}>
        <Icon name="plus" size={16} /> Add certification
      </button>
      <div style={{ marginTop: 28, paddingTop: 20, borderTop: "1px solid var(--slate-100)", display: "flex", flexDirection: "column", alignItems: "center", gap: 8, textAlign: "center" }}>
        <div style={{ fontSize: 22 }}>🎉</div>
        <div style={{ fontWeight: 700, fontSize: 15, color: "var(--navy)" }}>Your résumé is ready!</div>
        <div style={{ fontSize: 13, color: "var(--slate-500)", marginBottom: 4 }}>Check your ATS score, then download your PDF.</div>
      </div>
    </div>);


  if (section === "languages") return (
    <div className="editor-inner">
      <div className="ed-head"><h2>Languages</h2><p>List languages you speak and your proficiency level.</p></div>
      {(data.languages || []).map((l, i) => (
        <div className="ed-row" key={i} style={{ display: "flex", gap: 8, alignItems: "flex-start" }}>
          <div style={{ flex: 2 }}>
            <Field label="Language">
              <TextIn value={l.lang} onChange={v => patch(d => { const n = [...(d.languages||[])]; n[i] = {...n[i], lang: v}; return {...d, languages: n}; })} placeholder="e.g. English" />
            </Field>
          </div>
          <div style={{ flex: 1 }}>
            <Field label="Proficiency">
              <select className="inp" value={l.level} onChange={e => patch(d => { const n = [...(d.languages||[])]; n[i] = {...n[i], level: e.target.value}; return {...d, languages: n}; })}>
                <option value="">Select…</option>
                <option>Native</option>
                <option>Fluent</option>
                <option>Advanced</option>
                <option>Intermediate</option>
                <option>Basic</option>
              </select>
            </Field>
          </div>
          <button className="icon-btn danger rm" style={{ marginTop: 22 }} onClick={() => patch(d => ({ ...d, languages: (d.languages||[]).filter((_,j) => j !== i) }))}><Icon name="x" size={15} /></button>
        </div>
      ))}
      <button className="add-btn" style={{ marginTop: 6 }} onClick={() => patch(d => ({ ...d, languages: [...(d.languages||[]), { lang: "", level: "" }] }))}>
        <Icon name="plus" size={16} /> Add language
      </button>
    </div>
  );

  if (section === "activities") return (
    <div className="editor-inner">
      <div className="ed-head"><h2>Extracurricular Activities</h2><p>Clubs, sports, volunteering, leadership roles outside work.</p></div>
      {(data.activities || []).map((a, i) => (
        <div className="exp-block" key={i}>
          <div className="exp-block-head">
            <span className="exp-block-num">{i + 1}</span>
            <button className="icon-btn danger rm" onClick={() => patch(d => ({ ...d, activities: (d.activities||[]).filter((_,j) => j !== i) }))}><Icon name="x" size={15} /></button>
          </div>
          <Field label="Activity / Role"><TextIn value={a.title} onChange={v => patch(d => { const n=[...(d.activities||[])]; n[i]={...n[i],title:v}; return {...d,activities:n}; })} placeholder="e.g. Team Captain" /></Field>
          <Field label="Organization"><TextIn value={a.org} onChange={v => patch(d => { const n=[...(d.activities||[])]; n[i]={...n[i],org:v}; return {...d,activities:n}; })} placeholder="e.g. University Football Club" /></Field>
          <Field label="Dates"><TextIn value={a.dates} onChange={v => patch(d => { const n=[...(d.activities||[])]; n[i]={...n[i],dates:v}; return {...d,activities:n}; })} placeholder="e.g. 2019 - 2022" /></Field>
          <Field label="Details (optional)">
            <div style={{ display: "flex", gap: 6, alignItems: "flex-start" }}>
              <textarea className="inp" rows={3} value={a.detail||""} placeholder="Describe achievements or responsibilities…"
                onChange={e => patch(d => { const n=[...(d.activities||[])]; n[i]={...n[i],detail:e.target.value}; return {...d,activities:n}; })} />
              <AITextBtn value={a.detail} onChange={v => patch(d => { const n=[...(d.activities||[])]; n[i]={...n[i],detail:v}; return {...d,activities:n}; })}
                prompt={"Improve this extracurricular activity description. Include quantifiable impact, leadership, or skills demonstrated. Role: " + (a.title||"") + " at " + (a.org||"")}
                aiHelpers={aiHelpers} />
            </div>
          </Field>
        </div>
      ))}
      <button className="add-btn" style={{ marginTop: 6 }} onClick={() => patch(d => ({ ...d, activities: [...(d.activities||[]), { title:"", org:"", dates:"", detail:"" }] }))}>
        <Icon name="plus" size={16} /> Add activity
      </button>
    </div>
  );

  if (section === "profdegrees") return (
    <div className="editor-inner">
      <div className="ed-head"><h2>Professional Credentials</h2><p>CA, CMA, CPA, PMP, CFA and other professional designations.</p></div>
      {(data.profdegrees || []).map((c, i) => (
        <div className="bullet" key={i}>
          <span className="dot" />
          <input className="inp" value={c} placeholder="e.g. CA - ICAB (2021)"
            onChange={e => patch(d => { const n=[...(d.profdegrees||[])]; n[i]=e.target.value; return {...d,profdegrees:n}; })} />
          <button className="icon-btn danger rm" onClick={() => patch(d => ({ ...d, profdegrees: (d.profdegrees||[]).filter((_,j) => j !== i) }))}><Icon name="x" size={15} /></button>
        </div>
      ))}
      <button className="add-btn" style={{ marginTop: 6 }} onClick={() => patch(d => ({ ...d, profdegrees: [...(d.profdegrees||[]), ""] }))}>
        <Icon name="plus" size={16} /> Add credential
      </button>
    </div>
  );

  if (section === "references") return (
    <div className="editor-inner">
      <div className="ed-head"><h2>References</h2><p>Professional references or select "Available upon request".</p></div>
      <label style={{ display:"flex", alignItems:"center", gap:10, marginBottom:16, cursor:"pointer", fontSize:13.5 }}>
        <input type="checkbox" checked={!!(data.refsOnRequest)}
          onChange={e => patch(d => ({ ...d, refsOnRequest: e.target.checked }))} />
        Show "Available upon request" only
      </label>
      {!data.refsOnRequest && (data.references || []).map((r, i) => (
        <div className="exp-block" key={i}>
          <div className="exp-block-head">
            <span className="exp-block-num">{i + 1}</span>
            <button className="icon-btn danger rm" onClick={() => patch(d => ({ ...d, references: (d.references||[]).filter((_,j) => j !== i) }))}><Icon name="x" size={15} /></button>
          </div>
          <Field label="Name"><TextIn value={r.name} onChange={v => patch(d => { const n=[...(d.references||[])]; n[i]={...n[i],name:v}; return {...d,references:n}; })} placeholder="Full name" /></Field>
          <Field label="Title"><TextIn value={r.title} onChange={v => patch(d => { const n=[...(d.references||[])]; n[i]={...n[i],title:v}; return {...d,references:n}; })} placeholder="Job title" /></Field>
          <Field label="Company"><TextIn value={r.company} onChange={v => patch(d => { const n=[...(d.references||[])]; n[i]={...n[i],company:v}; return {...d,references:n}; })} placeholder="Company name" /></Field>
          <Field label="Email"><TextIn value={r.email} onChange={v => patch(d => { const n=[...(d.references||[])]; n[i]={...n[i],email:v}; return {...d,references:n}; })} placeholder="email@example.com" /></Field>
          <Field label="Phone"><TextIn value={r.phone} onChange={v => patch(d => { const n=[...(d.references||[])]; n[i]={...n[i],phone:v}; return {...d,references:n}; })} placeholder="+1 555 000 0000" /></Field>
        </div>
      ))}
      {!data.refsOnRequest && (
        <button className="add-btn" style={{ marginTop: 6 }} onClick={() => patch(d => ({ ...d, references: [...(d.references||[]), { name:"", title:"", company:"", email:"", phone:"" }] }))}>
          <Icon name="plus" size={16} /> Add reference
        </button>
      )}
    </div>
  );

  if (section && section.startsWith("custom:")) {
    const id = section.slice(7);
    const item = (data.custom || []).find((x) => x.id === id);
    if (!item) return null;
    return (
      <div className="editor-inner">
        <div className="ed-head"><h2>Custom section</h2><p>Add anything the standard sections don't cover — Publications, Volunteering, Languages, Awards, a personal statement. It renders in your résumé exactly where you'd expect.</p></div>
        <Field label="Section heading"><TextIn value={item.heading} onChange={(v) => listSet("custom", id, "heading", v)} placeholder="e.g. Publications" /></Field>
        <Field label="Content">
          <div style={{ position: "relative" }}>
            <RichText value={item.body} onChange={(v) => listSet("custom", id, "body", v)}
              placeholder="Write here… use the toolbar for bold, italics, and bullet lists." />
            <div style={{ marginTop: 6 }}>
              <AITextBtn value={(item.body || "").replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim()}
                onChange={(v) => listSet("custom", id, "body", v)}
                prompt={"Improve this custom résumé section content. Make it concise, professional, and impactful. Section: " + (item.heading || "Custom")}
                aiHelpers={aiHelpers} />
            </div>
          </div>
        </Field>
        <button className="btn btn-ghost btn-sm danger-btn" style={{ marginTop: 6 }}
          onClick={() => { listDel("custom", id); setSection("basics"); }}>
          <Icon name="trash" size={14} /> Delete section
        </button>
      </div>
    );
  }

  return null;
}
Object.assign(window, { Editor });