/**
 * Arsova Caption Generator - React Application
 */

const { useState, useRef, useEffect } = React;

/* ═══════════════════════════════════════════════════════════════
   CONSTANTS
═══════════════════════════════════════════════════════════════ */
const PLATFORMS = ["Instagram", "TikTok", "Facebook", "Other"];
const POST_TYPES = ["Transformation", "Promotion", "Educational", "Behind-the-scenes", "Testimonial", "Humor", "Motivational"];
const SERVICES = ["Balayage", "Highlights", "Haircut", "Blowout", "Color Correction", "Extensions", "Gloss/Toner", "Keratin Treatment", "Vivid/Fashion Color", "Root Melt", "Money Piece", "Silk Press", "Bob/Lob Cut", "Curtain Bangs", "Bond Repair", "Other"];
const TONES = ["Fun & Playful", "Luxurious & Elegant", "Edgy & Bold", "Warm & Friendly", "Professional & Polished"];

/* ═══════════════════════════════════════════════════════════════
   SHARED STYLES
═══════════════════════════════════════════════════════════════ */
const BG = "linear-gradient(170deg, #f7f5f0 0%, #f0ece4 40%, #eae5db 70%, #f4f1eb 100%)";
const GOLD = "#8b7d52";
const DARK = "#2d2d2b";

const chipStyle = (active) => ({
  padding: "10px 20px", borderRadius: 100, cursor: "pointer", transition: "all 0.25s ease",
  border: active ? "2px solid " + GOLD : "1.5px solid rgba(139,125,82,0.3)",
  background: active ? GOLD : "rgba(255,255,255,0.6)",
  color: active ? "#fff" : DARK, fontFamily: "'Roboto', sans-serif",
  fontSize: 15, fontWeight: active ? 600 : 400, letterSpacing: "0.02em", whiteSpace: "nowrap",
});

const labelStyle = {
  fontFamily: "'Roboto', sans-serif", fontSize: 11, fontWeight: 600,
  textTransform: "uppercase", letterSpacing: "0.12em", color: GOLD, marginBottom: 10, display: "block",
};

const inputStyle = {
  width: "100%", padding: "14px 18px", borderRadius: 12,
  border: "1.5px solid rgba(139,125,82,0.25)", background: "rgba(255,255,255,0.6)",
  fontFamily: "'Roboto', sans-serif", fontSize: 14, color: DARK,
  outline: "none", transition: "border 0.2s ease", boxSizing: "border-box",
};

const selectStyle = {
  ...inputStyle, appearance: "none", backgroundImage: `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%238b7d52' d='M6 8L1 3h10z'/%3E%3C/svg%3E")`,
  backgroundRepeat: "no-repeat", backgroundPosition: "right 16px center", paddingRight: 40,
};

const sectionTitle = {
  fontFamily: "'Roboto', sans-serif", fontSize: 15, fontWeight: 600,
  color: DARK, marginBottom: 0, letterSpacing: "0.02em",
};

const stepBadge = {
  background: GOLD, color: "#fff", borderRadius: 100, width: 22, height: 22,
  display: "inline-flex", alignItems: "center", justifyContent: "center",
  fontSize: 11, fontWeight: 600, flexShrink: 0,
};

const goldBtn = (enabled) => ({
  padding: "16px 32px", borderRadius: 14, border: "none",
  background: enabled ? "linear-gradient(135deg, #8b7d52, #6b5f3a)" : "rgba(139,125,82,0.2)",
  color: enabled ? "#fff" : "#9b9b96", fontFamily: "'Roboto', sans-serif",
  fontSize: 14, fontWeight: 600, letterSpacing: "0.08em", textTransform: "uppercase",
  cursor: enabled ? "pointer" : "not-allowed", transition: "all 0.3s ease",
  boxShadow: enabled ? "0 4px 20px rgba(139,125,82,0.3)" : "none",
});

const spinner = (size = 18) => ({
  width: size, height: size, border: "2px solid rgba(255,255,255,0.3)", borderTopColor: "#fff",
  borderRadius: "50%", display: "inline-block", animation: "spin 0.8s linear infinite",
});

const navLink = (active) => ({
  padding: "8px 20px", borderRadius: 100, cursor: "pointer", transition: "all 0.2s ease",
  background: active ? GOLD : "transparent", color: active ? "#fff" : GOLD,
  border: active ? "none" : "1.5px solid rgba(139,125,82,0.3)",
  fontFamily: "'Roboto', sans-serif", fontSize: 12, fontWeight: 500,
  letterSpacing: "0.05em", textTransform: "uppercase", textDecoration: "none",
});

/* ═══════════════════════════════════════════════════════════════
   LOADING OVERLAY
═══════════════════════════════════════════════════════════════ */
function LoadingOverlay() {
  return (
    <div style={{
      position: "fixed", top: 0, left: 0, right: 0, bottom: 0,
      background: "rgba(247,245,240,0.95)", backdropFilter: "blur(8px)",
      display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center",
      zIndex: 9999,
    }}>
      <div style={{
        width: 80, height: 80, borderRadius: "50%",
        background: "linear-gradient(135deg, #8b7d52, #6b5f3a)",
        display: "flex", alignItems: "center", justifyContent: "center",
        animation: "spin 2s linear infinite",
        boxShadow: "0 8px 32px rgba(139,125,82,0.3)",
      }}>
        <span style={{ fontSize: 36 }}>✨</span>
      </div>
      <h2 style={{
        fontFamily: "'Roboto', sans-serif", fontSize: 24, color: DARK,
        marginTop: 28, marginBottom: 8,
      }}>Creating Your Captions</h2>
      <p style={{
        color: "#6b6b68", fontSize: 14, animation: "pulse 1.5s ease-in-out infinite",
      }}>This may take a moment...</p>
    </div>
  );
}

