const { useState: useStateP, useEffect: useEffectP, useMemo: useMemoP } = React;

// ── helpers ────────────────────────────────────────────────────────────────────

function fmtDate(iso) {
  if (!iso) return "—";
  return new Date(iso).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
}

function fmtBudget(n) {
  return window.PipalData.compactCurrency(Number(n || 0));
}

function ctr(impressions, clicks) {
  if (!impressions) return "—";
  return ((clicks / impressions) * 100).toFixed(2) + "%";
}

function statusTone(s) {
  return s === "active" ? "pos" : s === "pending_review" ? "warn" : s === "paused" ? "accent" : "neg";
}

function statusLabel(s) {
  return s === "pending_review" ? "review" : s;
}

// ── Donut ──────────────────────────────────────────────────────────────────────

const Donut = ({ value, size = 52, stroke = 6 }) => {
  const r = (size - stroke) / 2;
  const circ = 2 * Math.PI * r;
  const pct = Math.min(1, Math.max(0, value || 0));
  return (
    <svg width={size} height={size} style={{ transform: "rotate(-90deg)" }}>
      <circle cx={size/2} cy={size/2} r={r} fill="none" stroke="var(--surface-3)" strokeWidth={stroke}/>
      <circle cx={size/2} cy={size/2} r={r} fill="none" stroke="var(--accent)" strokeWidth={stroke}
        strokeDasharray={circ} strokeDashoffset={circ * (1 - pct)} strokeLinecap="round"/>
    </svg>
  );
};

// ── ReviewCard ─────────────────────────────────────────────────────────────────

const ReviewCard = ({ campaign, ads, advertiserName, onApprove, onReject, acting }) => {
  const D = window.PipalData;
  const I = window.Icons;

  const creative = ads[0]?.creative || {};
  const targeting = campaign.targeting || {};

  return (
    <div className="panel" style={{ display: "flex", flexDirection: "column" }}>
      {/* Header */}
      <div style={{ padding: "16px 18px", borderBottom: "1px solid var(--hairline)" }}>
        <div style={{ display: "flex", alignItems: "flex-start", justifyContent: "space-between", gap: 12 }}>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" }}>
              <span style={{ fontWeight: 600, fontSize: 14, color: "var(--ink)" }}>{campaign.name}</span>
              <span className="chip warn dot">review</span>
              <span className="chip">{campaign.objective}</span>
            </div>
            <div style={{ fontSize: 11.5, color: "var(--ink-3)", marginTop: 4, fontFamily: "var(--font-mono)" }}>
              {advertiserName || campaign.advertiser_id.slice(0, 8)} · {campaign.advertiser_type}
              {" · submitted "}{fmtDate(campaign.created_at)}
            </div>
          </div>
          <div style={{ display: "flex", gap: 6, flexShrink: 0 }}>
            <button
              className="btn"
              style={{ background: "var(--neg-soft)", color: "var(--neg)", borderColor: "transparent", height: 30 }}
              onClick={() => onReject(campaign.id)}
              disabled={acting}
            >
              <I.x size={11} /> Reject
            </button>
            <button
              className="btn primary"
              style={{ height: 30 }}
              onClick={() => onApprove(campaign.id)}
              disabled={acting}
            >
              <I.check size={11} /> Approve
            </button>
          </div>
        </div>
      </div>

      {/* Details grid */}
      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 0, borderBottom: "1px solid var(--hairline)" }}>
        <MiniStat label="Daily budget" value={fmtBudget(campaign.daily_budget)} />
        <MiniStat label="Total budget" value={campaign.total_budget ? fmtBudget(campaign.total_budget) : "Uncapped"} />
        <MiniStat label="Schedule" value={fmtDate(campaign.start_date)} sub={campaign.end_date ? `→ ${fmtDate(campaign.end_date)}` : "No end date"} />
      </div>

      {/* Ads */}
      {ads.length > 0 && (
        <div style={{ padding: "12px 18px", borderBottom: "1px solid var(--hairline)" }}>
          <div style={{ fontSize: 10, fontFamily: "var(--font-mono)", color: "var(--ink-3)", letterSpacing: "0.06em", textTransform: "uppercase", marginBottom: 8 }}>
            {ads.length} ad{ads.length !== 1 ? "s" : ""}
          </div>
          <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
            {ads.map(ad => (
              <div key={ad.id} style={{ display: "flex", alignItems: "center", gap: 10, padding: "8px 10px", background: "var(--surface-2)", borderRadius: 5 }}>
                {ad.creative?.image_url && (
                  <img src={ad.creative.image_url} alt="" style={{ width: 48, height: 48, objectFit: "cover", borderRadius: 4, flexShrink: 0 }} />
                )}
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontSize: 12.5, fontWeight: 500, color: "var(--ink)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
                    {ad.creative?.title || ad.creative?.headline || "—"}
                  </div>
                  <div style={{ fontSize: 11, color: "var(--ink-3)", marginTop: 2 }}>
                    {ad.placement_type.replace(/_/g, " ")} · {ad.bid_type.toUpperCase()} Rs{ad.bid_amount}/1k
                  </div>
                </div>
                {ad.creative?.destination_url && (
                  <a href={ad.creative.destination_url} target="_blank" rel="noreferrer" className="btn ghost" style={{ height: 24, fontSize: 11, flexShrink: 0 }}>
                    <I.externalArrow size={10} /> Link
                  </a>
                )}
              </div>
            ))}
          </div>
        </div>
      )}

      {/* Targeting */}
      {Object.keys(targeting).length > 0 && (
        <div style={{ padding: "10px 18px" }}>
          <div style={{ fontSize: 10, fontFamily: "var(--font-mono)", color: "var(--ink-3)", letterSpacing: "0.06em", textTransform: "uppercase", marginBottom: 6 }}>Targeting</div>
          <div style={{ display: "flex", flexWrap: "wrap", gap: 5 }}>
            {Object.entries(targeting).flatMap(([k, v]) =>
              Array.isArray(v)
                ? v.map(item => <span key={k + item} className="chip" style={{ fontSize: 11 }}>{item}</span>)
                : <span key={k} className="chip" style={{ fontSize: 11 }}>{k}: {String(v)}</span>
            )}
          </div>
        </div>
      )}
    </div>
  );
};

