// ─── Email Preview Tab (v3 — Save as Alert + Alert Management) ───
const SAVE_MSG_CLEAR_DELAY_MS = 3000;
const SERP_MONTHLY_LIMIT      = 3000;

function EmailPreview() {
  const { useState, useEffect, useCallback } = React;

  // Re-render on theme change
  const [, _themeRender] = useState(0);
  useEffect(() => {
    const h = () => _themeRender(n => n + 1);
    window.addEventListener("theme-change", h);
    return () => window.removeEventListener("theme-change", h);
  }, []);
  const t = window.activeTheme || window.theme || {};

  // ── State ──
  const [alerts, setAlerts] = useState([]);
  const [fullAlerts, setFullAlerts] = useState([]);  // full alert objects for management
  const [alertLimit, setAlertLimit] = useState(null);  // tier limit (null = unlimited)
  const [userRole, setUserRole] = useState("");
  const [selectedAlert, setSelectedAlert] = useState("");
  const [customMode, setCustomMode] = useState(false);

  // Search-style fields
  const [origin, setOrigin] = useState("MEM");
  const [destination, setDestination] = useState("");
  const [cabin, setCabin] = useState("J");
  const [maxMiles, setMaxMiles] = useState("");
  const [tripType, setTripType] = useState("round_trip");
  const [returnOrigin, setReturnOrigin] = useState("");
  const [returnDestination, setReturnDestination] = useState("");

  // Date range
  const [dateFrom, setDateFrom] = useState("");
  const [dateTo, setDateTo] = useState("");

  // Trip duration ranges
  const [minDays, setMinDays] = useState("");
  const [maxDays, setMaxDays] = useState("");

  // Open Jaw scope
  const [openJaw, setOpenJaw] = useState("same");

  // Max Stops
  const [maxStops, setMaxStops] = useState(1);

  // Filters
  const [selectedSources, setSelectedSources] = useState([]);
  const [selectedAirlines, setSelectedAirlines] = useState("");
  const [selectedBanks, setSelectedBanks] = useState([]);

  // Preview
  const [previewHtml, setPreviewHtml] = useState("");
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState("");

  // SerpApi usage
  const [serpUsage, setSerpUsage] = useState(null);

  // Save-as-alert state
  const [alertName, setAlertName] = useState("");
  const [alertEmail, setAlertEmail] = useState("");
  const [alertDuration, setAlertDuration] = useState("none");
  const [saving, setSaving] = useState(false);
  const [saveMsg, setSaveMsg] = useState("");
  const [editingAlertId, setEditingAlertId] = useState(null);  // null = new, string = editing existing

  // FlightAPI.io cash price enrichment
  const [enrichCash, setEnrichCash] = useState(false);
  const [flightApiStatus, setFlightApiStatus] = useState(null);

  // ── Load alerts helper ──
  const loadAlerts = useCallback(() => {
    (window.authFetch || fetch)("/api/alerts/my-list")
      .then(r => { if (!r.ok) throw new Error("Not authorized"); return r.json(); })
      .then(d => { setAlerts(d.alerts || []); })
      .catch(e => console.warn("Load alert list:", e));
    (window.authFetch || fetch)("/api/alerts/my")
      .then(r => { if (!r.ok) throw new Error("Not authorized"); return r.json(); })
      .then(d => {
        setFullAlerts(d.alerts || []);
        if (d.limit !== undefined) setAlertLimit(d.limit);
        if (d.role) setUserRole(d.role);
      })
      .catch(e => console.warn("Load alerts:", e));
  }, []);

  // ── Load saved alerts on mount ──
  useEffect(() => {
    loadAlerts();
    (window.authFetch || fetch)("/api/admin/serpapi-usage")
      .then(r => { if (!r.ok) throw new Error("Not authorized"); return r.json(); })
      .then(setSerpUsage)
      .catch(e => console.warn("Load SerpAPI usage:", e));
    // Pre-fill email from logged in user
    try {
      const token = window.authToken || localStorage.getItem("auth_token") || "";
      if (token) {
        const payload = JSON.parse(atob(token.split(".")[1]));
        if (payload.email) setAlertEmail(payload.email);
      }
    } catch (e) {}
    (window.authFetch || fetch)("/api/admin/flightapi-status")
      .then(r => { if (!r.ok) throw new Error("Not authorized"); return r.json(); })
      .then(setFlightApiStatus)
      .catch(e => console.warn("Load FlightAPI status:", e));
  }, []);

  // ── When a saved alert is chosen, populate custom fields ──
  const populateFromAlert = (alertName) => {
    const a = alerts.find(x => x.name === alertName);
    if (!a) return;
    setOrigin(a.origin || "");
    setDestination(a.destination || "");
    setCabin(a.cabin || "J");
    setMaxMiles(a.max_miles || "");
    setTripType(a.trip_type || "round_trip");
    setMinDays(a.min_days != null ? String(a.min_days) : "");
    setMaxDays(a.max_days != null ? String(a.max_days) : "");
    setOpenJaw(a.open_jaw || "same");
    setMaxStops(a.max_stops != null ? a.max_stops : 1);
    setDateFrom(a.date_start || "");
    setDateTo(a.date_end || "");
  };

  // ── Load alert into form for editing ──
  const loadAlertForEdit = (alert) => {
    setCustomMode(true);
    setEditingAlertId(alert.id);
    setAlertName(alert.name || "");
    setAlertEmail(alert.email || "");
    setOrigin(alert.origin || "");
    setDestination(alert.destination || "");
    setCabin(alert.cabin || "J");
    setMaxMiles(alert.max_miles ? String(alert.max_miles) : "");
    setTripType(alert.trip_type || "round_trip");
    setMinDays(alert.min_days != null ? String(alert.min_days) : "");
    setMaxDays(alert.max_days != null ? String(alert.max_days) : "");
    setOpenJaw(alert.open_jaw || "same");
    setMaxStops(alert.max_stops != null ? alert.max_stops : 1);
    setDateFrom(alert.date_start || "");
    setDateTo(alert.date_end || "");
    setSelectedSources(alert.programs ? alert.programs.split(",").map(s => s.trim()).filter(Boolean) : []);
    setSaveMsg("");
    // scroll to top
    window.scrollTo({ top: 0, behavior: "smooth" });
  };

  // ── Clear form for new alert ──
  const clearForm = () => {
    setEditingAlertId(null);
    setAlertName("");
    setOrigin("MEM");
    setDestination("");
    setCabin("J");
    setMaxMiles("");
    setTripType("round_trip");
    setReturnOrigin("");
    setReturnDestination("");
    setDateFrom("");
    setDateTo("");
    setMinDays("");
    setMaxDays("");
    setOpenJaw("same");
    setMaxStops(1);
    setSelectedSources([]);
    setSelectedAirlines("");
    setSelectedBanks([]);
    setAlertDuration("none");
    setSaveMsg("");
  };

  // ── Build query string & load preview ──
  const loadPreview = async (alertName) => {
    setLoading(true);
    setError("");
    setPreviewHtml("");
    try {
      const params = new URLSearchParams();
      if (alertName) {
        params.set("alert_name", alertName);
      } else {
        if (origin) params.set("origin", origin);
        if (destination) params.set("destination", destination);
        if (cabin) params.set("cabin", cabin);
        if (maxMiles) params.set("max_miles", maxMiles);
        if (tripType) params.set("trip_type", tripType);
        if (returnOrigin) params.set("return_origin", returnOrigin);
        if (returnDestination) params.set("return_destination", returnDestination);
        if (minDays) params.set("min_days", minDays);
        if (maxDays) params.set("max_days", maxDays);
        if (dateFrom) params.set("date_from", dateFrom);
        if (dateTo) params.set("date_to", dateTo);
        if (selectedSources.length) params.set("sources", selectedSources.join(","));
        if (selectedAirlines) params.set("airlines", selectedAirlines);
        if (openJaw && openJaw !== "same") params.set("open_jaw", openJaw);
        if (maxStops != null) params.set("max_stops", String(maxStops));
        if (origin) params.set("home_airport", origin.split(",")[0].trim());
      }
      // Always send banks and cash enrichment (applies to both saved alert and custom)
      if (selectedBanks.length) params.set("banks", selectedBanks.join(","));
      if (enrichCash) params.set("enrich_cash", "true");
      const resp = await (window.authFetch || fetch)(`/api/admin/email-preview?${params}`);
      if (resp.ok) {
        const html = await resp.text();
        setPreviewHtml(html);
      } else {
        const text = await resp.text();
        try {
          const err = JSON.parse(text);
          setError(err.error || err.detail || "Preview failed");
        } catch {
          setError(`Server error (${resp.status}): ${text.slice(0, 200)}`);
        }
      }
    } catch (e) {
      setError(e.message);
    }
    setLoading(false);
  };

  // ── Save current form as alert ──
  const saveAlert = async () => {
    if (!alertName.trim()) { setSaveMsg("Please enter an alert name"); return; }
    if (!origin || !destination) { setSaveMsg("Origin and destination are required"); return; }
    setSaving(true);
    setSaveMsg("");
    try {
      const body = {
        name: alertName.trim(),
        origin: origin,
        destination: destination,
        cabin: cabin,
        max_miles: maxMiles ? parseInt(maxMiles) : 999999,
        trip_type: tripType,
        min_days: minDays ? parseInt(minDays) : 7,
        max_days: maxDays ? parseInt(maxDays) : 21,
        open_jaw: openJaw,
        max_stops: maxStops,
        date_start: dateFrom || null,
        date_end: dateTo || null,
        email: alertEmail.trim(),
        programs: selectedSources.length ? selectedSources.join(",") : "",
        duration: alertDuration,
        active: true,
      };

      const isEdit = !!editingAlertId;
      const url = isEdit ? `/api/alerts/${editingAlertId}` : "/api/alerts";
      const method = isEdit ? "PUT" : "POST";

      const resp = await (window.authFetch || fetch)(url, {
        method,
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(body),
      });
      const data = await resp.json();
      if (resp.ok) {
        setSaveMsg(isEdit ? "Alert updated!" : "Alert saved!");
        setEditingAlertId(null);
        loadAlerts();
        // Auto-generate a name suggestion for next time
        setTimeout(() => setSaveMsg(""), SAVE_MSG_CLEAR_DELAY_MS);
      } else {
        setSaveMsg(data.error || "Save failed");
      }
    } catch (e) {
      setSaveMsg("Error: " + e.message);
    }
    setSaving(false);
  };

  // ── Delete alert ──
  const deleteAlert = async (id) => {
    if (!confirm("Delete this alert?")) return;
    try {
      await (window.authFetch || fetch)(`/api/alerts/${id}`, { method: "DELETE" });
      loadAlerts();
    } catch (e) { console.error("Delete failed:", e); }
  };

  // ── Toggle alert active/inactive ──
  const toggleAlert = async (id) => {
    try {
      await (window.authFetch || fetch)(`/api/alerts/${id}/toggle`, { method: "POST" });
      loadAlerts();
    } catch (e) { console.error("Toggle failed:", e); }
  };

  // ── Claim orphaned alerts (admin: assign NULL user_id alerts to me) ──
  const claimOrphans = async () => {
    try {
      const resp = await (window.authFetch || fetch)("/api/alerts/claim-orphans", { method: "POST" });
      const data = await resp.json();
      if (data.count > 0) {
        setSaveMsg(`Claimed ${data.count} orphaned alert(s)!`);
        loadAlerts();
      }
    } catch (e) { console.error("Claim failed:", e); }
  };

  // ── Programs / Sources reference ──
  const PROGRAMS_LIST = [
    { key: "aeroplan", name: "Air Canada Aeroplan" },
    { key: "flyingblue", name: "Air France/KLM Flying Blue" },
    { key: "alaska", name: "Alaska Atmos Rewards" },
    { key: "american", name: "American AAdvantage" },
    { key: "delta", name: "Delta SkyMiles" },
    { key: "emirates", name: "Emirates Skywards" },
    { key: "etihad", name: "Etihad Guest" },
    { key: "united", name: "United MileagePlus" },
    { key: "virgin", name: "Virgin Atlantic" },
    { key: "jetblue", name: "JetBlue TrueBlue" },
    { key: "southwest", name: "Southwest Rapid Rewards" },
    { key: "avianca", name: "Avianca LifeMiles" },
    { key: "turkish", name: "Turkish Miles&Smiles" },
    { key: "qantas", name: "Qantas Frequent Flyer" },
    { key: "cathay", name: "Cathay Pacific Asia Miles" },
    { key: "singapore", name: "Singapore KrisFlyer" },
    { key: "ana", name: "ANA Mileage Club" },
    { key: "jal", name: "JAL Mileage Bank" },
    { key: "british", name: "British Airways Avios" },
    { key: "iberia", name: "Iberia Avios" },
    { key: "quantas", name: "Qantas" },
    { key: "velocity", name: "Virgin Australia Velocity" },
    { key: "smiles", name: "GOL Smiles" },
    { key: "aeromexico", name: "Aeromexico Rewards" },
    { key: "copaairlines", name: "Copa ConnectMiles" },
  ];

  // Bank / transfer partner groups
  const BANK_PARTNERS = {
    "Chase Ultimate Rewards": { key: "chase", programs: ["united", "aeroplan", "flyingblue", "british", "singapore", "southwest", "jetblue", "iberia", "virgin", "emirates"] },
    "Amex Membership Rewards": { key: "amex", programs: ["delta", "aeroplan", "flyingblue", "british", "singapore", "ana", "cathay", "jetblue", "iberia", "virgin", "emirates", "avianca", "etihad"] },
    "Citi ThankYou": { key: "citi", programs: ["turkish", "singapore", "cathay", "flyingblue", "virgin", "jetblue", "avianca", "etihad", "qantas"] },
    "Capital One Miles": { key: "capital_one", programs: ["flyingblue", "british", "turkish", "singapore", "cathay", "avianca", "emirates", "etihad", "qantas", "aeromexico"] },
    "Bilt Rewards": { key: "bilt", programs: ["united", "aeroplan", "flyingblue", "british", "turkish", "cathay", "american", "alaska", "virgin", "emirates", "iberia"] },
    "Wells Fargo": { key: "wells_fargo", programs: ["flyingblue", "british", "avianca"] },
    "Rove": { key: "rove", programs: ["aeroplan", "flyingblue", "british", "turkish", "avianca", "etihad"] },
  };

  const toggleSource = (key) => {
    setSelectedSources(prev =>
      prev.includes(key) ? prev.filter(k => k !== key) : [...prev, key]
    );
  };

  const toggleBank = (bankKey) => {
    setSelectedBanks(prev =>
      prev.includes(bankKey) ? prev.filter(b => b !== bankKey) : [...prev, bankKey]
    );
  };

  const fillProgramsFromBank = (bankName) => {
    const bank = BANK_PARTNERS[bankName];
    if (!bank) return;
    setSelectedSources(bank.programs);
  };

  const addProgramsFromBank = (bankName) => {
    const bank = BANK_PARTNERS[bankName];
    if (!bank) return;
    setSelectedSources(prev => [...new Set([...prev, ...bank.programs])]);
  };

  const programsReachableViaSelectedBanks = React.useMemo(() => {
    const reachable = new Set();
    for (const [, bank] of Object.entries(BANK_PARTNERS)) {
      if (selectedBanks.includes(bank.key)) {
        bank.programs.forEach(p => reachable.add(p));
      }
    }
    return reachable;
  }, [selectedBanks]);

  // Cabin labels
  const cabinLabels = { F: "First", J: "Business", W: "Premium Econ", Y: "Economy" };

  // ── Inline styles (dynamic theme) ──
  const card = { background: t.surface, border: `1px solid ${t.border}`, borderRadius: 12, padding: 16, marginBottom: 12, overflow: "visible" };
  const labelStyle = { fontSize: 11, color: t.textDim, textTransform: "uppercase", letterSpacing: "0.05em", marginBottom: 4, display: "block" };
  const inputStyle = { background: t.card, border: `1px solid ${t.borderLight}`, borderRadius: 8, padding: "8px 12px", color: t.text, fontSize: 14, outline: "none", width: "100%", boxSizing: "border-box", fontFamily: "inherit" };
  const selectStyle = { ...inputStyle, appearance: "auto" };
  const btnPrimary = { background: t.accent, color: "#fff", border: "none", borderRadius: 8, padding: "10px 20px", fontSize: 14, fontWeight: 600, cursor: "pointer", transition: "background 0.15s", fontFamily: "inherit" };
  const btnPrimaryDisabled = { ...btnPrimary, background: t.border, color: t.textDim, cursor: "not-allowed" };
  const btnToggleActive = { background: t.accent, color: "#fff", border: "none", borderRadius: 8, padding: "6px 12px", fontSize: 13, fontWeight: 600, cursor: "pointer", transition: "background 0.15s", fontFamily: "inherit" };
  const btnToggleInactive = { background: t.card, color: t.textMuted, border: "none", borderRadius: 8, padding: "6px 12px", fontSize: 13, fontWeight: 600, cursor: "pointer", transition: "background 0.15s", fontFamily: "inherit" };
  const btnSmall = { padding: "5px 12px", fontSize: 12, fontWeight: 500, border: `1px solid ${t.borderLight}`, borderRadius: 6, cursor: "pointer", fontFamily: "inherit", transition: "all 0.15s" };
  const chipBase = { display: "inline-block", padding: "4px 10px", borderRadius: 6, fontSize: 12, fontWeight: 500, cursor: "pointer", transition: "all 0.15s", border: `1px solid ${t.borderLight}`, marginRight: 6, marginBottom: 6, userSelect: "none" };
  const chipActive = { ...chipBase, background: t.accent, color: "#fff", borderColor: t.accent };
  const chipInactive = { ...chipBase, background: t.card, color: t.textMuted, borderColor: t.borderLight };
  const sectionTitle = { fontSize: 13, fontWeight: 600, color: t.textMuted, marginBottom: 8, marginTop: 12 };
  const fieldGroup = { flex: 1, minWidth: 100 };
  const row = { display: "flex", gap: 12, alignItems: "flex-end", flexWrap: "wrap", overflow: "visible", position: "relative", zIndex: 10 };

  // Theme for AutocompleteInput
  const acTheme = { border: t.borderLight, accent: t.accent, text: t.text, textDim: t.textDim, bg: t.surface, hover: t.hover, card: t.card, cardBg: t.cardBg };

  return (
    <div style={{ maxWidth: 1200, margin: "0 auto", padding: "16px 0" }}>
      {/* ── Header with mode toggle ── */}
      <div style={card}>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 16 }}>
          <h3 style={{ fontSize: 18, fontWeight: 700, color: t.text, margin: 0 }}>
            Email Alerts
          </h3>
          <div style={{ display: "flex", gap: 8 }}>
            <button onClick={() => { setCustomMode(false); setEditingAlertId(null); }} style={!customMode ? btnToggleActive : btnToggleInactive}
            >Saved Alerts</button>
            <button onClick={() => { setCustomMode(true); }} style={customMode ? btnToggleActive : btnToggleInactive}
            >Custom Search</button>
          </div>
        </div>

        {!customMode ? (
          /* ── Saved alerts mode ── */
          <div>
            <div style={row}>
              <div style={{ flex: 1, minWidth: 250 }}>
                <label style={labelStyle}>Alert</label>
                <select value={selectedAlert || ""} onChange={e => { setSelectedAlert(e.target.value); populateFromAlert(e.target.value); }} style={selectStyle}>
                  <option value="">Select an alert...</option>
                  {alerts.map(a => (
                    <option key={a.id} value={a.name}>
                      {a.active ? "\u{1F7E2}" : "\u26AA"} {a.name} — {a.origin}{"\u2192"}{a.destination} ({cabinLabels[a.cabin] || a.cabin})
                    </option>
                  ))}
                </select>
              </div>
              <button onClick={() => loadPreview(selectedAlert)} disabled={!selectedAlert || loading} style={(!selectedAlert || loading) ? btnPrimaryDisabled : btnPrimary}>
                {loading ? "Loading..." : "Preview"}
              </button>
            </div>
          </div>
        ) : (
          /* ── Custom search mode — full search controls ── */
          <div>
            {/* Editing indicator */}
            {editingAlertId && (
              <div style={{ background: t.accent + "15", border: `1px solid ${t.accent}40`, borderRadius: 8, padding: "8px 16px", marginBottom: 12, display: "flex", justifyContent: "space-between", alignItems: "center" }}>
                <span style={{ fontSize: 13, color: t.accent }}>Editing: <strong>{alertName}</strong></span>
                <button onClick={() => { clearForm(); }} style={{ ...btnSmall, background: "transparent", color: t.textMuted, borderColor: t.border }}>Cancel Edit</button>
              </div>
            )}

            {/* Alert Name & Email row */}
            <div style={{ ...sectionTitle, marginTop: 0 }}>Alert Settings</div>
            <div style={row}>
              <div style={{ flex: 1, minWidth: 200 }}>
                <label style={labelStyle}>Alert Name</label>
                <input type="text" value={alertName} onChange={e => setAlertName(e.target.value)} placeholder="e.g. NYC to Tokyo Business" style={inputStyle} />
              </div>
              <div style={{ width: 250 }}>
                <label style={labelStyle}>Email (for notifications)</label>
                <input type="email" value={alertEmail} onChange={e => setAlertEmail(e.target.value)} placeholder="your@email.com" style={inputStyle} />
              </div>
              <div style={{ width: 130 }}>
                <label style={labelStyle}>Duration</label>
                <select value={alertDuration} onChange={e => setAlertDuration(e.target.value)} style={selectStyle}>
                  <option value="none">No Expiry</option>
                  <option value="1w">1 Week</option>
                  <option value="1m">1 Month</option>
                  <option value="3m">3 Months</option>
                  <option value="6m">6 Months</option>
                  <option value="1y">1 Year</option>
                </select>
              </div>
            </div>

            {/* Row 1: Origin / Destination / Cabin */}
            <div style={sectionTitle}>Route</div>
            <div style={{ ...row, zIndex: 50 }}>
              <div style={{ width: 220, position: "relative", zIndex: 200, overflow: "visible" }}>
                <label style={labelStyle}>Origin</label>
                <AutocompleteInput value={origin} onChange={setOrigin} placeholder="City, country, region, or IATA" theme={acTheme} />
              </div>
              <button type="button" onClick={() => { const tmp = origin; setOrigin(destination); setDestination(tmp); }} style={{ alignSelf: "flex-end", marginBottom: 2, padding: "4px 8px", color: t.textMuted, background: "transparent", border: "none", borderRadius: 6, fontSize: 18, cursor: "pointer" }} title="Swap origin and destination">{"\u21C4"}</button>
              <div style={{ width: 260, position: "relative", zIndex: 100, overflow: "visible" }}>
                <label style={labelStyle}>Destination</label>
                <AutocompleteInput value={destination} onChange={setDestination} placeholder="City, country, region, or IATA" theme={acTheme} />
              </div>
              <div style={{ width: 120 }}>
                <label style={labelStyle}>Cabin</label>
                <select value={cabin} onChange={e => setCabin(e.target.value)} style={selectStyle}>
                  <option value="F">First</option>
                  <option value="J">Business</option>
                  <option value="W">Premium Econ</option>
                  <option value="Y">Economy</option>
                </select>
              </div>
              <div style={{ width: 100 }}>
                <label style={labelStyle}>Max Miles</label>
                <input type="number" value={maxMiles} onChange={e => setMaxMiles(e.target.value)} placeholder="any" style={inputStyle} />
              </div>
            </div>

            {/* Row 2: Trip type / Return route */}
            <div style={sectionTitle}>Trip Type</div>
            <div style={{ ...row, zIndex: 40 }}>
              <div style={{ width: 140 }}>
                <label style={labelStyle}>Type</label>
                <select value={tripType} onChange={e => { setTripType(e.target.value); if (e.target.value === "open_jaw") setOpenJaw("country"); else if (e.target.value === "round_trip") setOpenJaw("same"); }} style={selectStyle}>
                  <option value="round_trip">Round Trip</option>
                  <option value="one_way">One Way</option>
                  <option value="open_jaw">Open Jaw</option>
                </select>
              </div>
              {(tripType === "round_trip" || tripType === "open_jaw") && (
                <>
                  <div style={{ width: 150 }}>
                    <label style={labelStyle}>Open Jaw Scope</label>
                    <select value={openJaw} onChange={e => setOpenJaw(e.target.value)} style={selectStyle}>
                      <option value="same">Same Airport</option>
                      <option value="country">Same Country</option>
                      <option value="continent">Same Continent</option>
                    </select>
                  </div>
                  <div style={{ width: 180 }}>
                    <label style={labelStyle}>Return Dest</label>
                    <AutocompleteInput value={returnDestination} onChange={setReturnDestination} placeholder="Same as origin" theme={acTheme} />
                  </div>
                  <div style={{ width: 180 }}>
                    <label style={labelStyle}>Return Origin</label>
                    <AutocompleteInput value={returnOrigin} onChange={setReturnOrigin} placeholder="Same as dest" theme={acTheme} />
                  </div>
                </>
              )}
            </div>

            {/* Row 3: Date Range & Trip Duration */}
            <div style={sectionTitle}>Dates & Duration</div>
            <div style={{ ...row, zIndex: 5 }}>
              <div style={{ width: 150 }}>
                <label style={labelStyle}>Depart After</label>
                <input type="date" value={dateFrom} onChange={e => setDateFrom(e.target.value)} style={inputStyle} />
              </div>
              <div style={{ width: 150 }}>
                <label style={labelStyle}>Depart Before</label>
                <input type="date" value={dateTo} onChange={e => setDateTo(e.target.value)} style={inputStyle} />
              </div>
              <div style={{ width: 90 }}>
                <label style={labelStyle}>Min Days</label>
                <input type="number" value={minDays} onChange={e => setMinDays(e.target.value)} placeholder="8" style={inputStyle} />
              </div>
              <div style={{ width: 90 }}>
                <label style={labelStyle}>Max Days</label>
                <input type="number" value={maxDays} onChange={e => setMaxDays(e.target.value)} placeholder="12" style={inputStyle} />
              </div>
              <button type="button" onClick={() => { setDateFrom(""); setDateTo(""); setMinDays(""); setMaxDays(""); }} style={{ alignSelf: "flex-end", marginBottom: 2, padding: "6px 12px", color: t.textMuted, background: t.card, border: `1px solid ${t.borderLight}`, borderRadius: 6, fontSize: 12, cursor: "pointer", fontFamily: "inherit" }}>Any Dates</button>
            </div>

            {/* Max Stops */}
            <div style={sectionTitle}>Max Stops</div>
            <div style={{ display: "flex", gap: 8, marginBottom: 4 }}>
              {[{ id: 0, label: "Nonstop" }, { id: 1, label: "1 Stop" }, { id: 2, label: "2 Stops" }].map(s => (
                <button key={s.id} onClick={() => setMaxStops(s.id)} style={{
                  padding: "6px 14px", borderRadius: 8, fontSize: 13, fontWeight: 600, cursor: "pointer",
                  border: `1.5px solid ${maxStops === s.id ? t.accent : t.borderLight}`,
                  background: maxStops === s.id ? t.accent + "18" : t.card,
                  color: maxStops === s.id ? t.accent : t.textMuted,
                  transition: "all 0.15s", fontFamily: "inherit",
                }}>{s.label}</button>
              ))}
            </div>

            {/* Row 4: Transfer Programs */}
            <div style={sectionTitle}>Transfer Programs <span style={{ fontWeight: 400, color: t.textDim, fontSize: 11 }}>— filter results to specific programs (empty = all)</span></div>
            <div style={{ display: "flex", gap: 6, flexWrap: "wrap", marginBottom: 6 }}>
              <span style={{ fontSize: 11, color: t.textDim, alignSelf: "center", marginRight: 2 }}>Quick fill:</span>
              {Object.entries(BANK_PARTNERS).map(([bankName, bank]) => (
                <button key={bankName} onClick={() => fillProgramsFromBank(bankName)}
                  style={{ padding: "3px 8px", fontSize: 11, fontWeight: 500, background: t.card, color: t.textMuted, border: `1px solid ${t.border}`, borderRadius: 4, cursor: "pointer", transition: "all 0.15s", fontFamily: "inherit" }}
                  title={`Select only ${bankName} partners`}
                >{bankName.split(" ")[0]}</button>
              ))}
              <button onClick={() => setSelectedSources([])} style={{ padding: "3px 8px", fontSize: 11, fontWeight: 500, background: t.card, color: t.textDim, border: `1px solid ${t.border}`, borderRadius: 4, cursor: "pointer", fontFamily: "inherit" }}>Clear</button>
              <button onClick={() => setSelectedSources(PROGRAMS_LIST.map(p => p.key))} style={{ padding: "3px 8px", fontSize: 11, fontWeight: 500, background: t.card, color: t.textDim, border: `1px solid ${t.border}`, borderRadius: 4, cursor: "pointer", fontFamily: "inherit" }}>All</button>
            </div>
            <div style={{ display: "flex", flexWrap: "wrap", gap: 0 }}>
              {PROGRAMS_LIST.map(p => {
                const isSelected = selectedSources.includes(p.key);
                const isReachable = programsReachableViaSelectedBanks.size > 0 && programsReachableViaSelectedBanks.has(p.key);
                const dimmed = selectedBanks.length > 0 && !isReachable && !isSelected;
                return (
                  <span key={p.key} onClick={() => toggleSource(p.key)}
                    style={{
                      ...chipBase,
                      ...(isSelected ? { background: t.accent, color: "#fff", borderColor: t.accent } : {}),
                      ...(dimmed ? { opacity: 0.4 } : {}),
                      ...(isReachable && !isSelected ? { borderColor: "rgba(16,185,129,0.4)" } : {}),
                    }}
                  >{p.name}</span>
                );
              })}
            </div>

            {/* Specific Airlines filter */}
            <div style={sectionTitle}>Specific Airlines (operating carrier)</div>
            <div style={row}>
              <div style={{ flex: 1 }}>
                <input type="text" value={selectedAirlines} onChange={e => setSelectedAirlines(e.target.value.toUpperCase())} placeholder="e.g. NH,JL,CX (IATA airline codes, comma-separated)" style={inputStyle} />
              </div>
            </div>

            {/* Action buttons: Preview + Save */}
            <div style={{ marginTop: 16, display: "flex", gap: 12, alignItems: "center", flexWrap: "wrap" }}>
              <button onClick={() => loadPreview(null)} disabled={(!origin || !destination) || loading} style={((!origin || !destination) || loading) ? btnPrimaryDisabled : btnPrimary}>
                {loading ? (enrichCash ? "Fetching Prices & Generating..." : "Generating Preview...") : (enrichCash ? "Generate with Cash Prices" : "Generate Email Preview")}
              </button>
              <button onClick={saveAlert} disabled={saving || !alertName.trim()} style={{
                ...btnPrimary,
                background: saving || !alertName.trim() ? t.border : t.success || "#10b981",
                color: saving || !alertName.trim() ? t.textDim : "#fff",
                cursor: saving || !alertName.trim() ? "not-allowed" : "pointer",
              }}>
                {saving ? "Saving..." : editingAlertId ? "Update Alert" : "Save as Alert"}
              </button>
              {saveMsg && (
                <span style={{ fontSize: 13, color: saveMsg.includes("!") ? (t.success || "#10b981") : (t.danger || "#ef4444"), fontWeight: 500 }}>
                  {saveMsg}
                </span>
              )}
            </div>
          </div>
        )}

        {error && (
          <div style={{ marginTop: 12, background: "rgba(127,29,29,0.3)", border: "1px solid #b91c1c", borderRadius: 8, padding: "8px 12px", color: "#fca5a5", fontSize: 14 }}>
            {error}
          </div>
        )}
      </div>

      {/* ── Preview Options (shared between saved alerts and custom mode) ── */}
      <div style={card}>
        <div style={sectionTitle}>Preview Options</div>
        {/* Bank Selection */}
        <div style={{ marginBottom: 10 }}>
          <label style={{ ...labelStyle, marginBottom: 6, display: "block" }}>My Banks <span style={{ fontWeight: 400, color: t.textDim, fontSize: 11 }}>— select cards you have for transfer cost display</span></label>
          <div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
            {Object.entries(BANK_PARTNERS).map(([bankName, bank]) => {
              const isActive = selectedBanks.includes(bank.key);
              return (
                <button key={bankName} onClick={() => toggleBank(bank.key)}
                  style={{
                    padding: "5px 12px", fontSize: 12, fontWeight: isActive ? 700 : 500,
                    background: isActive ? "rgba(16,185,129,0.15)" : t.card,
                    color: isActive ? "#10b981" : t.text,
                    border: isActive ? "1px solid rgba(16,185,129,0.4)" : `1px solid ${t.borderLight}`,
                    borderRadius: 6, cursor: "pointer", transition: "all 0.15s", fontFamily: "inherit"
                  }}
                >{bankName}</button>
              );
            })}
            <button onClick={() => setSelectedBanks([])} style={{ padding: "5px 12px", fontSize: 12, fontWeight: 500, background: t.card, color: t.textDim, border: `1px solid ${t.border}`, borderRadius: 6, cursor: "pointer", fontFamily: "inherit" }}>Clear</button>
          </div>
        </div>
        {/* Cash Price Toggle */}
        {flightApiStatus && flightApiStatus.configured && (
          <div>
            <label style={{ display: "flex", alignItems: "center", gap: 10, cursor: "pointer", padding: "8px 12px", background: enrichCash ? "rgba(59,130,246,0.1)" : t.card, border: enrichCash ? "1px solid rgba(59,130,246,0.4)" : `1px solid ${t.borderLight}`, borderRadius: 8, transition: "all 0.15s" }}>
              <input type="checkbox" checked={enrichCash} onChange={e => setEnrichCash(e.target.checked)} style={{ accentColor: t.accent, width: 16, height: 16 }} />
              <div>
                <div style={{ fontSize: 13, fontWeight: 600, color: enrichCash ? t.accent : t.text }}>Include Cash Prices</div>
                <div style={{ fontSize: 11, color: t.textDim, marginTop: 2 }}>
                  Compares award vs cash prices to calculate cents-per-point value.
                </div>
              </div>
            </label>
          </div>
        )}
      </div>

      {/* ── My Alerts — management section ── */}
      <div style={card}>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 12 }}>
          <h3 style={{ fontSize: 16, fontWeight: 700, color: t.text, margin: 0 }}>
            My Alerts ({fullAlerts.length}{alertLimit != null ? `/${alertLimit}` : ""})
          </h3>
          <div style={{ display: "flex", gap: 6, alignItems: "center" }}>
            {(userRole === "master_admin" || userRole === "admin") && fullAlerts.some(a => !a.user_id) && (
              <button onClick={claimOrphans} style={{ ...btnSmall, background: (t.warning || "#f59e0b") + "15", color: t.warning || "#f59e0b", borderColor: (t.warning || "#f59e0b") + "40" }}
                title="Adopt orphaned alerts (no owner) to your account">
                Claim Unowned
              </button>
            )}
            {alertLimit != null && fullAlerts.length >= alertLimit ? (
              <span style={{ fontSize: 11, color: t.warning || "#f59e0b", fontWeight: 600 }}>Limit reached — upgrade for more</span>
            ) : (
              <button onClick={() => { clearForm(); setCustomMode(true); }} style={{ ...btnSmall, background: t.accent + "15", color: t.accent, borderColor: t.accent + "40" }}>
                + New Alert
              </button>
            )}
          </div>
        </div>
        <div style={{ fontSize: 12, color: t.textDim, marginBottom: 12 }}>
          Active alerts run automatically after each daily ingestion and send results to your email.
        </div>
        {fullAlerts.length === 0 ? (
          <div style={{ textAlign: "center", padding: 32, color: t.textDim }}>
            <div style={{ fontSize: 32, marginBottom: 8 }}>{"🔔"}</div>
            <div>No alerts configured yet</div>
            <div style={{ fontSize: 12, marginTop: 4 }}>Use Custom Search above to create your first alert</div>
          </div>
        ) : (
          <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
            {fullAlerts.map(a => (
              <div key={a.id} style={{
                background: t.card,
                border: `1px solid ${a.active ? (t.accent + "40") : t.border}`,
                borderRadius: 10,
                padding: "12px 16px",
                display: "grid",
                gridTemplateColumns: "auto 1fr auto",
                gap: 12,
                alignItems: "center",
                opacity: a.active ? 1 : 0.6,
              }}>
                {/* Toggle */}
                <button onClick={() => toggleAlert(a.id)} style={{
                  width: 36, height: 20, borderRadius: 10, border: "none", cursor: "pointer",
                  background: a.active ? (t.success || "#10b981") : (t.border || "#333"),
                  position: "relative", transition: "background 0.2s",
                }}>
                  <span style={{
                    position: "absolute", top: 2, width: 16, height: 16, borderRadius: "50%",
                    background: "#fff", transition: "left 0.2s",
                    left: a.active ? 18 : 2,
                  }} />
                </button>
                {/* Info */}
                <div style={{ minWidth: 0, overflow: "hidden" }}>
                  <div style={{ fontWeight: 600, fontSize: 14, color: t.text, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{a.name}</div>
                  <div style={{ color: t.textMuted, fontSize: 12, marginTop: 2, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
                    {(() => {
                      const fmtCodes = (codes) => {
                        if (!codes) return "—";
                        const arr = codes.split(",").map(c => c.trim()).filter(Boolean);
                        if (arr.length <= 4) return arr.join(",");
                        return `${arr.slice(0, 3).join(",")}… (${arr.length} airports)`;
                      };
                      return `${fmtCodes(a.origin)} \u2192 ${fmtCodes(a.destination)} \u00B7 ${cabinLabels[a.cabin] || a.cabin} \u00B7 ${a.min_days}-${a.max_days} days`;
                    })()}
                    {a.max_stops != null && a.max_stops !== 1 ? ` \u00B7 ${a.max_stops === 0 ? "Nonstop" : a.max_stops + " stops"}` : ""}
                    {a.open_jaw && a.open_jaw !== "same" ? ` \u00B7 open jaw (${a.open_jaw})` : ""}
                    {a.email ? ` \u00B7 ${a.email}` : ""}
                    {a.date_start ? ` \u00B7 ${a.date_start}` : ""}
                    {a.date_end ? ` to ${a.date_end}` : ""}
                    {a.expires_at ? ` \u00B7 expires ${new Date(a.expires_at).toLocaleDateString()}` : ""}
                  </div>
                </div>
                {/* Actions */}
                <div style={{ display: "flex", gap: 6 }}>
                  <button onClick={() => { setSelectedAlert(a.name); setCustomMode(false); loadPreview(a.name); }} style={{ ...btnSmall, background: t.accent + "15", color: t.accent, borderColor: t.accent + "40" }}>👁 Preview</button>
                  <button onClick={() => { loadAlertForEdit(a); }} style={{ ...btnSmall, background: t.card, color: t.textMuted, borderColor: t.border }}>Edit</button>
                  <button onClick={() => deleteAlert(a.id)} style={{ ...btnSmall, background: t.card, color: t.danger || "#ef4444", borderColor: (t.danger || "#ef4444") + "40" }}>{"\u00D7"}</button>
                </div>
              </div>
            ))}
          </div>
        )}
      </div>

      {/* ── API Status Cards (admin only) ── */}
      {(userRole === "master_admin" || userRole === "admin") && (serpUsage || flightApiStatus) && (
        <div style={{ ...card, display: "flex", gap: 24, alignItems: "center", padding: "10px 16px", flexWrap: "wrap" }}>
          {serpUsage && (
            <>
              <span style={{ fontSize: 12, color: t.textDim }}>
                SerpApi: <strong style={{ color: t.text }}>{serpUsage.used_today || 0}</strong> / {serpUsage.daily_limit || 100} today
              </span>
              <span style={{ fontSize: 12, color: t.textDim }}>
                Monthly: <strong style={{ color: t.text }}>{serpUsage.used_month || 0}</strong> / {serpUsage.monthly_limit || SERP_MONTHLY_LIMIT}
              </span>
            </>
          )}
          {flightApiStatus && (
            <>
              <span style={{ fontSize: 12, color: t.textDim, borderLeft: serpUsage ? `1px solid ${t.border}` : "none", paddingLeft: serpUsage ? 16 : 0 }}>
                FlightAPI.io: <strong style={{ color: flightApiStatus.configured ? "#10b981" : "#ef4444" }}>{flightApiStatus.configured ? "Active" : "Not Configured"}</strong>
              </span>
              {flightApiStatus.configured && flightApiStatus.cache_entries > 0 && (
                <span style={{ fontSize: 12, color: t.textDim }}>
                  Cached: <strong style={{ color: t.text }}>{flightApiStatus.cache_entries}</strong> routes
                </span>
              )}
            </>
          )}
        </div>
      )}

      {/* ── Email Preview iframe — FULL WIDTH ── */}
      {previewHtml && (
        <div style={{ ...card, padding: 0, overflow: "hidden" }}>
          <div style={{ padding: "10px 16px", borderBottom: `1px solid ${t.border}`, display: "flex", justifyContent: "space-between", alignItems: "center" }}>
            <span style={{ fontSize: 13, fontWeight: 600, color: t.textMuted }}>
              Email Preview
            </span>
            <button onClick={() => { const w = window.open("", "_blank"); w.document.write(previewHtml); w.document.close(); }} style={{ padding: "4px 12px", fontSize: 12, background: t.card, color: t.textMuted, border: `1px solid ${t.borderLight}`, borderRadius: 6, cursor: "pointer", fontFamily: "inherit" }}>Open in New Tab</button>
          </div>
          <iframe
            srcDoc={previewHtml}
            style={{ width: "100%", height: "calc(100vh - 200px)", minHeight: 600, border: "none", background: "#fff" }}
            title="Email Preview"
          />
        </div>
      )}

      {/* Empty state */}
      {!previewHtml && !loading && !error && (
        <div style={{ ...card, display: "flex", alignItems: "center", justifyContent: "center", minHeight: 200, color: t.textDim, fontSize: 15 }}>
          <div style={{ textAlign: "center" }}>
            <div style={{ fontSize: 40, marginBottom: 12 }}>{"\u2709\uFE0F"}</div>
            <div>Select an alert or configure a custom search to preview the email</div>
          </div>
        </div>
      )}
    </div>
  );
}