/* ═══════════════════════════════════════════════════════════════
   CAPTION CARD (for generator results)
═══════════════════════════════════════════════════════════════ */
function CaptionCard({ text, tone, onCopy }) {
  const [copied, setCopied] = useState(false);
  const handleCopy = () => { navigator.clipboard.writeText(text); setCopied(true); setTimeout(() => setCopied(false), 2000); if (onCopy) onCopy(); };
  return (
    <div style={{
      background: "rgba(255,255,255,0.65)", backdropFilter: "blur(12px)", borderRadius: 16,
      padding: "16px 18px", border: "1px solid rgba(139,125,82,0.12)",
      display: "flex", flexDirection: "column", height: "100%", transition: "all 0.3s ease",
    }}
      onMouseEnter={e => { e.currentTarget.style.transform = "translateY(-2px)"; e.currentTarget.style.boxShadow = "0 8px 32px rgba(45,45,43,0.08)"; }}
      onMouseLeave={e => { e.currentTarget.style.transform = "translateY(0)"; e.currentTarget.style.boxShadow = "none"; }}>
      {tone && (
        <div style={{ marginBottom: 10 }}>
          <span style={{ background: "rgba(139,125,82,0.15)", color: DARK, padding: "4px 10px", borderRadius: 100, fontSize: 10, fontWeight: 500 }}>{tone}</span>
        </div>
      )}
      <div style={{ whiteSpace: "pre-wrap", fontSize: 15, lineHeight: 1.6, color: DARK, flex: 1, marginBottom: 12 }}>{text}</div>
      <div style={{ marginTop: "auto" }}>
        <button onClick={handleCopy} style={{
          background: copied ? DARK : "rgba(45,45,43,0.08)", color: copied ? "#fff" : DARK,
          border: "1px solid rgba(45,45,43,0.2)", borderRadius: 6, padding: "5px 12px", fontSize: 11, cursor: "pointer", transition: "all 0.2s ease",
        }}>{copied ? "✓ Copied" : "Copy"}</button>
      </div>
    </div>
  );
}

/* ═══════════════════════════════════════════════════════════════
   HISTORY CAPTION CARD (with voting)
═══════════════════════════════════════════════════════════════ */
function HistoryCaptionCard({ caption, onVote, onDelete, isAdmin }) {
  const [copied, setCopied] = useState(false);
  const [voting, setVoting] = useState(false);

  const handleCopy = () => { navigator.clipboard.writeText(caption.caption_text); setCopied(true); setTimeout(() => setCopied(false), 2000); };

  const handleVote = async (dir) => {
    if (voting) return;
    setVoting(true);
    await onVote(caption.id, dir);
    setVoting(false);
  };

  return (
    <div style={{
      background: "rgba(255,255,255,0.65)", backdropFilter: "blur(12px)", borderRadius: 16,
      padding: "16px 18px", border: "1px solid rgba(139,125,82,0.12)",
      display: "flex", flexDirection: "column", height: "100%",
    }}>
      {/* Meta info */}
      <div style={{ display: "flex", flexWrap: "wrap", gap: 8, marginBottom: 12 }}>
        {caption.platform && <span style={{ background: "rgba(139,125,82,0.1)", color: GOLD, padding: "4px 10px", borderRadius: 100, fontSize: 10, fontWeight: 600, textTransform: "uppercase" }}>{caption.platform}</span>}
        {caption.post_type && <span style={{ background: "rgba(139,125,82,0.1)", color: GOLD, padding: "4px 10px", borderRadius: 100, fontSize: 10, fontWeight: 600, textTransform: "uppercase" }}>{caption.post_type}</span>}
        {caption.tone_group && <span style={{ background: "rgba(139,125,82,0.15)", color: DARK, padding: "4px 10px", borderRadius: 100, fontSize: 10, fontWeight: 500, textTransform: "uppercase", letterSpacing: "0.05em" }}>{caption.tone_group.replace(/\s*\(Preferred\)/i, '')}</span>}
      </div>

      {/* Caption text */}
      <div style={{ whiteSpace: "pre-wrap", fontSize: 15, lineHeight: 1.6, color: DARK, marginBottom: 12, flex: 1, overflow: "hidden" }}>
        {caption.caption_text}
      </div>

      {/* Actions row */}
      <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", borderTop: "1px solid rgba(139,125,82,0.1)", paddingTop: 10, marginTop: "auto" }}>
        {/* Voting */}
        <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
          <button onClick={() => handleVote("up")} disabled={voting} style={{
            width: 28, height: 28, borderRadius: 6, border: "1px solid rgba(139,125,82,0.2)",
            background: "rgba(255,255,255,0.8)", cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center",
            transition: "all 0.2s ease", fontSize: 12,
          }} onMouseEnter={e => e.currentTarget.style.background = "rgba(139,125,82,0.1)"} onMouseLeave={e => e.currentTarget.style.background = "rgba(255,255,255,0.8)"}>
            👍
          </button>
          <span style={{ fontWeight: 600, fontSize: 12, color: caption.votes > 0 ? "#2a7d2a" : caption.votes < 0 ? "#8a3030" : DARK, minWidth: 24, textAlign: "center" }}>
            {caption.votes > 0 ? "+" : ""}{caption.votes}
          </span>
          <button onClick={() => handleVote("down")} disabled={voting} style={{
            width: 28, height: 28, borderRadius: 6, border: "1px solid rgba(139,125,82,0.2)",
            background: "rgba(255,255,255,0.8)", cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center",
            transition: "all 0.2s ease", fontSize: 12,
          }} onMouseEnter={e => e.currentTarget.style.background = "rgba(139,125,82,0.1)"} onMouseLeave={e => e.currentTarget.style.background = "rgba(255,255,255,0.8)"}>
            👎
          </button>
        </div>

        {/* Copy & Delete */}
        <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
          <button onClick={handleCopy} style={{
            background: copied ? DARK : "rgba(45,45,43,0.08)", color: copied ? "#fff" : DARK,
            border: "1px solid rgba(45,45,43,0.2)", borderRadius: 6, padding: "5px 12px", fontSize: 11, cursor: "pointer",
          }}>{copied ? "✓" : "Copy"}</button>
          {isAdmin && (
            <button onClick={() => onDelete(caption.id)} style={{
              background: "rgba(200,70,70,0.1)", color: "#8a3030",
              border: "1px solid rgba(200,70,70,0.3)", borderRadius: 6, padding: "5px 12px", fontSize: 11, cursor: "pointer",
            }}>Delete</button>
          )}
        </div>
      </div>
    </div>
  );
}