const MiniStat = ({ label, value, sub }) => (
  <div style={{ padding: "12px 18px", borderRight: "1px solid var(--hairline)" }}>
    <div style={{ fontSize: 9.5, fontFamily: "var(--font-mono)", color: "var(--ink-3)", letterSpacing: "0.06em", textTransform: "uppercase" }}>{label}</div>
    <div style={{ fontSize: 15, fontWeight: 550, marginTop: 3, color: "var(--ink)", fontFeatureSettings: '"tnum" 1' }}>{value}</div>
    {sub && <div style={{ fontSize: 11, color: "var(--ink-3)", marginTop: 1 }}>{sub}</div>}
  </div>
);

// ── CampaignRow ────────────────────────────────────────────────────────────────

const CampaignRow = ({ c, ads, sel, onClick }) => {
  const D = window.PipalData;
  const totalImpressions = ads.reduce((s, a) => s + (a.impressions || 0), 0);
  const totalClicks = ads.reduce((s, a) => s + (a.clicks || 0), 0);
  const pct = c.total_budget ? Math.min(1, Number(c.spent_amount) / Number(c.total_budget)) : 0;

  return (
    <tr onClick={onClick} style={{ cursor: "pointer", background: sel ? "var(--surface-2)" : undefined }}>
      <td>
        <div style={{ fontWeight: 500, color: "var(--ink)", fontSize: 12.5 }}>{c.name}</div>
        <div className="id">{c.id.slice(0, 8).toUpperCase()}</div>
      </td>
      <td><span className="chip">{c.objective}</span></td>
      <td><span className={`chip dot ${statusTone(c.status)}`}>{statusLabel(c.status)}</span></td>
      <td>
        {c.total_budget ? (
          <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
            <div style={{ flex: 1, height: 5, background: "var(--surface-3)", borderRadius: 3, overflow: "hidden" }}>
              <div style={{ width: (pct * 100) + "%", height: "100%", background: pct > 0.85 ? "var(--warn)" : "var(--accent)" }} />
            </div>
            <span className="num muted" style={{ fontSize: 10.5 }}>{Math.round(pct * 100)}%</span>
          </div>
        ) : <span className="muted" style={{ fontSize: 11 }}>uncapped</span>}
      </td>
      <td className="num" style={{ textAlign: "right" }}>{D.compactCurrency(Number(c.spent_amount))}</td>
      <td className="num" style={{ textAlign: "right" }}>{totalImpressions.toLocaleString()}</td>
      <td className="num muted" style={{ textAlign: "right" }}>{ctr(totalImpressions, totalClicks)}</td>
      <td className="muted" style={{ textAlign: "right", fontSize: 11.5 }}>{fmtDate(c.end_date)}</td>
    </tr>
  );
};

// ── Shared input style ─────────────────────────────────────────────────────────

const iStyle = {
  width: "100%", height: 28, fontSize: 12, padding: "0 8px", boxSizing: "border-box",
  background: "var(--surface-2)", border: "1px solid var(--hairline)", borderRadius: 4,
  color: "var(--ink)", fontFamily: "inherit",
};

const EditSection = ({ label, children }) => (
  <div style={{ padding: "12px 14px", borderTop: "1px solid var(--hairline)" }}>
    <div style={{ fontSize: 10, fontFamily: "var(--font-mono)", color: "var(--ink-3)", letterSpacing: "0.06em", textTransform: "uppercase", marginBottom: 8 }}>{label}</div>
    {children}
  </div>
);

const EditRow = ({ label, children }) => (
  <div style={{ marginBottom: 8 }}>
    <div style={{ fontSize: 11, color: "var(--ink-3)", marginBottom: 3 }}>{label}</div>
    {children}
  </div>
);

// ── CampaignDetail ─────────────────────────────────────────────────────────────

