/* global React, Ic, Retailer, Spark, fluxActions, useFlux, fmtMoney, timeAgo, pctOff, Field, toast, CATEGORIES, RETAILER_LIST, DangerButton */
const { useState: useAS, useMemo: useAM } = React;

// ─────────────────────────────────────────────────────────────
// Dashboard — overview KPIs, recent ingests, delivery health
// ─────────────────────────────────────────────────────────────
function Dashboard({ go }) {
  const s = useFlux();
  const stats = useAM(() => {
    const now = Date.now();
    const last24 = s.discounts.filter((d) => now - new Date(d.created_at).getTime() < 864e5);
    const avgPct = s.discounts.length ? Math.round(s.discounts.reduce((a, d) => a + d.discount_pct, 0) / s.discounts.length) : 0;
    const dlv = s.deliveries;
    const failed = dlv.filter((d) => d.status === "failed").length;
    const okRate = dlv.length ? Math.round(((dlv.length - failed) / dlv.length) * 100) : 100;
    return { total: s.discounts.length, last24: last24.length, avgPct, activeKeys: s.apiKeys.filter((k) => !k.revoked).length, webhooks: s.webhooks.filter((w) => w.active).length, deliveries: dlv.length, failed, okRate };
  }, [s]);

  // ingest volume sparkline-ish: count per day bucket (last 14)
  const byDay = useAM(() => {
    const buckets = new Array(14).fill(0);
    const now = Date.now();
    s.discounts.forEach((d) => {
      const days = Math.floor((now - new Date(d.created_at).getTime()) / 864e5);
      if (days >= 0 && days < 14) buckets[13 - days]++;
    });
    return buckets;
  }, [s.discounts]);
  const maxDay = Math.max(1, ...byDay);

  const topRetailers = useAM(() => {
    const m = {};
    s.discounts.forEach((d) => { m[d.retailer] = (m[d.retailer] || 0) + 1; });
    return Object.entries(m).sort((a, b) => b[1] - a[1]).slice(0, 6);
  }, [s.discounts]);

  const recent = s.discounts.slice(0, 7);

  return (
    <div className="view-pad fade-in">
      <div className="sec-head">
        <h2>Overview</h2>
        <span className="desc">Ingestion, storage &amp; delivery at a glance</span>
        <span className="spacer" />
        <button className="btn primary" onClick={() => go("add")}><Ic.plus className="ico" />Add discount</button>
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "repeat(5, 1fr)", gap: 12, marginBottom: 18 }}>
        <div className="kpi"><div className="label">Discounts stored</div><div className="value">{stats.total.toLocaleString()}</div><div className="delta">+{stats.last24} in last 24h</div></div>
        <div className="kpi"><div className="label">Avg discount</div><div className="value indigo">{stats.avgPct}%</div><div className="delta">across all live deals</div></div>
        <div className="kpi"><div className="label">Active API keys</div><div className="value green">{stats.activeKeys}</div><div className="delta">scrapers authorised</div></div>
        <div className="kpi"><div className="label">Active webhooks</div><div className="value">{stats.webhooks}</div><div className="delta">Discord channels</div></div>
        <div className="kpi"><div className="label">Delivery success</div><div className={`value ${stats.failed ? "yellow" : "green"}`}>{stats.okRate}%</div><div className="delta">{stats.failed} failed of {stats.deliveries}</div></div>
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "1.6fr 1fr", gap: 18, marginBottom: 18 }}>
        <div className="card" style={{ padding: 18 }}>
          <div style={{ display: "flex", justifyContent: "space-between", marginBottom: 14 }}>
            <div><div style={{ fontSize: 13, fontWeight: 600 }}>Ingest volume · last 14 days</div><div style={{ fontSize: 11.5, color: "var(--text-3)" }}>New discounts received per day</div></div>
          </div>
          <div style={{ display: "flex", alignItems: "flex-end", gap: 6, height: 150 }}>
            {byDay.map((v, i) => (
              <div key={i} style={{ flex: 1, height: "100%", display: "flex", flexDirection: "column", justifyContent: "flex-end" }} title={`${v} discounts`}>
                <div style={{ height: `${(v / maxDay) * 100}%`, minHeight: v ? 4 : 0, background: "linear-gradient(180deg, var(--indigo), rgba(99,102,241,.35))", borderRadius: "3px 3px 0 0" }} />
              </div>
            ))}
          </div>
          <div style={{ display: "flex", justifyContent: "space-between", marginTop: 8, fontSize: 10, color: "var(--text-3)", fontFamily: "var(--mono)" }}>
            <span>14d ago</span><span>7d ago</span><span>today</span>
          </div>
        </div>

        <div className="card" style={{ padding: 18 }}>
          <div style={{ fontSize: 13, fontWeight: 600, marginBottom: 14 }}>Top retailers</div>
          <div style={{ display: "flex", flexDirection: "column", gap: 11 }}>
            {topRetailers.map(([name, count]) => {
              const max = topRetailers[0][1];
              return (
                <div key={name} style={{ display: "grid", gridTemplateColumns: "1fr 90px auto", gap: 12, alignItems: "center" }}>
                  <Retailer name={name} />
                  <div style={{ height: 5, background: "var(--elev-2)", borderRadius: 99, overflow: "hidden" }}>
                    <div style={{ width: `${(count / max) * 100}%`, height: "100%", background: "var(--indigo)" }} />
                  </div>
                  <div className="mono" style={{ fontSize: 11.5, color: "var(--text-2)", textAlign: "right", width: 26 }}>{count}</div>
                </div>
              );
            })}
          </div>
        </div>
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "1.5fr 1fr", gap: 18 }}>
        <div className="card" style={{ padding: 0 }}>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", padding: "14px 18px", borderBottom: "1px solid var(--border)" }}>
            <div style={{ fontSize: 13, fontWeight: 600 }}>Recently ingested</div>
            <button className="btn ghost sm" onClick={() => go("discounts")}>View all <Ic.arrowRight className="ico" /></button>
          </div>
          <table className="tbl">
            <thead><tr><th>Product</th><th>Retailer</th><th>Off</th><th>Source</th><th>When</th></tr></thead>
            <tbody>
              {recent.map((d) => (
                <tr key={d.id} style={{ cursor: "pointer" }} onClick={() => go("detail", d.id)}>
                  <td>{d.title}</td>
                  <td><Retailer name={d.retailer} /></td>
                  <td><span className="pill indigo">{d.discount_pct}%</span></td>
                  <td><span className="mono-sm">{d.source}</span></td>
                  <td className="muted">{timeAgo(d.created_at)}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>

        <div className="card" style={{ padding: 0 }}>
          <div style={{ padding: "14px 18px", borderBottom: "1px solid var(--border)", display: "flex", justifyContent: "space-between", alignItems: "center" }}>
            <div style={{ fontSize: 13, fontWeight: 600 }}>Recent deliveries</div>
            <button className="btn ghost sm" onClick={() => go("webhooks")}>Webhooks <Ic.arrowRight className="ico" /></button>
          </div>
          <div style={{ padding: 6 }}>
            {s.deliveries.slice(0, 6).map((x) => (
              <div key={x.id} style={{ display: "flex", gap: 10, padding: "10px 12px", alignItems: "center", borderBottom: "1px solid var(--border)" }}>
                <Ic.discord style={{ width: 16, height: 16, color: "var(--text-3)", flexShrink: 0 }} />
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontSize: 12, color: "var(--text)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{x.discountTitle}</div>
                  <div style={{ fontSize: 11, color: "var(--text-3)", marginTop: 2 }}>{x.webhookName} · {timeAgo(x.ts)}</div>
                </div>
                <window.DeliveryPill status={x.status} code={x.code} />
              </div>
            ))}
            {s.deliveries.length === 0 && <div style={{ padding: 20, color: "var(--text-3)", fontSize: 13, textAlign: "center" }}>No deliveries yet</div>}
          </div>
        </div>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Add / Edit discount
// ─────────────────────────────────────────────────────────────
function blank() {
  return { title: "", retailer: "Target AU", category: "Sneakers", url: "", image: "", price_original: "", price_sale: "", currency: "AUD", code: "", description: "", expires_at: "", status: "active" };
}
function DiscountForm({ id, go }) {
  const s = useFlux();
  const editing = !!id;
  const existing = editing ? s.discounts.find((x) => x.id === id) : null;
  const [f, setF] = useAS(() => existing ? { ...existing, price_original: existing.price_original ?? "", price_sale: existing.price_sale ?? "", expires_at: existing.expires_at ? existing.expires_at.slice(0, 10) : "" } : blank());
  const set = (k, v) => setF((p) => ({ ...p, [k]: v }));
  const pct = pctOff(Number(f.price_original) || 0, Number(f.price_sale) || 0);

  const save = async () => {
    if (!f.title.trim()) return toast("Title is required", "error");
    if (!f.url.trim() || !/^https?:\/\//.test(f.url)) return toast("A valid http(s) URL is required", "error");
    if (f.price_sale === "" || isNaN(Number(f.price_sale))) return toast("Sale price is required", "error");
    const newId = await fluxActions.upsertDiscount({ ...f, expires_at: f.expires_at || null });
    if (!newId) return;
    toast(editing ? "Discount updated" : "Discount added", "success");
    go("detail", editing ? id : newId);
  };

  return (
    <div className="view-pad fade-in" style={{ maxWidth: 880 }}>
      <button className="btn ghost sm" style={{ marginBottom: 16 }} onClick={() => go(editing ? "detail" : "discounts", id)}><Ic.chevLeft className="ico" />Back</button>
      <div className="sec-head"><h2>{editing ? "Edit discount" : "Add discount"}</h2><span className="desc">{editing ? "Manual edit — same record scrapers write to" : "Manual entry — same store the ingestion API writes to"}</span></div>

      <div className="card" style={{ padding: 22 }}>
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16 }}>
          <Field label="Product title" style={{ gridColumn: "1 / -1" }}>
            <input className="input" value={f.title} onChange={(e) => set("title", e.target.value)} placeholder="Nike Dunk Low · Panda" />
          </Field>

          <Field label="Retailer">
            <input className="input" list="retailers" value={f.retailer} onChange={(e) => set("retailer", e.target.value)} />
            <datalist id="retailers">{RETAILER_LIST.map((r) => <option key={r} value={r} />)}</datalist>
          </Field>
          <Field label="Category">
            <select className="input" value={f.category} onChange={(e) => set("category", e.target.value)}>{CATEGORIES.map((c) => <option key={c}>{c}</option>)}</select>
          </Field>

          <Field label="Original price" hint="optional">
            <input className="input" type="number" step="0.01" value={f.price_original} onChange={(e) => set("price_original", e.target.value)} placeholder="170" />
          </Field>
          <Field label="Sale price" hint="required">
            <input className="input" type="number" step="0.01" value={f.price_sale} onChange={(e) => set("price_sale", e.target.value)} placeholder="110" />
          </Field>

          <Field label="Currency">
            <select className="input" value={f.currency} onChange={(e) => set("currency", e.target.value)}>{["AUD", "USD", "GBP", "EUR", "NZD"].map((c) => <option key={c}>{c}</option>)}</select>
          </Field>
          <Field label="Discount" hint="auto-calculated">
            <div className="input" style={{ display: "flex", alignItems: "center", color: pct ? "var(--indigo)" : "var(--text-3)", fontWeight: 600 }}>{pct ? `${pct}% off` : "—"}</div>
          </Field>

          <Field label="Deal URL" style={{ gridColumn: "1 / -1" }} hint="required — also the dedupe key">
            <input className="input" value={f.url} onChange={(e) => set("url", e.target.value)} placeholder="https://retailer.com/p/product" />
          </Field>
          <Field label="Image URL" style={{ gridColumn: "1 / -1" }} hint="optional">
            <input className="input" value={f.image} onChange={(e) => set("image", e.target.value)} placeholder="https://…/image.jpg" />
          </Field>

          <Field label="Promo code" hint="optional">
            <input className="input" value={f.code} onChange={(e) => set("code", e.target.value)} placeholder="SAVE20" />
          </Field>
          <Field label="Expires" hint="optional">
            <input className="input" type="date" value={f.expires_at} onChange={(e) => set("expires_at", e.target.value)} />
          </Field>

          <Field label="Description" style={{ gridColumn: "1 / -1" }} hint="optional">
            <textarea className="input" value={f.description} onChange={(e) => set("description", e.target.value)} placeholder="Short note shown on the detail page and in the Discord embed." />
          </Field>
        </div>

        <div style={{ display: "flex", gap: 10, marginTop: 22, justifyContent: "space-between" }}>
          <div>
            {editing && <DangerButton className="btn danger" confirmLabel="Click again to delete" onConfirm={() => { fluxActions.deleteDiscount(id); toast("Discount deleted", "success"); go("discounts"); }}><Ic.trash className="ico" />Delete</DangerButton>}
          </div>
          <div style={{ display: "flex", gap: 10 }}>
            <button className="btn" onClick={() => go(editing ? "detail" : "discounts", id)}>Cancel</button>
            <button className="btn primary" onClick={save}><Ic.check className="ico" />{editing ? "Save changes" : "Add discount"}</button>
          </div>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { Dashboard, DiscountForm });
