/* global React, Icons, AI, AutoText, Field, Section, PROFILE_RESUMES, PROFILE_LETTERS, COVER_TEMPLATES, getProfile, ExportButton, PdfButton, Pro */
// ============================================================
//  Cover letters — renderer (CoverPaper) + editor (CoverScreen)
//  A cover-letter template is a layout descriptor in profiles.jsx
//  (COVER_TEMPLATES). The same accent system as résumés drives color
//  via --pa / --pa2. Content lives in a "cover doc" (see makeCoverDoc).
// ============================================================
const { useState: useStateCL, useEffect: useEffectCL, useRef: useRefCL } = React;

const initialsCL = (name) => (name || "?").trim().split(" ").map((w) => w[0]).slice(0, 2).join("").toUpperCase();

// build a default cover doc from a profile's résumé + draft copy
function makeCoverDoc(profileId) {
  const r = PROFILE_RESUMES[profileId] || {};
  const l = PROFILE_LETTERS[profileId] || {};
  return {
    profileId,
    name: r.name || "Your Name",
    title: r.title || "",
    email: r.email || "", phone: r.phone || "", location: r.location || "", website: r.website || "",
    date: "June 3, 2026",
    recipientName: l.manager || "Hiring Manager",
    recipientTitle: l.managerTitle || "",
    company: l.company || "Company",
    role: l.role || r.title || "the role",
    greeting: l.manager ? `Dear ${l.manager},` : "Dear Hiring Manager,",
    paras: (l.paras && l.paras.length) ? [...l.paras] : [""],
    closing: "Sincerely,",
    signoff: r.name || "Your Name",
  };
}

// ---- sender identity block (varies subtly by layout) ----
function CoverContacts({ d }) {
  const items = [
    ["mail", "email", d.email], ["phone", "phone", d.phone], ["pin", "location", d.location], ["globe", "website", d.website],
  ].filter(([, , v]) => v);
  return (
    <div className="cl-contacts">
      {items.map(([ic, field, v], i) => {
        const Ic = Icons[ic] || Icons.tag;
        return <span key={i} className="cl-contact"><Ic size={12} /><span data-edit={field}>{v}</span></span>;
      })}
    </div>
  );
}

function CoverHeader({ d, layout }) {
  const parts = (d.name || "").split(" ");
  if (layout === "bold") {
    return (
      <header className="cl-head cl-head-bold">
        <div className="cl-band">
          <h1 className="cl-name" data-edit="name">{d.name}</h1>
          {d.title && <div className="cl-title" data-edit="title">{d.title}</div>}
          <CoverContacts d={d} />
        </div>
      </header>
    );
  }
  if (layout === "executive") {
    return (
      <header className="cl-head cl-head-exec">
        <span className="cl-mono">{initialsCL(d.name)}</span>
        <div className="cl-exec-txt">
          <h1 className="cl-name" data-edit="name">{d.name}</h1>
          {d.title && <div className="cl-title" data-edit="title">{d.title}</div>}
        </div>
        <div className="cl-exec-c"><CoverContacts d={d} /></div>
      </header>
    );
  }
  if (layout === "creative") {
    return (
      <header className="cl-head cl-head-creative">
        <h1 className="cl-name" data-edit="name">
          <span className="cl-n1">{parts[0]}</span>
          {parts.length > 1 && <span className="cl-n2"> {parts.slice(1).join(" ")}</span>}
        </h1>
        {d.title && <div className="cl-title" data-edit="title">{d.title}</div>}
        <CoverContacts d={d} />
      </header>
    );
  }
  if (layout === "minimal") {
    return (
      <header className="cl-head cl-head-min">
        <h1 className="cl-name" data-edit="name">{d.name}</h1>
        <CoverContacts d={d} />
      </header>
    );
  }
  if (layout === "dark") {
    return (
      <header className="cl-head cl-head-dark">
        <h1 className="cl-name" data-edit="name">{d.name}</h1>
        {d.title && <div className="cl-title" data-edit="title">{d.title}</div>}
        <CoverContacts d={d} />
      </header>
    );
  }
  if (layout === "mono") {
    return (
      <header className="cl-head cl-head-mono">
        <div className="cl-mono-tag">// cover-letter.txt</div>
        <h1 className="cl-name" data-edit="name">{d.name}</h1>
        {d.title && <div className="cl-title" data-edit="title">{d.title}</div>}
        <CoverContacts d={d} />
      </header>
    );
  }
  // classic (centered)
  return (
    <header className="cl-head cl-head-classic">
      <h1 className="cl-name" data-edit="name">{d.name}</h1>
      {d.title && <div className="cl-title" data-edit="title">{d.title}</div>}
      <CoverContacts d={d} />
    </header>
  );
}