const OBJECTIVES = ["awareness", "traffic", "conversions"];
const ADVERTISER_TYPES = ["seller", "brand", "individual"];
const PLACEMENT_TYPES = ["feed", "search_results", "product_detail", "home_banner", "category_page", "checkout"];
const BANNER_PLACEMENTS = ["home_banner", "category_page"];
function isBannerPlacement(p) { return BANNER_PLACEMENTS.includes(p); }
const BID_TYPES = ["cpm", "cpc", "cpa"];
const MEDIA_TYPES = ["image", "video", "text", "carousel"];
const ALL_SURFACES = ["feed", "search", "home", "product_detail", "category", "checkout"];

const CampaignDetail = ({ campaign, ads, advertiserName, onAction, onSave }) => {
  const D = window.PipalData;
  const I = window.Icons;
  const sb = window.supabaseClient;
  const [acting, setActing] = useStateP(false);
  const [editing, setEditing] = useStateP(false);
  const [saving, setSaving] = useStateP(false);
  const [saveError, setSaveError] = useStateP(null);
  const [form, setForm] = useStateP(null);
  const [adForms, setAdForms] = useStateP([]);
  const [newTargetKey, setNewTargetKey] = useStateP("");
  const [newTargetVal, setNewTargetVal] = useStateP("");

  const totalImpressions = ads.reduce((s, a) => s + (a.impressions || 0), 0);
  const totalClicks = ads.reduce((s, a) => s + (a.clicks || 0), 0);
  const totalSpend = ads.reduce((s, a) => s + Number(a.spend || 0), 0);
  const pct = campaign.total_budget ? Math.min(1, Number(campaign.spent_amount) / Number(campaign.total_budget)) : 0;

  const startEdit = () => {
    setForm({
      name: campaign.name,
      objective: campaign.objective,
      advertiser_type: campaign.advertiser_type,
      daily_budget: campaign.daily_budget,
      total_budget: campaign.total_budget ?? "",
      start_date: campaign.start_date ? campaign.start_date.slice(0, 10) : "",
      end_date: campaign.end_date ? campaign.end_date.slice(0, 10) : "",
      targeting: JSON.parse(JSON.stringify(campaign.targeting || {})),
    });
    setAdForms(ads.map(a => ({
      id: a.id,
      placement_type: a.placement_type || "feed",
      content_type: a.content_type || "",
      ad_format: a.ad_format || "",
      media_type: a.media_type || "image",
      surfaces: Array.isArray(a.surfaces) ? [...a.surfaces] : ["feed"],
      bid_type: a.bid_type || "cpm",
      bid_amount: a.bid_amount,
      title: a.creative?.title || a.creative?.headline || "",
      image_url: a.creative?.image_url || "",
      destination_url: a.creative?.destination_url || "",
      banner_height: a.creative?.banner_height || "",
    })));
    setSaveError(null);
    setNewTargetKey("");
    setNewTargetVal("");
    setEditing(true);
  };

  const cancelEdit = () => { setEditing(false); setForm(null); setAdForms([]); };

  const setF = (k, v) => setForm(f => ({ ...f, [k]: v }));
  const setAF = (id, k, v) => setAdForms(fs => fs.map(f => f.id === id ? { ...f, [k]: v } : f));
  const toggleSurface = (id, surf) => setAdForms(fs => fs.map(f => {
    if (f.id !== id) return f;
    const has = f.surfaces.includes(surf);
    return { ...f, surfaces: has ? f.surfaces.filter(s => s !== surf) : [...f.surfaces, surf] };
  }));

  const setTargetVal = (k, rawVal) => {
    const arr = rawVal.split(",").map(s => s.trim()).filter(Boolean);
    setForm(f => ({ ...f, targeting: { ...f.targeting, [k]: arr.length > 1 ? arr : rawVal } }));
  };
  const removeTargetKey = (k) => setForm(f => { const t = { ...f.targeting }; delete t[k]; return { ...f, targeting: t }; });
  const addTargetKey = () => {
    if (!newTargetKey.trim()) return;
    const arr = newTargetVal.split(",").map(s => s.trim()).filter(Boolean);
    setForm(f => ({ ...f, targeting: { ...f.targeting, [newTargetKey.trim()]: arr.length > 1 ? arr : newTargetVal } }));
    setNewTargetKey("");
    setNewTargetVal("");
  };

  const handleSave = async () => {
    setSaving(true);
    setSaveError(null);
    const campUpdate = {
      name: form.name,
      objective: form.objective,
      advertiser_type: form.advertiser_type,
      daily_budget: Number(form.daily_budget),
      total_budget: form.total_budget !== "" ? Number(form.total_budget) : null,
      start_date: form.start_date || null,
      end_date: form.end_date || null,
      targeting: form.targeting,
      updated_at: new Date().toISOString(),
    };
    const { error: ce } = await sb.from("ad_campaigns").update(campUpdate).eq("id", campaign.id);
    if (ce) { setSaveError(ce.message); setSaving(false); return; }
    for (const af of adForms) {
      const origCreative = ads.find(a => a.id === af.id)?.creative || {};
      const adUpdate = {
        placement_type: af.placement_type,
        content_type: af.content_type || null,
        ad_format: af.ad_format || null,
        media_type: af.media_type || null,
        surfaces: af.surfaces,
        bid_type: af.bid_type,
        bid_amount: Number(af.bid_amount),
        creative: { ...origCreative, title: af.title, headline: af.title, image_url: af.image_url, destination_url: af.destination_url, ...(af.banner_height ? { banner_height: Number(af.banner_height) } : {}) },
      };
      const { error: ae } = await sb.from("ads").update(adUpdate).eq("id", af.id);
      if (ae) { setSaveError(ae.message); setSaving(false); return; }
    }
    setSaving(false);
    setEditing(false);
    await onSave();
  };

  const doAction = async (action) => {
    setActing(true);
    await onAction(campaign.id, action);
    setActing(false);
  };

  if (editing && form) {
    return (
      <div className="panel" style={{ display: "flex", flexDirection: "column", overflow: "hidden" }}>
        <div className="panel-h">
          <span style={{ fontSize: 12.5, fontWeight: 550 }}>Edit campaign</span>
          <div className="right">
            <button className="btn ghost" style={{ height: 24 }} onClick={cancelEdit} disabled={saving}>Cancel</button>
          </div>
        </div>
        <div style={{ flex: 1, overflow: "auto" }}>
          <EditSection label="Campaign config">
            <EditRow label="Name">
              <input style={iStyle} value={form.name} onChange={e => setF("name", e.target.value)} />
            </EditRow>
            <EditRow label="Objective">
              <select style={iStyle} value={form.objective} onChange={e => setF("objective", e.target.value)}>
                {OBJECTIVES.map(o => <option key={o} value={o}>{o}</option>)}
              </select>
            </EditRow>
            <EditRow label="Advertiser type">
              <select style={iStyle} value={form.advertiser_type} onChange={e => setF("advertiser_type", e.target.value)}>
                {ADVERTISER_TYPES.map(t => <option key={t} value={t}>{t}</option>)}
              </select>
            </EditRow>
          </EditSection>

          <EditSection label="Budget &amp; schedule">
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8 }}>
              <EditRow label="Daily budget">
                <input style={iStyle} type="number" min="0" value={form.daily_budget} onChange={e => setF("daily_budget", e.target.value)} />
              </EditRow>
              <EditRow label="Total budget (blank = uncapped)">
                <input style={iStyle} type="number" min="0" value={form.total_budget} onChange={e => setF("total_budget", e.target.value)} placeholder="uncapped" />
              </EditRow>
              <EditRow label="Start date">
                <input style={iStyle} type="date" value={form.start_date} onChange={e => setF("start_date", e.target.value)} />
              </EditRow>
              <EditRow label="End date">
                <input style={iStyle} type="date" value={form.end_date} onChange={e => setF("end_date", e.target.value)} />
              </EditRow>
            </div>
          </EditSection>

          <EditSection label="Targeting">
            {Object.entries(form.targeting).map(([k, v]) => (
              <div key={k} style={{ display: "flex", gap: 6, marginBottom: 6, alignItems: "center" }}>
                <span style={{ fontSize: 11, fontFamily: "var(--font-mono)", color: "var(--ink-3)", whiteSpace: "nowrap", minWidth: 80 }}>{k}</span>
                <input
                  style={{ ...iStyle, flex: 1 }}
                  value={Array.isArray(v) ? v.join(", ") : String(v)}
                  onChange={e => setTargetVal(k, e.target.value)}
                  placeholder="comma-separated values"
                />
                <button className="btn ghost" style={{ height: 26, padding: "0 6px", flexShrink: 0, color: "var(--neg)" }} onClick={() => removeTargetKey(k)}>
                  <I.x size={10} />
                </button>
              </div>
            ))}
            <div style={{ display: "flex", gap: 6, marginTop: 4 }}>
              <input style={{ ...iStyle, width: 90 }} value={newTargetKey} onChange={e => setNewTargetKey(e.target.value)} placeholder="key" />
              <input style={{ ...iStyle, flex: 1 }} value={newTargetVal} onChange={e => setNewTargetVal(e.target.value)} placeholder="value(s)" />
              <button className="btn ghost" style={{ height: 28, padding: "0 8px", flexShrink: 0 }} onClick={addTargetKey}>+ Add</button>
            </div>
          </EditSection>

          {adForms.map((af, idx) => (
            <EditSection key={af.id} label={`Ad ${idx + 1}`}>
              <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8 }}>
                <EditRow label="Placement type">
                  <select style={iStyle} value={af.placement_type} onChange={e => setAF(af.id, "placement_type", e.target.value)}>
                    {PLACEMENT_TYPES.map(p => <option key={p} value={p}>{p.replace(/_/g, " ")}</option>)}
                  </select>
                </EditRow>
                <EditRow label="Content key / type">
                  <input style={iStyle} value={af.content_type} onChange={e => setAF(af.id, "content_type", e.target.value)} placeholder="e.g. product, category" />
                </EditRow>
                <EditRow label="Ad format">
                  <input style={iStyle} value={af.ad_format} onChange={e => setAF(af.id, "ad_format", e.target.value)} placeholder="banner, native…" />
                </EditRow>
                <EditRow label="Banner height">
                  <select style={iStyle} value={af.banner_height} onChange={e => setAF(af.id, "banner_height", e.target.value)}>
                    <option value="">— none —</option>
                    <option value="200">200px — small banner</option>
                    <option value="400">400px — large banner</option>
                  </select>
                </EditRow>
                <EditRow label="Media type">
                  <select style={iStyle} value={af.media_type} onChange={e => setAF(af.id, "media_type", e.target.value)}>
                    {MEDIA_TYPES.map(m => <option key={m} value={m}>{m}</option>)}
                  </select>
                </EditRow>
                <EditRow label="Bid type">
                  <select style={iStyle} value={af.bid_type} onChange={e => setAF(af.id, "bid_type", e.target.value)}>
                    {BID_TYPES.map(b => <option key={b} value={b}>{b.toUpperCase()}</option>)}
                  </select>
                </EditRow>
                <EditRow label="Bid amount (Rs/1k)">
                  <input style={iStyle} type="number" min="0" value={af.bid_amount} onChange={e => setAF(af.id, "bid_amount", e.target.value)} />
                </EditRow>
              </div>
              <EditRow label="Surfaces">
                <div style={{ display: "flex", flexWrap: "wrap", gap: 5, marginTop: 2 }}>
                  {ALL_SURFACES.map(surf => (
                    <label key={surf} style={{ display: "flex", alignItems: "center", gap: 4, cursor: "pointer", fontSize: 11.5 }}>
                      <input type="checkbox" checked={af.surfaces.includes(surf)} onChange={() => toggleSurface(af.id, surf)} style={{ accentColor: "var(--accent)" }} />
                      {surf}
                    </label>
                  ))}
                </div>
              </EditRow>
              <EditRow label="Creative title / headline">
                <input style={iStyle} value={af.title} onChange={e => setAF(af.id, "title", e.target.value)} />
              </EditRow>
              <EditRow label="Image URL">
                <input style={iStyle} value={af.image_url} onChange={e => setAF(af.id, "image_url", e.target.value)} placeholder="https://…" />
              </EditRow>
              <EditRow label="Destination URL">
                <input style={iStyle} value={af.destination_url} onChange={e => setAF(af.id, "destination_url", e.target.value)} placeholder="https://…" />
              </EditRow>
            </EditSection>
          ))}
        </div>
        <div style={{ padding: "10px 14px", borderTop: "1px solid var(--hairline)", display: "flex", flexDirection: "column", gap: 6 }}>
          {saveError && <div style={{ fontSize: 11.5, color: "var(--neg)" }}>{saveError}</div>}
          <button className="btn primary grow" onClick={handleSave} disabled={saving}>
            <I.check size={11} />{saving ? "Saving…" : "Save changes"}
          </button>
        </div>
      </div>
    );
  }

  return (
    <div className="panel" style={{ display: "flex", flexDirection: "column", overflow: "hidden" }}>
      <div className="panel-h">
        <span className="id" style={{ color: "var(--ink)" }}>{campaign.id.slice(0, 8).toUpperCase()}</span>
        <span className={`chip dot ${statusTone(campaign.status)}`} style={{ marginLeft: 6 }}>{statusLabel(campaign.status)}</span>
        <div className="right" style={{ display: "flex", alignItems: "center", gap: 8 }}>
          <span style={{ fontSize: 11, color: "var(--ink-3)", fontFamily: "var(--font-mono)" }}>{advertiserName}</span>
          <button className="btn ghost" style={{ height: 24 }} onClick={startEdit}>Edit</button>
        </div>
      </div>

      <div style={{ flex: 1, overflow: "auto" }}>
        <div style={{ padding: "14px" }}>
          <div style={{ fontSize: 15, fontWeight: 550, color: "var(--ink)", letterSpacing: "-0.01em" }}>{campaign.name}</div>
          <div className="muted" style={{ fontSize: 11.5, marginTop: 4 }}>
            {campaign.objective} · {campaign.advertiser_type}
            {campaign.end_date ? ` · ends ${fmtDate(campaign.end_date)}` : " · no end date"}
          </div>
        </div>

        <div style={{ padding: "0 14px 14px" }}>
          <div className="row gap-3" style={{ marginBottom: 8 }}>
            <div>
              <div style={{ fontFamily: "var(--font-mono)", fontSize: 9.5, color: "var(--ink-3)", letterSpacing: "0.06em", textTransform: "uppercase" }}>Spent</div>
              <div style={{ fontSize: 18, fontWeight: 550, marginTop: 2, fontFeatureSettings: '"tnum" 1' }}>{D.compactCurrency(Number(campaign.spent_amount))}</div>
            </div>
            {campaign.total_budget && (
              <div>
                <div style={{ fontFamily: "var(--font-mono)", fontSize: 9.5, color: "var(--ink-3)", letterSpacing: "0.06em", textTransform: "uppercase" }}>Budget</div>
                <div className="muted" style={{ fontSize: 18, fontWeight: 500, marginTop: 2, fontFeatureSettings: '"tnum" 1' }}>{D.compactCurrency(Number(campaign.total_budget))}</div>
              </div>
            )}
            <div style={{ marginLeft: "auto" }}>
              <Donut value={pct} size={52} stroke={6} />
            </div>
          </div>
        </div>

        <div style={{ padding: "14px", borderTop: "1px solid var(--hairline)" }}>
          <div style={{ fontSize: 10, fontFamily: "var(--font-mono)", color: "var(--ink-3)", letterSpacing: "0.06em", textTransform: "uppercase", marginBottom: 8 }}>Performance</div>
          <DetailRow k="Impressions" v={totalImpressions.toLocaleString()} />
          <DetailRow k="Clicks" v={totalClicks.toLocaleString()} />
          <DetailRow k="CTR" v={ctr(totalImpressions, totalClicks)} />
          <DetailRow k="Spend" v={D.compactCurrency(totalSpend)} />
          <DetailRow k="Daily budget" v={D.compactCurrency(Number(campaign.daily_budget))} />
        </div>

        <div style={{ padding: "14px", borderTop: "1px solid var(--hairline)" }}>
          <div style={{ fontSize: 10, fontFamily: "var(--font-mono)", color: "var(--ink-3)", letterSpacing: "0.06em", textTransform: "uppercase", marginBottom: 8 }}>Schedule</div>
          <DetailRow k="Start" v={fmtDate(campaign.start_date)} />
          <DetailRow k="End" v={fmtDate(campaign.end_date)} />
        </div>

        {Object.keys(campaign.targeting || {}).length > 0 && (
          <div style={{ padding: "14px", borderTop: "1px solid var(--hairline)" }}>
            <div style={{ fontSize: 10, fontFamily: "var(--font-mono)", color: "var(--ink-3)", letterSpacing: "0.06em", textTransform: "uppercase", marginBottom: 8 }}>Targeting</div>
            <div style={{ display: "flex", flexDirection: "column", gap: 4 }}>
              {Object.entries(campaign.targeting).map(([k, v]) => (
                <div key={k} style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 8, padding: "3px 0" }}>
                  <span style={{ fontSize: 11.5, color: "var(--ink-3)", fontFamily: "var(--font-mono)", whiteSpace: "nowrap" }}>{k}</span>
                  <span style={{ fontSize: 11.5, color: "var(--ink)", textAlign: "right" }}>
                    {Array.isArray(v) ? v.join(", ") : String(v)}
                  </span>
                </div>
              ))}
            </div>
          </div>
        )}

        {ads.length > 0 && (
          <div style={{ padding: "14px", borderTop: "1px solid var(--hairline)" }}>
            <div style={{ fontSize: 10, fontFamily: "var(--font-mono)", color: "var(--ink-3)", letterSpacing: "0.06em", textTransform: "uppercase", marginBottom: 8 }}>Ads ({ads.length})</div>
            {ads.map((ad, idx) => (
              <div key={ad.id} style={{ padding: "10px", background: "var(--surface-2)", borderRadius: 5, marginBottom: 8 }}>
                <div style={{ display: "flex", gap: 8, alignItems: "flex-start" }}>
                  {ad.creative?.image_url && (
                    <img src={ad.creative.image_url} alt="" style={{ width: 40, height: 40, objectFit: "cover", borderRadius: 4, flexShrink: 0 }} />
                  )}
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 12, fontWeight: 500, color: "var(--ink)" }}>{ad.creative?.title || ad.creative?.headline || `Ad ${idx + 1}`}</div>
                    <div style={{ fontSize: 11, color: "var(--ink-3)", marginTop: 2, fontFamily: "var(--font-mono)" }}>
                      {ad.placement_type.replace(/_/g, " ")} · {ad.bid_type.toUpperCase()} Rs{ad.bid_amount}/1k
                      {isBannerPlacement(ad.placement_type) && ad.creative?.banner_height ? ` · ${ad.creative.banner_height}px banner` : ""}
                    </div>
                    {Array.isArray(ad.surfaces) && ad.surfaces.length > 0 && (
                      <div style={{ display: "flex", flexWrap: "wrap", gap: 3, marginTop: 4 }}>
                        {ad.surfaces.map(s => <span key={s} className="chip" style={{ fontSize: 10 }}>{s}</span>)}
                      </div>
                    )}
                  </div>
                </div>
              </div>
            ))}
          </div>
        )}
      </div>

      <div style={{ padding: "10px 14px", borderTop: "1px solid var(--hairline)", display: "flex", gap: 6 }}>
        {campaign.status === "active" && (
          <button className="btn grow" onClick={() => doAction("pause")} disabled={acting}>
            <I.refresh size={11} /> Pause
          </button>
        )}
        {campaign.status === "paused" && (
          <button className="btn grow" onClick={() => doAction("resume")} disabled={acting}>
            <I.refresh size={11} /> Resume
          </button>
        )}
        {campaign.status === "pending_review" && (
          <>
            <button
              className="btn grow"
              style={{ background: "var(--neg-soft)", color: "var(--neg)", borderColor: "transparent" }}
              onClick={() => doAction("reject")}
              disabled={acting}
            >
              <I.x size={11} /> Reject
            </button>
            <button className="btn primary grow" onClick={() => doAction("approve")} disabled={acting}>
              <I.check size={11} /> Approve
            </button>
          </>
        )}
        {!["pending_review", "active", "paused"].includes(campaign.status) && (
          <span className="muted" style={{ fontSize: 12, padding: "0 4px" }}>No actions available</span>
        )}
      </div>
    </div>
  );
};