/* ═══════════════════════════════════════════════════════════════
   PARSE RESPONSE
═══════════════════════════════════════════════════════════════ */
function parseResponse(text) {
  const sections = [];
  const re = /###\s*(.+)/g;
  let m, starts = [];
  while ((m = re.exec(text)) !== null) starts.push({ title: m[1].trim(), index: m.index });
  for (let i = 0; i < starts.length; i++) {
    const chunk = text.substring(starts[i].index, i + 1 < starts.length ? starts[i + 1].index : text.length);
    const opts = [], optRe = /\*\*Option\s*\d+\*\*/g;
    let om, os = [];
    while ((om = optRe.exec(chunk)) !== null) os.push(om.index + om[0].length);
    for (let j = 0; j < os.length; j++) {
      const t = chunk.substring(os[j], j + 1 < os.length ? chunk.lastIndexOf("**Option", os[j + 1]) : chunk.length).trim();
      if (t.length > 10) opts.push(t);
    }
    if (opts.length) sections.push({ title: starts[i].title, options: opts });
  }
  return sections;
}

/* ═══════════════════════════════════════════════════════════════
   LOGIN SCREEN
═══════════════════════════════════════════════════════════════ */
function LoginScreen({ onSuccess }) {
  const [pw, setPw] = useState("");
  const [err, setErr] = useState("");
  const [busy, setBusy] = useState(false);

  const submit = async () => {
    if (!pw.trim()) return;
    setBusy(true); setErr("");
    try {
      const r = await fetch("/api/login", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ password: pw }) });
      const d = await r.json();
      if (r.ok) onSuccess(d.role);
      else setErr(d.error || "Incorrect password.");
    } catch { setErr("Connection error."); }
    finally { setBusy(false); }
  };

  return (
    <div style={{ minHeight: "100vh", display: "flex", alignItems: "center", justifyContent: "center", background: BG, padding: 24 }}>
      <div style={{ background: "rgba(255,255,255,0.5)", backdropFilter: "blur(20px)", borderRadius: 24, border: "1px solid rgba(255,255,255,0.6)", padding: "56px 44px", maxWidth: 420, width: "100%", boxShadow: "0 4px 40px rgba(45,45,43,0.05)", textAlign: "center", animation: "fadeUp 0.5s ease" }}>
        <div style={{ fontSize: 11, letterSpacing: "0.3em", textTransform: "uppercase", color: GOLD, fontWeight: 600, marginBottom: 12 }}>Team Access</div>
        <h1 style={{ fontFamily: "'Roboto', sans-serif", fontSize: 36, fontWeight: 700, color: DARK, margin: 0, lineHeight: 1.1 }}>Arsova Caption</h1>
        <h1 style={{ fontFamily: "'Roboto', sans-serif", fontSize: 36, fontWeight: 700, color: DARK, margin: "0 0 32px", lineHeight: 1.1, fontStyle: "italic" }}>Generator</h1>
        <p style={{ color: "#6b6b68", fontSize: 15, marginBottom: 28 }}>Enter the team password to continue.</p>
        <input type="password" placeholder="Password" value={pw} autoFocus onChange={e => { setPw(e.target.value); setErr(""); }} onKeyDown={e => e.key === "Enter" && submit()} style={{ ...inputStyle, textAlign: "center", fontSize: 15, padding: "16px 20px", marginBottom: 8, border: err ? "1.5px solid rgba(200,70,70,0.5)" : inputStyle.border }} />
        {err && <p style={{ color: "#c44", fontSize: 12, marginBottom: 4, fontWeight: 500 }}>{err}</p>}
        <button onClick={submit} disabled={!pw.trim() || busy} style={{ ...goldBtn(pw.trim() && !busy), width: "100%", marginTop: 12 }}>
          {busy ? <span style={{ display: "inline-flex", alignItems: "center", gap: 8 }}><span style={spinner(16)} />Verifying...</span> : "Enter"}
        </button>
      </div>
    </div>
  );
}

