/* eslint-disable */
/* ============================================================
   AsciiPicCTA — "Get your own ASCII profile pic"
   ------------------------------------------------------------
   Placeholder front-end for a viral micro-tool.

   Frontend (this file):
     • drag-and-drop / file-input zone
     • runs a local in-browser ASCII conversion as a *preview*
       (so people see something instantly even before backend
       is wired)
     • collects social handles + email (optional)
     • POSTs to /api/ascii-portrait (TODO — handled by Claude
       Code, see HANDOFF-V3.md §7).

   Backend spec for Claude Code:
     • POST /api/ascii-portrait  multipart: { image, email?, x?,
       linkedin?, github?, instagram? }
     • Pipeline:
         1. Receive image, validate (jpg/png, ≤8MB, 1:1ish)
         2. Push original to S3:
              s3://kevinz-ai-portraits/originals/{uuid}.jpg
         3. Run ASCII conversion (server-side — better than the
            preview): grayscale → contrast normalize → 70-char
            ramp, 80×40 default (configurable)
         4. Save .txt to:
              s3://kevinz-ai-portraits/ascii/{uuid}.txt
         5. Render preview PNG (1200×1200, JetBrains Mono,
            amber on OLED black, KZ corner sigil) → save:
              s3://kevinz-ai-portraits/cards/{uuid}.png
         6. Return { uuid, ascii_url, card_url, share_url }
     • DB row in `portraits`:
              id · created_at · email · socials_json · uuid
              · status (pending|done|flagged)
     • Moderation: Rekognition NSFW + face-detect required
     • Rate limit: 3 / IP / hour, 1 / email / day
     • Public viewer route: /p/{uuid} renders card_url + share
       buttons (Twitter, LinkedIn, download .txt + .png)
     • Webhook to kevin@kevinz.ai on every successful upload
       so he can see who's using it.

   Privacy:
     • EXIF stripped server-side before S3 push
     • Originals auto-purge at 30 days; ASCII + card kept
     • robots disallow on /p/{uuid} unless user opts in to
       "feature on kevinz.ai gallery"
   ============================================================ */

const { useState: _useStateCTA, useRef: _useRefCTA, useEffect: _useEffectCTA, useCallback: _useCBcta } = React;

/* ---------- in-browser ASCII converter (preview only) ---------- */
const ASCII_RAMP = " .,:;-=+*#%@"; // 12 levels, light → dark
function imageToAscii(img, cols = 80) {
  const aspect = img.height / img.width;
  // chars are taller than wide; fudge factor for JetBrains Mono
  const rows = Math.max(20, Math.floor(cols * aspect * 0.5));
  const c = document.createElement("canvas");
  c.width = cols;
  c.height = rows;
  const ctx = c.getContext("2d");
  ctx.drawImage(img, 0, 0, cols, rows);
  const { data } = ctx.getImageData(0, 0, cols, rows);
  let out = "";
  for (let y = 0; y < rows; y++) {
    let line = "";
    for (let x = 0; x < cols; x++) {
      const i = (y * cols + x) * 4;
      const r = data[i], g = data[i + 1], b = data[i + 2];
      const lum = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
      const idx = Math.floor(lum * (ASCII_RAMP.length - 1));
      line += ASCII_RAMP[ASCII_RAMP.length - 1 - idx];
    }
    out += line + "\n";
  }
  return out;
}