const DetailRow = ({ k, v }) => (
  <div style={{ display: "flex", justifyContent: "space-between", padding: "3px 0" }}>
    <span style={{ fontSize: 12.5, color: "var(--ink-2)" }}>{k}</span>
    <span className="num" style={{ fontSize: 12.5, fontWeight: 500, color: "var(--ink)" }}>{v}</span>
  </div>
);

// ── PromotionsPage ─────────────────────────────────────────────────────────────

const PromotionsPage = () => {
  const D = window.PipalData;
  const I = window.Icons;
  const sb = window.supabaseClient;

  const [campaigns, setCampaigns] = useStateP([]);
  const [ads, setAds] = useStateP([]);
  const [advertiserNames, setAdvertiserNames] = useStateP({});
  const [loading, setLoading] = useStateP(true);
  const [tab, setTab] = useStateP("review");
  const [selId, setSelId] = useStateP(null);
  const [acting, setActing] = useStateP(false);
  const [toast, setToast] = useStateP(null);

  // ── fetch ──────────────────────────────────────────────────────────────────

  const fetchAll = async () => {
    const [campRes, adsRes] = await Promise.all([
      sb.from("ad_campaigns").select("*").order("created_at", { ascending: false }),
      sb.from("ads").select("*"),
    ]);
    const cs = campRes.data || [];
    const as = adsRes.data || [];
    setCampaigns(cs);
    setAds(as);

    // fetch advertiser store names — pick earliest created store per seller
    const ids = [...new Set(cs.map(c => c.advertiser_id))];
    if (ids.length > 0) {
      const { data: stores } = await sb.from("stores").select("seller_id, name, created_at").in("seller_id", ids).order("created_at", { ascending: true });
      if (stores) {
        const map = {};
        stores.forEach(s => {
          if (!map[s.seller_id]) map[s.seller_id] = s.name;
        });
        setAdvertiserNames(map);
      }
    }

    if (!selId && cs.length > 0) {
      const pending = cs.find(c => c.status === "pending_review");
      setSelId((pending || cs[0]).id);
    }
    setLoading(false);
  };

  useEffectP(() => { if (sb) fetchAll(); }, []);

  // ── tabs ───────────────────────────────────────────────────────────────────

  const pending = useMemoP(() => campaigns.filter(c => c.status === "pending_review"), [campaigns]);
  const active  = useMemoP(() => campaigns.filter(c => c.status === "active"), [campaigns]);
  const paused  = useMemoP(() => campaigns.filter(c => c.status === "paused"), [campaigns]);
  const ended   = useMemoP(() => campaigns.filter(c => c.status === "ended" || c.status === "rejected"), [campaigns]);

  const tabList = [
    { id: "review",  label: "Review",  ct: pending.length, alert: pending.length > 0 },
    { id: "active",  label: "Active",  ct: active.length },
    { id: "paused",  label: "Paused",  ct: paused.length },
    { id: "ended",   label: "Ended",   ct: ended.length },
  ];

  const visibleCampaigns = useMemoP(() => {
    if (tab === "review")  return pending;
    if (tab === "active")  return active;
    if (tab === "paused")  return paused;
    if (tab === "ended")   return ended;
    return [];
  }, [tab, pending, active, paused, ended]);

  const selected = campaigns.find(c => c.id === selId) || null;
  const selectedAds = ads.filter(a => a.campaign_id === selId);

  // ── stats ──────────────────────────────────────────────────────────────────

  const totalSpend = useMemoP(() => campaigns.reduce((s, c) => s + Number(c.spent_amount || 0), 0), [campaigns]);
  const totalImpressions = useMemoP(() => ads.reduce((s, a) => s + (a.impressions || 0), 0), [ads]);
  const totalClicks = useMemoP(() => ads.reduce((s, a) => s + (a.clicks || 0), 0), [ads]);

  // ── actions ────────────────────────────────────────────────────────────────

  const showToast = (msg, tone = "pos") => {
    setToast({ msg, tone });
    setTimeout(() => setToast(null), 3000);
  };

  const handleAction = async (campaignId, action) => {
    setActing(true);
    let update = {};
    if (action === "approve") update = { status: "active", start_date: new Date().toISOString() };
    else if (action === "reject") update = { status: "rejected" };
    else if (action === "pause") update = { status: "paused" };
    else if (action === "resume") update = { status: "active" };

    const { error } = await sb.from("ad_campaigns").update(update).eq("id", campaignId);
    if (!error) await sb.from("ads").update({ status: update.status }).eq("campaign_id", campaignId);
    if (error) {
      showToast("Failed: " + (error.message || JSON.stringify(error)), "neg");
    } else {
      const labels = { approve: "Campaign approved", reject: "Campaign rejected", pause: "Campaign paused", resume: "Campaign resumed" };
      showToast(labels[action] || "Done");
      await fetchAll();
      if (action === "approve" || action === "reject") {
        // move selection to next pending
        const next = campaigns.find(c => c.status === "pending_review" && c.id !== campaignId);
        if (next) setSelId(next.id);
      }
    }
    setActing(false);
  };

  // ── render ─────────────────────────────────────────────────────────────────

  return (
    <div className="page" data-screen-label="06 Promotions">
      {/* Toast */}
      {toast && (
        <div style={{
          position: "fixed", bottom: 24, left: "50%", transform: "translateX(-50%)",
          zIndex: 200, padding: "10px 18px", borderRadius: 8,
          background: toast.tone === "neg" ? "var(--neg)" : "var(--ink)",
          color: "#fff", fontSize: 13, fontWeight: 500, boxShadow: "0 4px 16px rgba(0,0,0,0.18)",
          pointerEvents: "none",
        }}>{toast.msg}</div>
      )}

      <div className="page-h">
        <div>
          <div className="ts">
            {loading ? "Loading…" : `${active.length} active · ${pending.length} pending review · Rs ${D.compactCurrency(totalSpend)} total spend`}
          </div>
          <h1>Promotions</h1>
        </div>
      </div>

      {/* KPIs */}
      <div className="kpi-grid" style={{ gridTemplateColumns: "repeat(4,1fr)" }}>
        <div className="kpi">
          <div className="lbl">Active campaigns</div>
          <div className="val">{active.length}</div>
          <div className="sub"><span className="muted">{campaigns.length} total</span></div>
        </div>
        <div className="kpi">
          <div className="lbl">Total spend</div>
          <div className="val">{D.compactCurrency(totalSpend)}</div>
        </div>
        <div className="kpi">
          <div className="lbl">Impressions</div>
          <div className="val">{totalImpressions >= 1000 ? (totalImpressions/1000).toFixed(1)+"k" : totalImpressions}</div>
        </div>
        <div className="kpi">
          <div className="lbl">Avg CTR</div>
          <div className="val">{ctr(totalImpressions, totalClicks)}</div>
        </div>
      </div>

      {/* Tabs */}
      <div className="ftabs" style={{ marginTop: 14 }}>
        {tabList.map(t => (
          <div key={t.id} className={"ftab" + (tab === t.id ? " active" : "")} onClick={() => { setTab(t.id); }}>
            {t.label}
            <span className="ct" style={t.alert ? { background: "var(--warn)", color: "#000" } : undefined}>{t.ct}</span>
          </div>
        ))}
      </div>

      {loading ? (
        <div style={{ padding: 40, textAlign: "center", color: "var(--ink-3)", fontSize: 13 }}>Loading campaigns…</div>
      ) : tab === "review" && pending.length === 0 ? (
        <div className="panel" style={{ padding: 40, textAlign: "center", color: "var(--ink-3)", fontSize: 13, marginTop: 14 }}>
          No campaigns pending review
        </div>
      ) : tab === "review" ? (
        /* ── Review queue: full-width cards ────────────────────────────────── */
        <div style={{ display: "flex", flexDirection: "column", gap: 14, marginTop: 14 }}>
          {pending.map(c => (
            <ReviewCard
              key={c.id}
              campaign={c}
              ads={ads.filter(a => a.campaign_id === c.id)}
              advertiserName={advertiserNames[c.advertiser_id]}
              onApprove={(id) => handleAction(id, "approve")}
              onReject={(id) => handleAction(id, "reject")}
              acting={acting}
            />
          ))}
        </div>
      ) : (
        /* ── Active / Paused / Ended: table + detail ────────────────────────── */
        <div className="mob-stack" style={{ display: "grid", gridTemplateColumns: "1fr 340px", gap: 14, marginTop: 14 }}>
          <div className="panel" style={{ overflow: "hidden" }}>
            <div className="panel-h">
              <span>{visibleCampaigns.length} {tab} campaign{visibleCampaigns.length !== 1 ? "s" : ""}</span>
            </div>
            {visibleCampaigns.length === 0 ? (
              <div style={{ padding: 32, textAlign: "center", color: "var(--ink-3)", fontSize: 12 }}>No campaigns</div>
            ) : (
              <div className="t-wrap">
                <table className="t">
                  <thead>
                    <tr>
                      <th>Campaign</th>
                      <th>Objective</th>
                      <th>Status</th>
                      <th style={{ width: 140 }}>Budget</th>
                      <th style={{ textAlign: "right" }}>Spend</th>
                      <th style={{ textAlign: "right" }}>Impressions</th>
                      <th style={{ textAlign: "right" }}>CTR</th>
                      <th style={{ textAlign: "right" }}>Ends</th>
                    </tr>
                  </thead>
                  <tbody>
                    {visibleCampaigns.map(c => (
                      <CampaignRow
                        key={c.id}
                        c={c}
                        ads={ads.filter(a => a.campaign_id === c.id)}
                        sel={c.id === selId}
                        onClick={() => setSelId(c.id)}
                      />
                    ))}
                  </tbody>
                </table>
              </div>
            )}
          </div>

          {selected ? (
            <CampaignDetail
              campaign={selected}
              ads={selectedAds}
              advertiserName={advertiserNames[selected.advertiser_id]}
              onAction={handleAction}
              onSave={fetchAll}
            />
          ) : (
            <div className="panel" style={{ display: "flex", alignItems: "center", justifyContent: "center", color: "var(--ink-3)", fontSize: 13 }}>
              Select a campaign
            </div>
          )}
        </div>
      )}
    </div>
  );
};

window.PromotionsPage = PromotionsPage;
