"use client";

import { useEffect, useState, type ChangeEvent, type CSSProperties, type FormEvent } from "react";

type FontChoice = "editorial" | "modern" | "romantic";
type Alignment = "left" | "center";
type PaletteChoice = "ivory" | "blush" | "sage" | "stone" | "white";
type UploadedPdf = {
  id: string;
  fileName: string;
  sizeBytes: number;
  pageCount: number;
  widthMm: number;
  heightMm: number;
};

const presets = [
  {
    id: "forever",
    label: "Our forever",
    note: "The signature message",
    heading: "A PIECE OF OUR FOREVER",
    message: "A tiny diamond,\nas lasting as the love\nwe share with you.",
    footer: "THANK YOU FOR BEING A PART OF OUR STORY",
  },
  {
    id: "wedding",
    label: "Wedding of",
    note: "Names take centre stage",
    heading: "THE WEDDING OF",
    message: "A little sparkle to remember\nour most beautiful day.",
    footer: "WITH LOVE, ALWAYS",
  },
  {
    id: "token",
    label: "With love",
    note: "Warm and personal",
    heading: "A TOKEN OF OUR LOVE",
    message: "A tiny diamond for you,\nwith our heartfelt thanks\nfor sharing this day.",
    footer: "FOREVER BEGINS HERE",
  },
];

const palettes = {
  ivory: { card: "#f4efe5", ink: "#332a21", accent: "#a78349", label: "Ivory" },
  blush: { card: "#f2e7e4", ink: "#4c302d", accent: "#a7786d", label: "Blush" },
  sage: { card: "#e7ebe2", ink: "#28372d", accent: "#7b8b70", label: "Sage" },
  stone: { card: "#e8e5df", ink: "#2d2c2a", accent: "#898178", label: "Stone" },
  white: { card: "#ffffff", ink: "#27231f", accent: "#aa8952", label: "White" },
};

const fonts: Record<FontChoice, { label: string; stack: string }> = {
  editorial: { label: "Editorial serif", stack: "Georgia, 'Times New Roman', serif" },
  modern: { label: "Modern minimal", stack: "Arial, Helvetica, sans-serif" },
  romantic: { label: "Romantic classic", stack: "'Palatino Linotype', Palatino, serif" },
};

function formatDate(date: string) {
  if (!date) return "YOUR WEDDING DATE";
  return new Intl.DateTimeFormat("en-ZA", {
    day: "2-digit",
    month: "long",
    year: "numeric",
  }).format(new Date(`${date}T12:00:00`)).toUpperCase();
}