/* ═══════════════════════════════════════════════════════════════
   MAIN APP
═══════════════════════════════════════════════════════════════ */
function App() {
  const [authed, setAuthed] = useState(false);
  const [role, setRole] = useState(null);
  const [checking, setChecking] = useState(true);
  const [page, setPage] = useState("generator");

  useEffect(() => {
    fetch("/api/session").then(r => r.json()).then(d => {
      if (d.authenticated) {
        setAuthed(true);
        setRole(d.role);
      }
    }).catch(() => {}).finally(() => setChecking(false));
  }, []);

  const handleLogin = (userRole) => {
    setAuthed(true);
    setRole(userRole);
  };

  const handleLogout = () => {
    setAuthed(false);
    setRole(null);
  };

  if (checking) return (
    <div style={{ minHeight: "100vh", display: "flex", alignItems: "center", justifyContent: "center", background: BG }}>
      <span style={{ ...spinner(28), borderColor: "rgba(139,125,82,0.2)", borderTopColor: GOLD }} />
    </div>
  );
  if (!authed) return <LoginScreen onSuccess={handleLogin} />;

  const doLogout = async () => {
    await fetch("/api/logout", { method: "POST" }).catch(() => {});
    handleLogout();
  };

  return (
    <div style={{ minHeight: "100vh", background: BG }}>
      {/* Navigation */}
      <nav style={{ display: "flex", justifyContent: "center", gap: 12, padding: "24px 20px 0" }}>
        <button onClick={() => setPage("generator")} style={navLink(page === "generator")}>✨ Generator</button>
        <button onClick={() => setPage("history")} style={navLink(page === "history")}>📋 History</button>
        <button onClick={doLogout} style={{ ...navLink(false), background: "rgba(200,70,70,0.1)", color: "#8a3030", border: "1px solid rgba(200,70,70,0.3)" }}>Logout</button>
      </nav>

      {page === "generator"
        ? <Generator />
        : <HistoryPage isAdmin={role === "admin"} />}
    </div>
  );
}