function AsciiPicCTA() {
  const [ascii, setAscii] = _useStateCTA(null);
  const [fileName, setFileName] = _useStateCTA("");
  const [busy, setBusy] = _useStateCTA(false);
  const [submitted, setSubmitted] = _useStateCTA(false);
  const [drag, setDrag] = _useStateCTA(false);
  const [form, setForm] = _useStateCTA({
    email: "", x: "", linkedin: "", github: "", instagram: ""
  });
  const dropRef = _useRefCTA(null);
  const inputRef = _useRefCTA(null);

  const handleFile = _useCBcta((file) => {
    if (!file || !file.type.startsWith("image/")) return;
    setBusy(true);
    setFileName(file.name);
    const reader = new FileReader();
    reader.onload = (e) => {
      const img = new Image();
      img.onload = () => {
        const a = imageToAscii(img, 80);
        setAscii(a);
        setBusy(false);
      };
      img.src = e.target.result;
    };
    reader.readAsDataURL(file);
  }, []);

  const onDrop = (e) => {
    e.preventDefault();
    setDrag(false);
    const f = e.dataTransfer.files?.[0];
    if (f) handleFile(f);
  };

  const submit = (e) => {
    e.preventDefault();
    // TODO (Claude Code): POST to /api/ascii-portrait with the
    // original file blob + form fields. Right now we just fake it.
    setSubmitted(true);
  };

  return (
    <section id="ascii-cta" data-section="ascii-cta" className="section-pad">
      <div className="container">
        <div className="box-head">
          <window.AsciiBadge glyph="bracket" count={3} />
          <span>// 09 — get your own ascii profile pic</span>
          <span className="rule" />
        </div>

        <div className="ascii-cta-wrap">
          {/* LEFT: pitch + form */}
          <div className="ascii-cta-left">
            <h2 className="h-section">
              your face,<br />
              <span className="amber">in 80 characters.</span>
            </h2>
            <p className="lede full mt-16" style={{ maxWidth: "44ch" }}>
              Drop a photo. Get a JetBrains-Mono portrait you can
              paste into your terminal banner, README, LinkedIn,
              X header. No watermark. Free.
            </p>

            <ul style={{ listStyle: "none", padding: 0, margin: "20px 0 0", fontFamily: "var(--mono)", fontSize: 12, color: "var(--fg-3)", lineHeight: 1.9 }}>
              <li><span className="amber">▸</span> 80×40 char render · 12-level ramp</li>
              <li><span className="amber">▸</span> .txt + 1200×1200 OLED card · downloadable</li>
              <li><span className="amber">▸</span> EXIF stripped · originals purge in 30d</li>
              <li><span className="amber">▸</span> share to /p/your-id · ghost-public if you want</li>
            </ul>

            {!submitted ? (
              <form onSubmit={submit} className="ascii-cta-form mt-32">
                <div className="ascii-cta-grid">
                  <input
                    className="news-input"
                    placeholder="x · @handle"
                    value={form.x}
                    onChange={(e) => setForm({ ...form, x: e.target.value })}
                  />
                  <input
                    className="news-input"
                    placeholder="linkedin · /in/..."
                    value={form.linkedin}
                    onChange={(e) => setForm({ ...form, linkedin: e.target.value })}
                  />
                  <input
                    className="news-input"
                    placeholder="github · username"
                    value={form.github}
                    onChange={(e) => setForm({ ...form, github: e.target.value })}
                  />
                  <input
                    className="news-input"
                    placeholder="instagram · @handle"
                    value={form.instagram}
                    onChange={(e) => setForm({ ...form, instagram: e.target.value })}
                  />
                  <button
                    type="submit"
                    className="btn btn-primary"
                    disabled={!ascii}
                    style={{ gridColumn: "1 / -1", width: "100%", justifyContent: "center", opacity: ascii ? 1 : 0.4 }}
                  >
                    {ascii ? "▸ generate · save · share" : "drop a photo first →"}
                  </button>
                </div>
                <div className="dim mt-12" style={{ fontSize: 10, letterSpacing: "0.18em", textTransform: "uppercase" }}>
                  socials are optional · share link returned instantly
                </div>
              </form>
            ) : (
              <div className="ascii-cta-done mt-32">
                <div className="amber" style={{ fontFamily: "var(--mono)", fontSize: 13, letterSpacing: "0.12em", textTransform: "uppercase" }}>
                  ✓ queued · check your inbox in ~30s
                </div>
                <div className="dim mt-8" style={{ fontSize: 12 }}>
                  preview shown right · final render runs server-side at 2× resolution.
                </div>
                <button
                  className="btn mt-16"
                  onClick={() => { setSubmitted(false); setAscii(null); setFileName(""); }}
                >
                  ↻ make another
                </button>
              </div>
            )}
          </div>

          {/* RIGHT: drop zone / preview */}
          <div className="ascii-cta-right">
            <div className="win">
              <div className="win-title">
                <div className="lights"><span className="r" /><span className="a" /><span className="g" /></div>
                <span>~/ascii-portrait · {ascii ? "preview" : "drop image"}</span>
                <span className="meta">{fileName || "—"}</span>
              </div>
              <div
                ref={dropRef}
                className={"ascii-cta-drop " + (drag ? "is-drag" : "") + (ascii ? " has-art" : "")}
                onDragOver={(e) => { e.preventDefault(); setDrag(true); }}
                onDragLeave={() => setDrag(false)}
                onDrop={onDrop}
                onClick={() => !ascii && inputRef.current?.click()}
              >
                <input
                  ref={inputRef}
                  type="file"
                  accept="image/*"
                  style={{ display: "none" }}
                  onChange={(e) => handleFile(e.target.files?.[0])}
                />
                {!ascii && !busy && (
                  <div className="ascii-cta-empty">
                    <pre className="dim" style={{ margin: 0, fontSize: 11, lineHeight: 1.3 }}>{`
   ┌────────────────────────┐
   │                        │
   │     ▸ drop image       │
   │       or click         │
   │                        │
   │   .jpg · .png · ≤8MB   │
   │                        │
   └────────────────────────┘
`}</pre>
                  </div>
                )}
                {busy && (
                  <div className="amber" style={{ fontFamily: "var(--mono)", fontSize: 12, letterSpacing: "0.18em", textTransform: "uppercase" }}>
                    ↻ converting · 80 cols · 12 levels<span className="cursor" />
                  </div>
                )}
                {ascii && (
                  <pre className="ascii-cta-preview">{ascii}</pre>
                )}
              </div>
              <div className="win-foot">
                <span>{ascii ? "preview · client-side" : "ready"}</span>
                <span>{ascii ? "server render at 2× on submit" : "drop image to begin"}</span>
              </div>
            </div>

            {ascii && (
              <div className="row gap-12 mt-12" style={{ justifyContent: "flex-end" }}>
                <button
                  className="btn"
                  onClick={() => { setAscii(null); setFileName(""); }}
                >× clear</button>
                <button
                  className="btn"
                  onClick={() => {
                    const blob = new Blob([ascii], { type: "text/plain" });
                    const url = URL.createObjectURL(blob);
                    const a = document.createElement("a");
                    a.href = url; a.download = "portrait.txt"; a.click();
                    URL.revokeObjectURL(url);
                  }}>↓ download .txt</button>
              </div>
            )}
          </div>
        </div>
      </div>

      <style>{`
        .ascii-cta-wrap{
          display: grid; grid-template-columns: 1fr 1.2fr; gap: 32px;
          align-items: start;
        }
        @media (max-width: 980px){ .ascii-cta-wrap{ grid-template-columns: 1fr; } }
        .ascii-cta-grid{
          display: grid; grid-template-columns: 1fr 1fr; gap: 8px;
        }
        @media (max-width: 600px){ .ascii-cta-grid{ grid-template-columns: 1fr; } }
        .ascii-cta-grid .news-input{ width: 100%; }
        .ascii-cta-grid button{ grid-column: 1 / -1; }
        .ascii-cta-drop{
          min-height: 360px;
          padding: 18px;
          background: #050606;
          display: flex; align-items: center; justify-content: center;
          cursor: pointer;
          transition: background 140ms ease;
          overflow: hidden;
        }
        .ascii-cta-drop.is-drag{
          background: color-mix(in oklch, var(--amber) 8%, #050606);
          outline: 1px dashed var(--amber);
          outline-offset: -8px;
        }
        .ascii-cta-drop.has-art{ cursor: default; }
        .ascii-cta-empty{ text-align: center; }
        .ascii-cta-preview{
          font-family: var(--mono);
          font-size: 6px;
          line-height: 1;
          letter-spacing: 0;
          color: var(--amber);
          text-shadow: 0 0 6px color-mix(in oklch, var(--amber) 30%, transparent);
          white-space: pre;
          margin: 0;
          user-select: all;
        }
        @media (max-width: 600px){ .ascii-cta-preview{ font-size: 5px; } }
      `}</style>
    </section>
  );
}
window.AsciiPicCTA = AsciiPicCTA;