export default function PersonalisePage() {
  const [activePreset, setActivePreset] = useState("forever");
  const [partnerOne, setPartnerOne] = useState("Mark");
  const [partnerTwo, setPartnerTwo] = useState("Mandy");
  const [weddingDate, setWeddingDate] = useState("2027-03-20");
  const [heading, setHeading] = useState(presets[0].heading);
  const [message, setMessage] = useState(presets[0].message);
  const [footer, setFooter] = useState(presets[0].footer);
  const [font, setFont] = useState<FontChoice>("editorial");
  const [fontSize, setFontSize] = useState(100);
  const [alignment, setAlignment] = useState<Alignment>("center");
  const [palette, setPalette] = useState<PaletteChoice>("ivory");
  const [saveOpen, setSaveOpen] = useState(false);
  const [saveEmail, setSaveEmail] = useState("");
  const [saveStatus, setSaveStatus] = useState<"idle" | "saving" | "saved" | "error">("idle");
  const [saveMessage, setSaveMessage] = useState("");
  const [recoveryLink, setRecoveryLink] = useState("");
  const [recoveryOpen, setRecoveryOpen] = useState(false);
  const [recoveryEmail, setRecoveryEmail] = useState("");
  const [recoveryStatus, setRecoveryStatus] = useState<"idle" | "sending" | "sent" | "not-found" | "error">("idle");
  const [recoveryMessage, setRecoveryMessage] = useState("");
  const [resentLink, setResentLink] = useState("");
  const [shareOpen, setShareOpen] = useState(false);
  const [shareStatus, setShareStatus] = useState<"idle" | "creating" | "ready" | "error">("idle");
  const [shareLink, setShareLink] = useState("");
  const [shareMessage, setShareMessage] = useState("");
  const [restoreMessage, setRestoreMessage] = useState("");
  const [uploadedPdf, setUploadedPdf] = useState<UploadedPdf | null>(null);
  const [uploadStatus, setUploadStatus] = useState<"idle" | "uploading" | "uploaded" | "error">("idle");
  const [uploadMessage, setUploadMessage] = useState("");

  const coupleNames = `${partnerOne || "Partner one"} & ${partnerTwo || "Partner two"}`;
  const selectedPalette = palettes[palette];
  const cardStyle = {
    "--card-bg": selectedPalette.card,
    "--card-ink": selectedPalette.ink,
    "--card-accent": selectedPalette.accent,
    "--card-scale": fontSize / 100,
    "--card-font": fonts[font].stack,
    textAlign: alignment,
  } as CSSProperties;

  useEffect(() => {
    const storedUpload = sessionStorage.getItem("diamondVialUploadedDesign");
    if (storedUpload) {
      try {
        setUploadedPdf(JSON.parse(storedUpload) as UploadedPdf);
        setUploadStatus("uploaded");
      } catch {
        sessionStorage.removeItem("diamondVialUploadedDesign");
      }
    }

    const token = new URLSearchParams(window.location.search).get("token");
    if (!token) return;

    let cancelled = false;
    setRestoreMessage("Restoring your saved design…");
    fetch(`/api/designs?token=${encodeURIComponent(token)}`)
      .then(async (response) => {
        const result = await response.json() as {
          design?: {
            partnerOne: string;
            partnerTwo: string;
            weddingDate: string;
            heading: string;
            message: string;
            footer: string;
            font: FontChoice;
            fontSize: number;
            alignment: Alignment;
            palette: PaletteChoice;
          };
          email?: string;
          error?: string;
        };
        if (!response.ok || !result.design) throw new Error(result.error || "Unable to restore this design.");
        if (cancelled) return;

        const saved = result.design;
        setPartnerOne(saved.partnerOne);
        setPartnerTwo(saved.partnerTwo);
        setWeddingDate(saved.weddingDate);
        setHeading(saved.heading);
        setMessage(saved.message);
        setFooter(saved.footer);
        setFont(saved.font);
        setFontSize(saved.fontSize);
        setAlignment(saved.alignment);
        setPalette(saved.palette);
        setActivePreset("custom");
        setRestoreMessage(`Saved design restored for ${result.email || "your email"}.`);
        window.history.replaceState({}, "", "/personalise");
      })
      .catch((error: unknown) => {
        if (!cancelled) setRestoreMessage(error instanceof Error ? error.message : "Unable to restore this design.");
      });

    return () => { cancelled = true; };
  }, []);

  async function submitSavedDesign(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setSaveStatus("saving");
    setSaveMessage("");
    setRecoveryLink("");

    try {
      const response = await fetch("/api/designs", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          email: saveEmail,
          design: { partnerOne, partnerTwo, weddingDate, heading, message, footer, font, fontSize, alignment, palette },
        }),
      });
      const result = await response.json() as { message?: string; error?: string; developmentMagicLink?: string };
      if (!response.ok) throw new Error(result.error || "Unable to save your design.");

      setSaveStatus("saved");
      setSaveMessage(result.message || "Your design is saved.");
      setRecoveryLink(result.developmentMagicLink || "");
    } catch (error) {
      setSaveStatus("error");
      setSaveMessage(error instanceof Error ? error.message : "Unable to save your design.");
    }
  }

  async function createPublicShare() {
    setShareOpen(true);
    setShareStatus("creating");
    setShareLink("");
    setShareMessage("");

    try {
      const response = await fetch("/api/shares", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          design: { partnerOne, partnerTwo, weddingDate, heading, message, footer, font, fontSize, alignment, palette },
        }),
      });
      const result = await response.json() as { share?: { url: string }; error?: string };
      if (!response.ok || !result.share) throw new Error(result.error || "Unable to create the share link.");
      setShareLink(result.share.url);
      setShareStatus("ready");
    } catch (error) {
      setShareStatus("error");
      setShareMessage(error instanceof Error ? error.message : "Unable to create the share link.");
    }
  }

  async function resendPrivateLink(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setRecoveryStatus("sending");
    setRecoveryMessage("");
    setResentLink("");
    try {
      const response = await fetch("/api/designs", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ action: "recover", email: recoveryEmail }),
      });
      const result = await response.json() as { recovered?: boolean; message?: string; developmentMagicLink?: string; error?: string };
      if (!response.ok) throw new Error(result.error || "Unable to find your saved design.");
      setRecoveryStatus(result.recovered ? "sent" : "not-found");
      setRecoveryMessage(result.message || (result.recovered ? "Your fresh edit link is ready." : "No saved design was found."));
      setResentLink(result.developmentMagicLink || "");
    } catch (error) {
      setRecoveryStatus("error");
      setRecoveryMessage(error instanceof Error ? error.message : "Unable to find your saved design.");
    }
  }

  async function copyPublicLink(successMessage = "Public link copied.") {
    if (!shareLink) return;
    try {
      await navigator.clipboard.writeText(shareLink);
      setShareMessage(successMessage);
    } catch {
      setShareMessage("Select and copy the public link above.");
    }
  }

  function applyPreset(preset: (typeof presets)[number]) {
    setActivePreset(preset.id);
    setHeading(preset.heading);
    setMessage(preset.message);
    setFooter(preset.footer);
  }

  function resetDesign() {
    setActivePreset("forever");
    setPartnerOne("Mark");
    setPartnerTwo("Mandy");
    setWeddingDate("2027-03-20");
    setHeading(presets[0].heading);
    setMessage(presets[0].message);
    setFooter(presets[0].footer);
    setFont("editorial");
    setFontSize(100);
    setAlignment("center");
    setPalette("ivory");
  }

  async function uploadOwnDesign(event: ChangeEvent<HTMLInputElement>) {
    const file = event.target.files?.[0];
    event.target.value = "";
    if (!file) return;

    if ((!file.name.toLowerCase().endsWith(".pdf") && file.type !== "application/pdf") || file.size > 10 * 1024 * 1024) {
      setUploadStatus("error");
      setUploadMessage(file.size > 10 * 1024 * 1024 ? "The PDF must be smaller than 10 MB." : "Please choose a PDF file.");
      return;
    }

    setUploadStatus("uploading");
    setUploadMessage("Checking your PDF and page dimensions…");
    const formData = new FormData();
    formData.append("file", file);

    try {
      const response = await fetch("/api/uploads", { method: "POST", body: formData });
      const result = await response.json() as { upload?: UploadedPdf; error?: string };
      if (!response.ok || !result.upload) throw new Error(result.error || "Unable to upload this PDF.");
      setUploadedPdf(result.upload);
      setUploadStatus("uploaded");
      setUploadMessage("PDF ready. This artwork will be attached to your order.");
      sessionStorage.setItem("diamondVialUploadedDesign", JSON.stringify(result.upload));
    } catch (error) {
      setUploadStatus("error");
      setUploadMessage(error instanceof Error ? error.message : "Unable to upload this PDF.");
    }
  }

  function removeUploadedPdf() {
    setUploadedPdf(null);
    setUploadStatus("idle");
    setUploadMessage("");
    sessionStorage.removeItem("diamondVialUploadedDesign");
  }

  function continueToOrder() {
    sessionStorage.setItem("diamondVialDraft", JSON.stringify({
      partnerOne,
      partnerTwo,
      weddingDate,
      heading,
      message,
      footer,
      font,
      fontSize,
      alignment,
      palette,
    }));
    if (uploadedPdf) sessionStorage.setItem("diamondVialUploadedDesign", JSON.stringify(uploadedPdf));
    else sessionStorage.removeItem("diamondVialUploadedDesign");
    window.location.href = "/order";
  }

  return (
    <main className="designer-page">
      <header className="designer-header">
        <a className="brand" href="/" aria-label="Back to Gem Vial home">
          <img className="brand-mark" src="/logo.svg" width="24" height="38" alt="" aria-hidden="true" />
          <span>Gem Vial</span>
        </a>
        <div className="designer-progress" aria-label="Design progress">
          <span className="active">01 Personalise</span><i />
          <span>02 Enquire</span>
        </div>
        <a className="designer-back" href="/">← Back to collection</a>
      </header>

      <section className="designer-intro">
        <div>
          <p className="eyebrow"><span /> Your wedding, in every detail</p>
          <h1>Make it <em>uniquely yours.</em></h1>
        </div>
        <p>Choose a starting point, then refine every word and detail. Your card updates as you type.</p>
      </section>

      {restoreMessage && <div className="restore-notice" role="status"><span>◇</span>{restoreMessage}</div>}

      <section className="designer-workspace">
        <div className="preview-panel">
          <div className="preview-toolbar">
            <span>Live card preview</span>
            <span><i className="live-dot" /> Updates instantly</span>
          </div>

          <div className="card-stage">
            <article className={`wedding-card align-${alignment}`} style={cardStyle} aria-label="Personalised wedding favour card preview">
              <div className="card-heading">{heading || "YOUR HEADING"}</div>
              {activePreset === "wedding" && <div className="card-couple card-couple-feature">{coupleNames}</div>}
              <div className="card-ornament"><span /><b>♡</b><span /></div>
              <div className="card-message">
                {(message || "Your message").split("\n").map((line, index) => <span key={`${line}-${index}`}>{line}</span>)}
              </div>

              <div className="card-vial-wrap" aria-hidden="true">
                <div className="card-vial">
                  <div className="card-vial-glass"><img src="/diamond-single-28.png" width="29" height="29" alt="" /></div>
                  <div className="card-vial-cap" />
                </div>
              </div>

              <div className="card-footer-text">{footer || "YOUR FOOTER MESSAGE"}</div>
              <div className="card-couple">{coupleNames}</div>
              <div className="card-date">{formatDate(weddingDate)}</div>
            </article>
            <p className="preview-note">Preview is representative. Final spacing is refined before print.</p>
          </div>
        </div>

        <aside className="editor-panel" aria-label="Card editor">
          <div className="saved-design-recovery">
            <div>
              <strong>Already saved a design?</strong>
              <span>Lost your private edit link? We’ll email you a fresh one.</span>
            </div>
            <button type="button" onClick={() => { setRecoveryOpen(true); setRecoveryStatus("idle"); setRecoveryMessage(""); setResentLink(""); }}>Resend my edit link <span>→</span></button>
          </div>
          <section className="editor-section quick-section">
            <div className="editor-title-row"><span className="editor-step">01</span><div><h2>Quick start</h2><p>Choose a wording style</p></div></div>
            <div className="preset-grid">
              {presets.map((preset) => (
                <button
                  type="button"
                  key={preset.id}
                  className={activePreset === preset.id ? "preset active" : "preset"}
                  onClick={() => applyPreset(preset)}
                  aria-pressed={activePreset === preset.id}
                >
                  <span>{preset.label}</span><small>{preset.note}</small><i>↗</i>
                </button>
              ))}
            </div>
            <div className="control-group">
              <span className="control-label">Card colour</span>
              <div className="swatches">
                {(Object.entries(palettes) as [PaletteChoice, (typeof palettes)[PaletteChoice]][]).map(([value, choice]) => (
                  <button type="button" key={value} className={palette === value ? "swatch active" : "swatch"} onClick={() => setPalette(value)} aria-label={`${choice.label} card`} aria-pressed={palette === value}>
                    <i style={{ background: choice.card }} /><span>{choice.label}</span>
                  </button>
                ))}
              </div>
            </div>
          </section>

          <section className="editor-section">
            <div className="editor-title-row"><span className="editor-step">02</span><div><h2>Your details</h2><p>Names and wedding date</p></div></div>
            <div className="form-grid two-col">
              <label><span>Partner one</span><input value={partnerOne} onChange={(event) => setPartnerOne(event.target.value)} placeholder="Mark" /></label>
              <label><span>Partner two</span><input value={partnerTwo} onChange={(event) => setPartnerTwo(event.target.value)} placeholder="Mandy" /></label>
            </div>
            <div className="form-grid">
              <label><span>Wedding date</span><input type="date" value={weddingDate} onChange={(event) => setWeddingDate(event.target.value)} /></label>
            </div>
          </section>

          <section className="editor-section">
            <div className="editor-title-row"><span className="editor-step">03</span><div><h2>Your wording</h2><p>Edit every line</p></div></div>
            <div className="form-grid">
              <label><span>Heading</span><input value={heading} maxLength={42} onChange={(event) => setHeading(event.target.value)} /></label>
              <label><span>Message</span><textarea value={message} maxLength={130} rows={4} onChange={(event) => setMessage(event.target.value)} /></label>
              <label><span>Footer message</span><input value={footer} maxLength={58} onChange={(event) => setFooter(event.target.value)} /></label>
            </div>
          </section>

          <section className="editor-section">
            <div className="editor-title-row"><span className="editor-step">04</span><div><h2>Look & feel</h2><p>Typography and card style</p></div></div>
            <div className="form-grid">
              <label>
                <span>Typography</span>
                <select value={font} onChange={(event) => setFont(event.target.value as FontChoice)}>
                  {Object.entries(fonts).map(([value, choice]) => <option key={value} value={value}>{choice.label}</option>)}
                </select>
              </label>
              <label className="range-label">
                <span>Text size <b>{fontSize}%</b></span>
                <input type="range" min="82" max="118" value={fontSize} onChange={(event) => setFontSize(Number(event.target.value))} />
              </label>
            </div>
            <div className="control-group">
              <span className="control-label">Alignment</span>
              <div className="segmented">
                <button type="button" className={alignment === "left" ? "active" : ""} onClick={() => setAlignment("left")}>Left</button>
                <button type="button" className={alignment === "center" ? "active" : ""} onClick={() => setAlignment("center")}>Centred</button>
              </div>
            </div>
          </section>

          <section className="own-design-upload" aria-labelledby="own-design-title">
            <div className="own-design-mark" aria-hidden="true">↥</div>
            <div className="own-design-copy">
              <p>Have finished artwork?</p>
              <h2 id="own-design-title">Upload your own design</h2>
              <span>Your PDF will be used instead of the card editor design.</span>
              <div className="own-design-specs" aria-label="Maximum PDF dimensions">
                <span><b>Millimetres</b>148 × 210 mm</span>
                <span><b>Centimetres</b>14.8 × 21.0 cm</span>
                <span><b>Inches</b>5.83 × 8.27 in</span>
              </div>
            </div>
            <div className="own-design-control">
              <label className={uploadStatus === "uploading" ? "upload-pdf-button busy" : "upload-pdf-button"}>
                <input type="file" accept="application/pdf,.pdf" onChange={uploadOwnDesign} disabled={uploadStatus === "uploading"} />
                {uploadStatus === "uploading" ? "Checking PDF…" : uploadedPdf ? "Replace PDF" : "Choose PDF"}<span>↗</span>
              </label>
              <small>PDF only · Max 10 MB · A5 or smaller</small>
            </div>
            {(uploadMessage || uploadedPdf) && (
              <div className={`upload-result ${uploadStatus}`} role="status">
                {uploadedPdf && <div><strong>{uploadedPdf.fileName}</strong><span>{uploadedPdf.pageCount} {uploadedPdf.pageCount === 1 ? "page" : "pages"} · {uploadedPdf.widthMm} × {uploadedPdf.heightMm} mm</span></div>}
                <p>{uploadMessage}</p>
                {uploadedPdf && <button type="button" onClick={removeUploadedPdf}>Remove</button>}
              </div>
            )}
          </section>

          <div className="editor-actions">
            <button type="button" className="reset-button" onClick={resetDesign}>Reset design</button>
            <button type="button" className="button save-design-button" onClick={() => { setSaveOpen(true); setSaveStatus("idle"); setSaveMessage(""); setRecoveryLink(""); }}>
              Save design <span>♡</span>
            </button>
            <button type="button" className="button share-design-button" onClick={createPublicShare}>
              Share a link <span>↗</span>
            </button>
            <button type="button" className="button button-dark use-design-button" onClick={continueToOrder}>Use this design <span>→</span></button>
            <p>Save with a private edit link, share a public view-only link, or continue to choose your diamond and guest quantity.</p>
          </div>
        </aside>
      </section>

      {saveOpen && (
        <div className="save-modal-backdrop" role="presentation" onMouseDown={(event) => { if (event.target === event.currentTarget) setSaveOpen(false); }}>
          <section className="save-modal" role="dialog" aria-modal="true" aria-labelledby="save-design-title">
            <button className="save-modal-close" type="button" onClick={() => setSaveOpen(false)} aria-label="Close save design window">×</button>
            <div className="save-modal-mark">◇</div>
            <p className="save-modal-kicker">Private design access</p>
            <h2 id="save-design-title">Save your design.</h2>
            <p className="save-modal-intro">Enter your email and we’ll send a private magic link that brings back this exact card—no password or account needed.</p>

            <form onSubmit={submitSavedDesign}>
              <label>
                <span>Email address</span>
                <input type="email" value={saveEmail} onChange={(event) => setSaveEmail(event.target.value)} placeholder="you@example.com" autoComplete="email" required maxLength={254} autoFocus />
              </label>
              <button className="button button-dark" type="submit" disabled={saveStatus === "saving"}>
                {saveStatus === "saving" ? "Saving…" : "Email my magic link"}
              </button>
            </form>

            {saveMessage && (
              <div className={`save-result ${saveStatus}`} role="status">
                <strong>{saveStatus === "saved" ? "Design saved" : "Please try again"}</strong>
                <span>{saveMessage}</span>
                {recoveryLink && (
                  <div className="local-recovery">
                    <a href={recoveryLink}>Open recovery link</a>
                    <button type="button" onClick={() => navigator.clipboard?.writeText(recoveryLink)}>Copy link</button>
                  </div>
                )}
              </div>
            )}

            <p className="save-modal-fineprint">Your link expires after 30 days. Anyone with the link can view the design, so keep it private.</p>
          </section>
        </div>
      )}

      {recoveryOpen && (
        <div className="save-modal-backdrop" role="presentation" onMouseDown={(event) => { if (event.target === event.currentTarget) setRecoveryOpen(false); }}>
          <section className="save-modal recovery-modal" role="dialog" aria-modal="true" aria-labelledby="recover-design-title">
            <button className="save-modal-close" type="button" onClick={() => setRecoveryOpen(false)} aria-label="Close design recovery window">×</button>
            <img className="share-modal-logo" src="/logo.svg" width="24" height="38" alt="" aria-hidden="true" />
            <p className="save-modal-kicker">Private design recovery</p>
            <h2 id="recover-design-title">Find your saved design.</h2>
            <p className="save-modal-intro">Enter the email address you used when saving. We’ll send a fresh private link to your latest saved design.</p>
            <form onSubmit={resendPrivateLink}>
              <label><span>Email address</span><input type="email" value={recoveryEmail} onChange={(event) => setRecoveryEmail(event.target.value)} placeholder="you@example.com" autoComplete="email" required maxLength={254} /></label>
              <button className="button button-dark" type="submit" disabled={recoveryStatus === "sending"}>{recoveryStatus === "sending" ? "Finding your design…" : "Resend my edit link"}</button>
            </form>
            {recoveryMessage && (
              <div className={`save-result ${recoveryStatus === "sent" ? "saved" : recoveryStatus === "error" ? "error" : ""}`} role="status">
                <strong>{recoveryStatus === "sent" ? "Link ready" : recoveryStatus === "not-found" ? "Design not found" : "Please try again"}</strong>
                <span>{recoveryMessage}</span>
                {resentLink && <div className="local-recovery"><a href={resentLink}>Open recovered design</a><button type="button" onClick={() => navigator.clipboard?.writeText(resentLink)}>Copy link</button></div>}
              </div>
            )}
            <p className="save-modal-fineprint">The fresh link is private, restores editing access, and expires after 30 days. Public share links cannot be used here.</p>
          </section>
        </div>
      )}

      {shareOpen && (
        <div className="save-modal-backdrop" role="presentation" onMouseDown={(event) => { if (event.target === event.currentTarget) setShareOpen(false); }}>
          <section className="save-modal share-modal" role="dialog" aria-modal="true" aria-labelledby="share-design-title">
            <button className="save-modal-close" type="button" onClick={() => setShareOpen(false)} aria-label="Close share design window">×</button>
            <img className="share-modal-logo" src="/logo.svg" width="24" height="38" alt="" aria-hidden="true" />
            <p className="save-modal-kicker">Public design link</p>
            <h2 id="share-design-title">Share your design.</h2>
            <p className="save-modal-intro">This public, view-only link has its own magic token. It is completely separate from your private edit link and cannot be used to change your design.</p>

            {shareStatus === "creating" && <div className="share-creating" role="status">Creating your secure public link…</div>}
            {shareStatus === "error" && <div className="save-result error" role="alert"><strong>Please try again</strong><span>{shareMessage}</span></div>}
            {shareStatus === "ready" && (
              <div className="share-ready">
                <label className="share-link-field">
                  <span>Public share link</span>
                  <input value={shareLink} readOnly onFocus={(event) => event.currentTarget.select()} />
                </label>
                <div className="share-link-actions">
                  <button type="button" onClick={() => copyPublicLink()}>Copy link</button>
                  <a href={shareLink} target="_blank" rel="noreferrer">Open public page ↗</a>
                </div>
                <div className="share-socials" aria-label="Share this design">
                  <a href={`https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(shareLink)}`} target="_blank" rel="noreferrer">Facebook</a>
                  <button type="button" onClick={() => copyPublicLink("Link copied—paste it into Instagram.")}>Instagram</button>
                  <a href={`https://wa.me/?text=${encodeURIComponent(`A Gem Vial design shared with you: ${shareLink}`)}`} target="_blank" rel="noreferrer">WhatsApp</a>
                  <a href={`mailto:?subject=${encodeURIComponent("A Gem Vial design")}&body=${encodeURIComponent(`A Gem Vial design has been shared with you:\n\n${shareLink}`)}`}>Email</a>
                </div>
                {shareMessage && <p className="share-copy-message" role="status">{shareMessage}</p>}
              </div>
            )}

            <p className="save-modal-fineprint">Anyone with this public link can view the card and leave a public comment. The separate private edit link is never exposed.</p>
          </section>
        </div>
      )}
    </main>
  );
}