/* ═══════════════════════════════════════════════════════════════
   GENERATOR PAGE
═══════════════════════════════════════════════════════════════ */
function Generator() {
  const [platform, setPlatform] = useState("");
  const [postType, setPostType] = useState("");
  const [services, setServices] = useState([]);
  const [customService, setCustomService] = useState("");
  const [clientStory, setClientStory] = useState("");
  const [products, setProducts] = useState("");
  const [seasonalTheme, setSeasonalTheme] = useState("");
  const [specialOffer, setSpecialOffer] = useState("");
  const [city, setCity] = useState("");
  const [salonName, setSalonName] = useState("");
  const [stylistName, setStylistName] = useState("");
  const [stylistUsername, setStylistUsername] = useState("");
  const [tone, setTone] = useState("");
  const [additionalNotes, setAdditionalNotes] = useState("");
  const [loading, setLoading] = useState(false);
  const [rawResponse, setRawResponse] = useState("");
  const [sections, setSections] = useState([]);
  const [error, setError] = useState("");
  const [generationId, setGenerationId] = useState(null);
  const [saved, setSaved] = useState(false);
  const resultsRef = useRef(null);

  const toggle = (s) => setServices(p => p.includes(s) ? p.filter(x => x !== s) : [...p, s]);
  const canSubmit = platform && postType && services.length > 0;

  const buildPrompt = () => {
    const all = [...services]; if (customService.trim()) all.push(customService.trim());
    let p = "Generate 9 social media captions for a hair salon post.\n\n";
    p += "**Platform:** " + platform + "\n";
    p += "**Post Type:** " + postType + "\n";
    p += "**Service/Style:** " + all.join(", ") + "\n";
    if (salonName) p += "**Salon Name:** " + salonName + "\n";
    if (stylistName) p += "**Stylist Name:** " + stylistName + "\n";
    if (stylistUsername) { const h = stylistUsername.startsWith("@") ? stylistUsername : "@" + stylistUsername; p += "**Stylist Username:** " + h + "\n"; }
    if (city) p += "**City/Location:** " + city + "\n";
    if (clientStory) p += "**Client Story/Inspiration:** " + clientStory + "\n";
    if (products) p += "**Products Used:** " + products + "\n";
    if (seasonalTheme) p += "**Seasonal Theme:** " + seasonalTheme + "\n";
    if (specialOffer) p += "**Special Offer/Promotion:** " + specialOffer + "\n";
    if (additionalNotes) p += "**Additional Notes:** " + additionalNotes + "\n";
    if (tone) {
      p += "\n**PREFERRED TONE:** " + tone + "\n";
      p += "Generate 5 captions in " + tone + " tone, plus 1 caption in each of the other 4 tones (9 total).";
    } else {
      p += "\nGenerate 9 captions distributed across all 5 tones (Fun & Playful, Luxurious & Elegant, Edgy & Bold, Warm & Friendly, Professional & Polished).";
    }
    return p;
  };

  const handleGenerate = async () => {
    if (!canSubmit) return;
    setLoading(true); setError(""); setRawResponse(""); setSections([]); setGenerationId(null); setSaved(false);

    const metadata = {
      platform, postType, services: services.join(", "), tone,
      salonName, stylistName, city
    };

    try {
      const res = await fetch("/api/generate", {
        method: "POST", headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ messages: [{ role: "user", content: buildPrompt() }], metadata }),
      });
      if (res.status === 401) { window.location.reload(); return; }
      const data = await res.json();
      if (!res.ok) throw new Error(data.error || "Generation failed.");
      const text = (data.content || []).map(b => b.type === "text" ? b.text : "").join("\n");
      if (!text) throw new Error("Empty response.");
      setRawResponse(text);
      const parsed = parseResponse(text);
      setSections(parsed);
      if (data.generationId) {
        setGenerationId(data.generationId);
        // Auto-save captions to database
        const captions = [];
        parsed.forEach(sec => {
          sec.options.forEach(opt => {
            captions.push({ toneGroup: sec.title.replace(/\s*\(Preferred\)/i, ''), text: opt });
          });
        });
        if (captions.length > 0) {
          fetch("/api/captions", {
            method: "POST", headers: { "Content-Type": "application/json" },
            body: JSON.stringify({ generationId: data.generationId, captions }),
          }).then(res => { if (res.ok) setSaved(true); }).catch(() => {});
        }
      }
      setTimeout(() => resultsRef.current?.scrollIntoView({ behavior: "smooth" }), 300);
    } catch (err) {
      setError(err.message || "Something went wrong.");
    } finally { setLoading(false); }
  };

  const handleSaveCaptions = async () => {
    if (!generationId || sections.length === 0) return;
    const captions = [];
    sections.forEach(sec => {
      sec.options.forEach(opt => {
        captions.push({ toneGroup: sec.title.replace(/\s*\(Preferred\)/i, ''), text: opt });
      });
    });
    try {
      const res = await fetch("/api/captions", {
        method: "POST", headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ generationId, captions }),
      });
      if (res.ok) setSaved(true);
    } catch (err) {
      console.error("Save error:", err);
    }
  };

  const reset = () => {
    setPlatform(""); setPostType(""); setServices([]); setCustomService("");
    setClientStory(""); setProducts(""); setSeasonalTheme(""); setSpecialOffer("");
    setCity(""); setSalonName(""); setStylistName(""); setStylistUsername("");
    setTone(""); setAdditionalNotes(""); setRawResponse(""); setSections([]); setError("");
    setGenerationId(null); setSaved(false);
  };

  return (
    <>
      {/* Loading Overlay */}
      {loading && <LoadingOverlay />}

      {/* Header */}
      <div style={{ padding: "32px 24px 0", textAlign: "center" }}>
        <h1 style={{ fontFamily: "'Roboto', sans-serif", fontSize: "clamp(28px, 5vw, 44px)", fontWeight: 700, color: DARK, margin: 0, lineHeight: 1.1 }}>Arsova Caption Generator</h1>
        <p style={{ color: "#6b6b68", fontSize: 15, marginTop: 12, maxWidth: 400, marginLeft: "auto", marginRight: "auto" }}>
          Create scroll-stopping captions. Fill in the details and get 9 options across 3 tones.
        </p>
      </div>

      {/* Form */}
      <div style={{ maxWidth: 1100, margin: "32px auto", padding: "0 20px" }}>
        <div style={{ background: "rgba(255,255,255,0.45)", backdropFilter: "blur(20px)", borderRadius: 24, border: "1px solid rgba(255,255,255,0.6)", padding: "28px 32px", boxShadow: "0 4px 40px rgba(45,45,43,0.05)" }}>

          {/* Row 1: Platform & Post Type */}
          <div className="form-row" style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 24, marginBottom: 24 }}>
            {/* Step 1: Platform */}
            <div>
              <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 6 }}>
                <span style={stepBadge}>1</span><span style={sectionTitle}>Platform</span>
                <span style={{ color: "#c44", fontSize: 11, fontWeight: 500 }}>Required</span>
              </div>
              <div style={{ display: "flex", flexWrap: "wrap", gap: 8 }}>
                {PLATFORMS.map(p => <button key={p} onClick={() => setPlatform(p)} style={chipStyle(platform === p)}>{p}</button>)}
              </div>
            </div>

            {/* Step 2: Post Type */}
            <div>
              <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 6 }}>
                <span style={stepBadge}>2</span><span style={sectionTitle}>Post Type</span>
                <span style={{ color: "#c44", fontSize: 11, fontWeight: 500 }}>Required</span>
              </div>
              <div style={{ display: "flex", flexWrap: "wrap", gap: 8 }}>
                {POST_TYPES.map(t => <button key={t} onClick={() => setPostType(t)} style={chipStyle(postType === t)}>{t}</button>)}
              </div>
            </div>
          </div>

          {/* Row 2: Service & Details */}
          <div className="form-row" style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 24, marginBottom: 24 }}>
            {/* Step 3: Service */}
            <div>
              <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 6 }}>
                <span style={stepBadge}>3</span><span style={sectionTitle}>Service or Style</span>
                <span style={{ color: "#c44", fontSize: 11, fontWeight: 500 }}>Select at least 1</span>
              </div>
              <div style={{ display: "flex", flexWrap: "wrap", gap: 6, marginBottom: 10 }}>
                {SERVICES.map(s => <button key={s} onClick={() => toggle(s)} style={chipStyle(services.includes(s))}>{s}</button>)}
              </div>
              <input type="text" placeholder="Or type a custom service..." value={customService} onChange={e => setCustomService(e.target.value)} style={inputStyle} />
            </div>

            {/* Step 4: Details */}
            <div>
              <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 10 }}>
                <span style={stepBadge}>4</span><span style={sectionTitle}>Details</span>
                <span style={{ color: GOLD, fontSize: 11 }}>Optional</span>
              </div>
              <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10, marginBottom: 10 }}>
                <div><label style={labelStyle}>Salon Name</label><input type="text" placeholder="Arsova Salon" value={salonName} onChange={e => setSalonName(e.target.value)} style={inputStyle} /></div>
                <div><label style={labelStyle}>City</label><input type="text" placeholder="Chicago, IL" value={city} onChange={e => setCity(e.target.value)} style={inputStyle} /></div>
              </div>
              <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10, marginBottom: 10 }}>
                <div><label style={labelStyle}>Stylist Name</label><input type="text" placeholder="Sarah" value={stylistName} onChange={e => setStylistName(e.target.value)} style={inputStyle} /></div>
                <div><label style={labelStyle}>Stylist @</label><input type="text" placeholder="@sarah.styles" value={stylistUsername} onChange={e => setStylistUsername(e.target.value)} style={inputStyle} /></div>
              </div>
              <div style={{ marginBottom: 10 }}>
                <label style={labelStyle}>Client Story</label>
                <textarea placeholder="She wanted a dramatic change..." value={clientStory} onChange={e => setClientStory(e.target.value)} rows={2} style={{ ...inputStyle, resize: "vertical" }} />
              </div>
              <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10 }}>
                <div><label style={labelStyle}>Products</label><input type="text" placeholder="Olaplex, Redken" value={products} onChange={e => setProducts(e.target.value)} style={inputStyle} /></div>
                <div><label style={labelStyle}>Season/Theme</label><input type="text" placeholder="Summer vibes" value={seasonalTheme} onChange={e => setSeasonalTheme(e.target.value)} style={inputStyle} /></div>
              </div>
            </div>
          </div>

          {/* Row 3: Tone & Generate */}
          <div className="form-row" style={{ display: "grid", gridTemplateColumns: "1fr auto", gap: 24, alignItems: "end" }}>
            {/* Step 5: Tone */}
            <div>
              <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 6 }}>
                <span style={stepBadge}>5</span><span style={sectionTitle}>Preferred Tone</span>
                <span style={{ color: GOLD, fontSize: 11 }}>5 captions from this tone + 1 from each other</span>
              </div>
              <div style={{ display: "flex", flexWrap: "wrap", gap: 8 }}>
                {TONES.map(t => <button key={t} onClick={() => setTone(tone === t ? "" : t)} style={chipStyle(tone === t)}>{t}</button>)}
              </div>
            </div>

            {/* Generate */}
            <div style={{ display: "flex", flexDirection: "column", alignItems: "center" }}>
              <button onClick={handleGenerate} disabled={!canSubmit || loading} style={{ ...goldBtn(canSubmit && !loading), whiteSpace: "nowrap", padding: "16px 40px" }}>
                {loading ? <span style={{ display: "inline-flex", alignItems: "center", gap: 10 }}><span style={spinner(18)} />Generating...</span> : "✨ Generate Captions"}
              </button>
              {!canSubmit && <p style={{ color: "#9b9b96", fontSize: 11, marginTop: 8, textAlign: "center" }}>Select platform, post type, service</p>}
            </div>
          </div>
        </div>
      </div>

      {/* Error */}
      {error && (
        <div style={{ maxWidth: 1100, margin: "0 auto 32px", padding: "0 20px" }}>
          <div style={{ background: "rgba(200,70,70,0.08)", border: "1px solid rgba(200,70,70,0.2)", borderRadius: 16, padding: "16px 20px", color: "#8a3030", fontSize: 14 }}>{error}</div>
        </div>
      )}

      {/* Results */}
      {sections.length > 0 && (
        <div ref={resultsRef} style={{ maxWidth: 1400, margin: "0 auto 60px", padding: "0 20px" }}>
          <div style={{ textAlign: "center", marginBottom: 28 }}>
            <h2 style={{ fontFamily: "'Roboto', sans-serif", fontSize: 28, color: DARK, margin: 0 }}>Your Captions</h2>
            <p style={{ color: "#6b6b68", fontSize: 15, marginTop: 8 }}>{tone ? `5 in ${tone} + 1 from each other tone` : "Distributed across all tones"}</p>
            {saved && <p style={{ color: "#2a7d2a", fontSize: 15, marginTop: 12, fontWeight: 500 }}>✓ Auto-saved to history</p>}
          </div>

          <div className="caption-grid">
            {sections.flatMap((sec, si) =>
              sec.options.map((opt, oi) => <CaptionCard key={`${si}-${oi}`} text={opt} tone={sec.title.replace(/\s*\(Preferred\)/i, '')} />)
            )}
          </div>

          <div style={{ textAlign: "center", marginTop: 24 }}>
            <button onClick={reset} style={{ padding: "12px 32px", borderRadius: 100, border: "1.5px solid rgba(139,125,82,0.3)", background: "transparent", color: GOLD, fontSize: 15, fontWeight: 500, cursor: "pointer", textTransform: "uppercase" }}>Start Over</button>
          </div>
        </div>
      )}

      <div style={{ textAlign: "center", padding: "20px 24px 40px", color: "#9b9b96", fontSize: 11 }}>
        Powered by AI · Arsova Salon Caption Generator
      </div>
    </>
  );
}