/* ============================================================
   AsciiCtaTeaser — compact homepage card. Click → opens modal
   with the full <AsciiPicCTA />.
   Also offers a deep link to the standalone page (?view=ascii)
   for share/social traffic — same React shell, different render
   tree, clean shareable URL.
   ============================================================ */
function AsciiCtaTeaser() {
  const [open, setOpen] = _useStateCTA(false);

  _useEffectCTA(() => {
    if (!open) return;
    const onKey = (e) => { if (e.key === "Escape") setOpen(false); };
    window.addEventListener("keydown", onKey);
    document.body.style.overflow = "hidden";
    return () => {
      window.removeEventListener("keydown", onKey);
      document.body.style.overflow = "";
    };
  }, [open]);

  return (
    <section id="ascii-cta" data-section="ascii-cta" className="section-pad">
      <div className="container">
        <div className="box-head">
          <window.AsciiBadge glyph="bracket" count={3} />
          <span>// 09 — get your own ascii profile pic</span>
          <span className="rule" />
        </div>

        <div style={{
          marginTop: 20,
          border: "1px solid var(--line-strong)",
          background: "var(--bg-1)",
          padding: "28px 32px",
          display: "grid",
          gridTemplateColumns: "1.4fr auto",
          gap: 24,
          alignItems: "center"
        }} className="ascii-teaser">
          <div>
            <h2 className="h-section" style={{ marginBottom: 8 }}>
              your face,<br />
              <span className="dim2" style={{ fontWeight: 600 }}>in 80 characters.</span>
            </h2>
            <p style={{ fontSize: 14, color: "var(--fg-3)", lineHeight: 1.55, maxWidth: "60ch", marginTop: 14 }}>
              Drop a photo, get a JetBrains-Mono portrait. Paste into your terminal banner,
              README, LinkedIn header. No watermark. Free.
            </p>
            <div style={{ marginTop: 16, fontSize: 11, color: "var(--fg-4)", letterSpacing: "0.16em", textTransform: "uppercase" }}>
              ▸ 80×40 render · ▸ .txt + .png · ▸ EXIF stripped · ▸ shareable link
            </div>
          </div>
          <div style={{ display: "flex", flexDirection: "column", gap: 10, alignItems: "stretch", minWidth: 220 }}>
            <button
              type="button"
              className="btn btn-primary"
              onClick={() => setOpen(true)}
              style={{ justifyContent: "center", whiteSpace: "nowrap" }}
            >
              ▸ open the tool
            </button>
            <a
              href="?view=ascii"
              className="btn btn-ghost"
              style={{ justifyContent: "center", whiteSpace: "nowrap", fontSize: 11 }}
            >
              ↗ standalone page
            </a>
          </div>
        </div>
      </div>

      {/* MODAL */}
      {open && (
        <div
          onClick={() => setOpen(false)}
          style={{
            position: "fixed", inset: 0, zIndex: 200,
            background: "rgba(0,0,0,0.92)",
            display: "flex", alignItems: "flex-start", justifyContent: "center",
            padding: "40px 24px",
            overflowY: "auto"
          }}
        >
          <div
            onClick={(e) => e.stopPropagation()}
            style={{
              width: "min(1180px, 100%)",
              position: "relative",
              border: "1px solid var(--amber)",
              background: "var(--bg)"
            }}
          >
            <button
              type="button"
              onClick={() => setOpen(false)}
              aria-label="close"
              style={{
                position: "sticky", top: 8, marginLeft: "auto", marginRight: 8,
                display: "block", float: "right",
                fontSize: 11, color: "var(--amber)", letterSpacing: "0.18em",
                textTransform: "uppercase", cursor: "pointer",
                background: "var(--bg-1)", border: "1px solid var(--line)",
                padding: "6px 10px", zIndex: 10
              }}
            >× close · esc</button>
            <window.AsciiPicCTA />
          </div>
        </div>
      )}
    </section>
  );
}
window.AsciiCtaTeaser = AsciiCtaTeaser;