function CoverBody({ d }) {
  return (
    <div className="cl-body">
      <div className="cl-meta">
        <div className="cl-date" data-edit="date">{d.date}</div>
        <div className="cl-to">
          {d.recipientName && <span className="cl-to-n" data-edit="recipientName">{d.recipientName}</span>}
          {d.recipientTitle && <span data-edit="recipientTitle">{d.recipientTitle}</span>}
          {d.company && <span className="cl-to-co" data-edit="company">{d.company}</span>}
        </div>
      </div>
      {d.role && <div className="cl-re">Re: <span data-edit="role">{d.role}</span></div>}
      <p className="cl-greeting" data-edit="greeting">{d.greeting}</p>
      <div className="cl-paras">
        {(d.paras || []).map((p, i) => (p && p.trim() ? <p key={i} data-edit={`para:${i}`}>{p}</p> : null))}
      </div>
      <div className="cl-sign">
        <p className="cl-closing" data-edit="closing">{d.closing}</p>
        <p className="cl-signoff" data-edit="signoff">{d.signoff}</p>
      </div>
    </div>
  );
}

function CoverPaper({ doc, templateId, style, accent, accent2 }) {
  const base = style || (COVER_TEMPLATES.find((t) => t.id === templateId)) || COVER_TEMPLATES[0];
  const layout = base.layout;
  const sv = { "--pa": accent || base.accent, "--pa2": accent2 || base.accent2 };
  const sidebar = layout === "modern";
  const serifCls = base.serif === true ? "cover-serif" : base.serif === false ? "cover-sans" : "";
  return (
    <div className={`cover cover-${layout} ${serifCls} ${base.id ? "ctpl-" + base.id : ""}`} style={sv}>
      {sidebar ? (
        <div className="cl-cols">
          <aside className="cl-rail">
            <h1 className="cl-name" data-edit="name">{doc.name}</h1>
            {doc.title && <div className="cl-title" data-edit="title">{doc.title}</div>}
            <div className="cl-rail-c"><CoverContacts d={doc} /></div>
          </aside>
          <main className="cl-main"><CoverBody d={doc} /></main>
        </div>
      ) : (
        <>
          <CoverHeader d={doc} layout={layout} />
          <CoverBody d={doc} />
        </>
      )}
    </div>
  );
}

// Derive a cover-letter style that mirrors a résumé template's design language
// (header archetype, serif/sans voice, accent colors) so the appended cover
// page reads as page 3 of the same document — not a separate design.
function coverStyleForTemplate(t, accent, accent2) {
  if (!t) return { id: "auto", layout: "classic", serif: true, accent, accent2 };
  const head = t.head || "";
  const serifHeads = new Set(["ibank", "serifCenter", "exec", "cv", "legal", "editorial", "formal", "ruled"]);
  const bandHeads = new Set(["band", "banner", "vivid", "techband", "warmband", "card"]);
  const classicHeads = new Set(["ibank", "serifCenter", "cv", "legal", "formal", "centered", "ruled", "clinical", "ruledpro", "timeline"]);
  const minimalHeads = new Set(["ats", "swiss", "labeled", "designer"]);
  let layout;
  if (head === "dark" || t.id === "onyx") layout = "dark";
  else if (head === "codecard" || t.id === "terminal") layout = "mono";
  else if (t.arch === "sidebar") layout = "modern";
  else if (head === "exec") layout = "executive";
  else if (bandHeads.has(head)) layout = "bold";
  else if (head === "editorial") layout = "creative";
  else if (classicHeads.has(head)) layout = "classic";
  else if (minimalHeads.has(head)) layout = "minimal";
  else layout = serifHeads.has(head) ? "classic" : "minimal";
  const serif = serifHeads.has(head) || layout === "classic" || layout === "executive";
  return {
    id: "auto-" + t.id, layout, serif: layout === "mono" ? undefined : serif,
    accent: accent || t.accent, accent2: accent2 || t.accent2,
  };
}