/* ═══════════════════════════════════════════════════════════════
   PAGINATION COMPONENT
═══════════════════════════════════════════════════════════════ */
function Pagination({ page, totalPages, total, onPageChange }) {
  if (totalPages <= 1) return null;

  const getPageNumbers = () => {
    const pages = [];
    const showAround = 2;
    for (let i = 1; i <= totalPages; i++) {
      if (i === 1 || i === totalPages || (i >= page - showAround && i <= page + showAround)) {
        pages.push(i);
      } else if (pages[pages.length - 1] !== '...') {
        pages.push('...');
      }
    }
    return pages;
  };

  const btnStyle = (active, disabled) => ({
    padding: "8px 14px", borderRadius: 8, cursor: disabled ? "not-allowed" : "pointer",
    border: active ? "none" : "1px solid rgba(139,125,82,0.25)",
    background: active ? GOLD : disabled ? "rgba(139,125,82,0.05)" : "rgba(255,255,255,0.6)",
    color: active ? "#fff" : disabled ? "#b0ada5" : DARK,
    fontFamily: "'Roboto', sans-serif", fontSize: 15, fontWeight: active ? 600 : 400,
    transition: "all 0.2s ease", minWidth: 40,
  });

  return (
    <div style={{ display: "flex", alignItems: "center", justifyContent: "center", gap: 8, flexWrap: "wrap" }}>
      <button onClick={() => onPageChange(page - 1)} disabled={page === 1} style={btnStyle(false, page === 1)}>
        ← Prev
      </button>
      {getPageNumbers().map((p, i) => (
        p === '...'
          ? <span key={`ellipsis-${i}`} style={{ padding: "0 8px", color: "#9b9b96" }}>...</span>
          : <button key={p} onClick={() => onPageChange(p)} style={btnStyle(p === page, false)}>{p}</button>
      ))}
      <button onClick={() => onPageChange(page + 1)} disabled={page === totalPages} style={btnStyle(false, page === totalPages)}>
        Next →
      </button>
      <span style={{ marginLeft: 12, fontSize: 12, color: "#9b9b96" }}>
        Page {page} of {totalPages} ({total} total)
      </span>
    </div>
  );
}

/* ═══════════════════════════════════════════════════════════════
   HISTORY PAGE
═══════════════════════════════════════════════════════════════ */
function HistoryPage({ isAdmin }) {
  const [captions, setCaptions] = useState([]);
  const [loading, setLoading] = useState(true);
  const [filters, setFilters] = useState({ platforms: [], postTypes: [], tones: [] });
  const [platform, setPlatform] = useState("");
  const [postType, setPostType] = useState("");
  const [tone, setTone] = useState("");
  const [sortBy, setSortBy] = useState("highest");
  const [error, setError] = useState("");
  const [page, setPage] = useState(1);
  const [pagination, setPagination] = useState({ total: 0, totalPages: 1 });

  const fetchFilters = async () => {
    try {
      const res = await fetch("/api/filters");
      if (res.ok) {
        const data = await res.json();
        setFilters(data);
      }
    } catch (err) {
      console.error("Filters error:", err);
    }
  };

  const fetchCaptions = async (pageNum = page) => {
    setLoading(true); setError("");
    try {
      const params = new URLSearchParams();
      if (platform) params.set("platform", platform);
      if (postType) params.set("postType", postType);
      if (tone) params.set("tone", tone);
      params.set("sortBy", sortBy);
      params.set("page", pageNum);
      params.set("limit", 30);

      const res = await fetch("/api/captions?" + params.toString());
      if (res.status === 401) { window.location.reload(); return; }
      if (res.status === 503) { setError("Database not configured. Add POSTGRES_URL to enable history."); setLoading(false); return; }
      const data = await res.json();
      if (res.ok) {
        setCaptions(data.captions || []);
        if (data.pagination) setPagination(data.pagination);
      }
      else setError(data.error || "Failed to load.");
    } catch (err) {
      setError("Connection error.");
    } finally { setLoading(false); }
  };

  useEffect(() => { fetchFilters(); fetchCaptions(1); }, []);
  useEffect(() => { setPage(1); fetchCaptions(1); }, [platform, postType, tone, sortBy]);
  useEffect(() => { fetchCaptions(page); }, [page]);

  const handleVote = async (id, direction) => {
    try {
      const res = await fetch(`/api/captions/${id}/vote`, {
        method: "POST", headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ direction }),
      });
      if (res.ok) {
        const data = await res.json();
        // Auto-delete if votes reach -5 or below
        if (data.votes <= -5) {
          await fetch(`/api/captions/${id}`, { method: "DELETE" });
          setCaptions(prev => prev.filter(c => c.id !== id));
        } else {
          setCaptions(prev => prev.map(c => c.id === id ? { ...c, votes: data.votes } : c).sort((a, b) => sortBy === "highest" ? b.votes - a.votes : a.votes - b.votes));
        }
      }
    } catch (err) {
      console.error("Vote error:", err);
    }
  };

  const handleDelete = async (id) => {
    if (!confirm("Delete this caption permanently?")) return;
    try {
      const res = await fetch(`/api/captions/${id}`, { method: "DELETE" });
      if (res.ok) {
        setCaptions(prev => prev.filter(c => c.id !== id));
      }
    } catch (err) {
      console.error("Delete error:", err);
    }
  };

  return (
    <>
      {/* Header */}
      <div style={{ padding: "32px 24px 0", textAlign: "center" }}>
        <h1 style={{ fontFamily: "'Roboto', sans-serif", fontSize: "clamp(28px, 5vw, 44px)", fontWeight: 700, color: DARK, margin: 0, lineHeight: 1.1 }}>Previously Generated Captions</h1>
        <p style={{ color: "#6b6b68", fontSize: 15, marginTop: 12, maxWidth: 400, marginLeft: "auto", marginRight: "auto" }}>
          Browse, filter, and vote on your saved captions. Highest voted appear first.
        </p>
      </div>

      {/* Filters */}
      <div style={{ maxWidth: 1400, margin: "32px auto", padding: "0 20px" }}>
        <div style={{ background: "rgba(255,255,255,0.45)", backdropFilter: "blur(20px)", borderRadius: 16, border: "1px solid rgba(255,255,255,0.6)", padding: "20px 24px", marginBottom: 24 }}>
          <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(180px, 1fr))", gap: 16 }}>
            <div>
              <label style={labelStyle}>Platform</label>
              <select value={platform} onChange={e => setPlatform(e.target.value)} style={selectStyle}>
                <option value="">All Platforms</option>
                {filters.platforms.map(p => <option key={p} value={p}>{p}</option>)}
              </select>
            </div>
            <div>
              <label style={labelStyle}>Post Type</label>
              <select value={postType} onChange={e => setPostType(e.target.value)} style={selectStyle}>
                <option value="">All Types</option>
                {filters.postTypes.map(t => <option key={t} value={t}>{t}</option>)}
              </select>
            </div>
            <div>
              <label style={labelStyle}>Tone</label>
              <select value={tone} onChange={e => setTone(e.target.value)} style={selectStyle}>
                <option value="">All Tones</option>
                {filters.tones.map(t => <option key={t} value={t}>{t}</option>)}
              </select>
            </div>
            <div>
              <label style={labelStyle}>Sort by Rating</label>
              <select value={sortBy} onChange={e => setSortBy(e.target.value)} style={selectStyle}>
                <option value="highest">Highest</option>
                <option value="lowest">Lowest</option>
              </select>
            </div>
          </div>
        </div>

        {/* Pagination - Top */}
        {!loading && captions.length > 0 && (
          <div style={{ marginBottom: 20 }}>
            <Pagination page={page} totalPages={pagination.totalPages} total={pagination.total} onPageChange={setPage} />
          </div>
        )}

        {/* Error */}
        {error && (
          <div style={{ background: "rgba(200,70,70,0.08)", border: "1px solid rgba(200,70,70,0.2)", borderRadius: 16, padding: "16px 20px", color: "#8a3030", fontSize: 14, marginBottom: 24 }}>{error}</div>
        )}

        {/* Loading */}
        {loading && (
          <div style={{ textAlign: "center", padding: 40 }}>
            <span style={{ ...spinner(28), borderColor: "rgba(139,125,82,0.2)", borderTopColor: GOLD }} />
          </div>
        )}

        {/* Empty state */}
        {!loading && !error && captions.length === 0 && (
          <div style={{ textAlign: "center", padding: 60, color: "#9b9b96" }}>
            <p style={{ fontSize: 16, marginBottom: 8 }}>No captions saved yet.</p>
            <p style={{ fontSize: 15 }}>Generate some captions — they'll be saved automatically!</p>
          </div>
        )}

        {/* Captions grid */}
        {!loading && captions.length > 0 && (
          <div>
            <div className="caption-grid">
              {captions.map(cap => (
                <HistoryCaptionCard key={cap.id} caption={cap} onVote={handleVote} onDelete={handleDelete} isAdmin={isAdmin} />
              ))}
            </div>

            {/* Pagination - Bottom */}
            <div style={{ marginTop: 28 }}>
              <Pagination page={page} totalPages={pagination.totalPages} total={pagination.total} onPageChange={setPage} />
            </div>
          </div>
        )}
      </div>

      <div style={{ textAlign: "center", padding: "20px 24px 40px", color: "#9b9b96", fontSize: 11 }}>
        Powered by AI · Arsova Salon Caption Generator
      </div>
    </>
  );
}

/* ═══════════════════════════════════════════════════════════════
   RENDER APP
═══════════════════════════════════════════════════════════════ */
ReactDOM.createRoot(document.getElementById("root")).render(<App />);