// scale a 768px cover paper to fit a container (gallery thumbs)
function CoverFit({ doc, templateId, designWidth = 768 }) {
  const ref = useRefCL(null);
  const [scale, setScale] = useStateCL(0.4);
  useEffectCL(() => {
    const el = ref.current; if (!el) return;
    const fit = () => setScale((el.clientWidth || designWidth * 0.4) / designWidth);
    fit();
    const ro = new ResizeObserver(fit);
    ro.observe(el);
    return () => ro.disconnect();
  }, [designWidth]);
  return (
    <div ref={ref} style={{ position: "absolute", inset: 0, overflow: "hidden" }}>
      <div style={{ transform: `scale(${scale})`, transformOrigin: "top left", width: designWidth }}>
        <CoverPaper doc={doc} templateId={templateId} />
      </div>
    </div>
  );
}

// ============================================================
//  Cover-letter editor screen
// ============================================================
// which form section controls each editable field on the letter
const COVER_FIELD_SEC = {
  name: "details", title: "details", email: "details", phone: "details", location: "details", website: "details",
  date: "role", recipientName: "role", recipientTitle: "role", company: "role", role: "role",
  greeting: "letter", closing: "letter", signoff: "letter",
};

function CoverScreen({ doc, setDoc, templateId, setTemplateId, accent, setAccent, onBack }) {
  const tpl = COVER_TEMPLATES.find((t) => t.id === templateId) || COVER_TEMPLATES[0];
  const [busy, setBusy] = useStateCL(false);
  const [toast, setToast] = useStateCL("");
  const [zoom, setZoom] = useStateCL(0.8);
  const [paperH, setPaperH] = useStateCL(900);
  const stageRef = useRefCL(null);
  const innerRef = useRefCL(null);
  const editingRef = useRefCL(false);   // true while an inline edit is focused

  const flash = (m) => { setToast(m); setTimeout(() => setToast(""), 2600); };
  const pa = accent.custom ? accent : { a: tpl.accent, b: tpl.accent2 };

  // ---- inline editing on the letter + click-to-locate the form section ----
  const commitCover = (path, val) => {
    setDoc((x) => {
      const d = { ...x };
      if (path.startsWith("para:")) {
        const i = Number(path.split(":")[1]);
        d.paras = (d.paras || []).map((p, j) => (j === i ? val : p));
      } else { d[path] = val; }
      return d;
    });
  };
  const onCoverMouseDown = (e) => {
    if (!e.target.closest(".cover")) return;
    const ed = e.target.closest("[data-edit]");
    const path = ed ? ed.getAttribute("data-edit") : null;
    if (path) {
      const sec = path.startsWith("para") ? "letter" : COVER_FIELD_SEC[path];
      if (sec) window.dispatchEvent(new CustomEvent("rb-focus-section", { detail: { key: sec } }));
    }
    if (!ed || ed.getAttribute("contenteditable") === "true") return;
    const orig = ed.textContent;
    const multi = path === "greeting" || path.startsWith("para");
    ed.setAttribute("contenteditable", "true");
    ed.classList.add("rb-edit-on");
    editingRef.current = true;
    const finish = () => {
      ed.removeEventListener("blur", finish);
      ed.removeEventListener("keydown", onKey);
      ed.removeAttribute("contenteditable");
      ed.classList.remove("rb-edit-on");
      editingRef.current = false;
      const val = ed.textContent.replace(/\u00a0/g, " ").replace(/[ \t]+/g, " ").trim();
      if (val !== orig.trim()) commitCover(path, val);
    };
    const onKey = (ev) => {
      if (ev.key === "Enter" && !(multi && ev.shiftKey)) { ev.preventDefault(); ed.blur(); }
      else if (ev.key === "Escape") { ev.preventDefault(); ed.textContent = orig; ed.blur(); }
    };
    ed.addEventListener("blur", finish);
    ed.addEventListener("keydown", onKey);
  };

  useEffectCL(() => {
    const fit = () => {
      const stage = stageRef.current; if (!stage) return;
      const avail = stage.clientWidth - 56;
      setZoom(Math.min(0.95, Math.max(0.3, avail / 768)));
    };
    fit();
    const ro = new ResizeObserver(fit);
    if (stageRef.current) ro.observe(stageRef.current);
    return () => ro.disconnect();
  }, []);

  useEffectCL(() => {
    const el = innerRef.current; if (!el) return;
    const measure = () => { if (editingRef.current) return; setPaperH(el.offsetHeight || 900); };
    measure();
    const ro = new ResizeObserver(measure);
    ro.observe(el);
    return () => ro.disconnect();
  }, [templateId, doc]);

  const set = (patch) => setDoc((x) => ({ ...x, ...patch }));
  const setPara = (i, v) => set({ paras: doc.paras.map((p, x) => x === i ? v : p) });
  const addPara = () => set({ paras: [...doc.paras, ""] });
  const delPara = (i) => set({ paras: doc.paras.filter((_, x) => x !== i) });

  const aiWrite = async () => {
    if (!Pro.guardAI()) return;
    setBusy(true);
    const r = PROFILE_RESUMES[doc.profileId] || {};
    const exp = (r.experience || [])[0] || {};
    const prompt = `Write a professional cover letter body of exactly 3 paragraphs for a job application.
Applicant: ${doc.name}, ${doc.title}.
Applying for: ${doc.role} at ${doc.company}.
Key achievements to weave in: ${(exp.bullets || []).slice(0, 3).join(" ")}
Top skills: ${(r.skills || []).map((s) => (s && s.name) || s).slice(0, 6).join(", ")}.
Tone: confident, specific, not generic. Include real metrics from the achievements.
Return ONLY the 3 paragraphs separated by a blank line — no greeting, no sign-off, no preamble.`;
    const out = await AI.run(prompt);
    setBusy(false);
    if (out) {
      const paras = out.split(/\n\s*\n/).map((s) => s.trim()).filter(Boolean);
      set({ paras: paras.length ? paras : doc.paras });
      Pro.recordAI();
      flash("Cover letter drafted with AI");
    } else flash("Couldn't reach AI — try again");
  };

  const accentOptions = [
    { a: "#1f3a5f", b: "#5a7a9c" }, { a: "#4f46e5", b: "#06b6d4" },
    { a: "#ef5b2b", b: "#ffb020" }, { a: "#7c3aed", b: "#06b6d4" },
    { a: "#111111", b: "#6b6b6b" }, { a: "#117a8b", b: "#3aa7a0" },
  ];

  return (
    <div className="cover-screen">
      <div className="b-toolbar">
        <button className="btn btn-quiet btn-sm" onClick={onBack}><Icons.arrowL size={15} /> Cover letters</button>
        <div className="b-tool-mid">
          <div className="tpl-switch">
            <Icons.layers size={15} style={{ color: "var(--ink-3)" }} />
            <select value={templateId} onChange={(e) => setTemplateId(e.target.value)}>
              {COVER_TEMPLATES.map((t) => <option key={t.id} value={t.id}>{t.name}</option>)}
            </select>
          </div>
          <div className="accent-row">
            {accentOptions.map((o, i) => (
              <button key={i} className={`acc-sw ${pa.a === o.a ? "on" : ""}`}
                style={{ background: `linear-gradient(135deg, ${o.a}, ${o.b})` }}
                onClick={() => setAccent({ ...o, custom: true })} title="Accent" />
            ))}
            <button className={`acc-sw reset ${!accent.custom ? "on" : ""}`} title="Match template"
              onClick={() => setAccent({ custom: false })}><Icons.refresh size={12} /></button>
          </div>
        </div>
        <div className="b-tool-end">
          <button className={`ai-chip ${busy ? "busy" : ""}`} onClick={aiWrite} disabled={busy}>
            {busy ? <Icons.refresh size={13} className="spin" /> : <Icons.magic size={13} />}
            {busy ? "Writing…" : "Write with AI"}
          </button>
          <PdfButton getNode={() => innerRef.current}
            fileName={`${(doc.name || "Cover Letter").trim()} — Cover Letter`} reason="cover" />
        </div>
      </div>

      <div className="b-panels">
        <div className="b-form">
          <div className="form-scroll">
            <div className="form-intro">
              <h2>Write your cover letter</h2>
              <p>Pre-filled to match your profile. <b>Click any line on the letter</b> to edit it in place — clicking also jumps to its controls here. Or hit <Icons.magic size={13} style={{ verticalAlign: "-2px", color: "var(--acc)" }} /> to redraft the body with AI.</p>
            </div>

            <Section icon={Icons.brief} title="The role" secKey="role">
              <Field label="Role / position" value={doc.role} onChange={(v) => set({ role: v })} />
              <Field label="Company" value={doc.company} onChange={(v) => set({ company: v })} />
              <div className="grid-2">
                <Field label="Hiring manager" value={doc.recipientName} onChange={(v) => set({ recipientName: v, greeting: `Dear ${v},` })} />
                <Field label="Their title" value={doc.recipientTitle} onChange={(v) => set({ recipientTitle: v })} />
              </div>
              <Field label="Date" value={doc.date} onChange={(v) => set({ date: v })} />
            </Section>

            <Section icon={Icons.user} title="Your details" secKey="details">
              <Field label="Full name" value={doc.name} onChange={(v) => set({ name: v, signoff: v })} />
              <Field label="Headline" value={doc.title} onChange={(v) => set({ title: v })} />
              <div className="grid-2">
                <Field label="Email" value={doc.email} onChange={(v) => set({ email: v })} />
                <Field label="Phone" value={doc.phone} onChange={(v) => set({ phone: v })} />
              </div>
              <div className="grid-2">
                <Field label="Location" value={doc.location} onChange={(v) => set({ location: v })} />
                <Field label="Website" value={doc.website} onChange={(v) => set({ website: v })} />
              </div>
            </Section>

            <Section icon={Icons.pen} title="Letter" secKey="letter">
              <Field label="Greeting" value={doc.greeting} onChange={(v) => set({ greeting: v })} />
              <span className="field-l" style={{ marginTop: 8 }}>Body paragraphs</span>
              <div className="bullets">
                {doc.paras.map((p, i) => (
                  <div className="bullet-row" key={i}>
                    <span className="bullet-dot" />
                    <AutoText value={p} onChange={(v) => setPara(i, v)} placeholder="Write a paragraph…" />
                    <div className="bullet-tools">
                      <button className="bul-del" onClick={() => delPara(i)}><Icons.close size={13} /></button>
                    </div>
                  </div>
                ))}
                <button className="add-inline" onClick={addPara}><Icons.plus size={13} /> Add paragraph</button>
              </div>
              <div className="grid-2" style={{ marginTop: 10 }}>
                <Field label="Closing" value={doc.closing} onChange={(v) => set({ closing: v })} />
                <Field label="Sign-off name" value={doc.signoff} onChange={(v) => set({ signoff: v })} />
              </div>
            </Section>

            <div className="form-foot">
              <Icons.check size={14} style={{ color: "var(--acc)" }} /> Keep it to one page — you're set.
            </div>
          </div>
        </div>

        <div className="b-preview" ref={stageRef}>
          <div className="preview-bar">
            <span className="pv-name">{tpl.name}</span>
            <span className="pv-hint"><Icons.pen size={11} /> Click any text to edit</span>
            <span className="pv-zoom">{Math.round(zoom * 100)}%</span>
          </div>
          <div className="preview-scroll" onMouseDown={onCoverMouseDown}>
            <div className="preview-paper" style={{ width: 768 * zoom, height: paperH * zoom }}>
              <div ref={innerRef} style={{ transform: `scale(${zoom})`, transformOrigin: "top left", width: 768 }}>
                <CoverPaper doc={doc} templateId={templateId}
                  accent={pa.custom ? pa.a : undefined} accent2={pa.custom ? pa.b : undefined} />
              </div>
            </div>
          </div>
        </div>
      </div>

      {toast && <div className="toast glass"><Icons.spark size={14} style={{ color: "var(--acc)" }} /> {toast}</div>}
    </div>
  );
}

Object.assign(window, { CoverPaper, CoverFit, CoverScreen, makeCoverDoc, coverStyleForTemplate });
