/* global React, Ic, fluxActions, useFlux, timeAgo, toast, Field, Modal, Switch, Seg, DangerButton, DeliveryPill, Copyable, CATEGORIES, RETAILER_LIST */
const { useState: useWS } = React;

function blankWebhook() {
  return { name: "", discordUrl: "", mode: "global", active: true, filters: { retailers: [], categories: [], minPct: 0 } };
}

function Webhooks({ go }) {
  const s = useFlux();
  const [editing, setEditing] = useWS(null); // webhook obj or 'new'
  const [tab, setTab] = useWS("hooks");

  const open = (w) => setEditing(w ? { ...w, filters: { retailers: [], categories: [], minPct: 0, ...(w.filters || {}) } } : blankWebhook());

  return (
    <div className="view-pad fade-in" style={{ maxWidth: 1100 }}>
      <div className="sec-head">
        <h2>Webhooks</h2>
        <span className="desc">Push new discounts to Discord — global feed or filtered subscriptions</span>
        <span className="spacer" />
        <div className="seg" style={{ marginRight: 4 }}>
          <button className={tab === "hooks" ? "on" : ""} onClick={() => setTab("hooks")}>Endpoints</button>
          <button className={tab === "log" ? "on" : ""} onClick={() => setTab("log")}>Delivery log {s.deliveries.length ? `· ${s.deliveries.length}` : ""}</button>
        </div>
        <button className="btn primary" onClick={() => open(null)}><Ic.plus className="ico" />New webhook</button>
      </div>

      {tab === "hooks" ? (
        <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
          {s.webhooks.length === 0 && <div className="empty"><Ic.webhook className="ic" /><div className="t">No webhooks yet</div><div className="d">Add a Discord webhook to start pushing deals.</div></div>}
          {s.webhooks.map((w) => <WebhookRow key={w.id} w={w} onEdit={() => open(w)} />)}
        </div>
      ) : (
        <DeliveryLog deliveries={s.deliveries} go={go} />
      )}

      {editing && <WebhookEditor w={editing} onClose={() => setEditing(null)} />}
    </div>
  );
}

function WebhookRow({ w, onEdit }) {
  const f = w.filters || {};
  const filterBits = [];
  if (w.mode === "filtered") {
    if (f.categories && f.categories.length) filterBits.push(f.categories.join(", "));
    if (f.retailers && f.retailers.length) filterBits.push(f.retailers.join(", "));
    if (f.minPct) filterBits.push(`≥ ${f.minPct}% off`);
  }
  const test = async () => {
    toast("Sending test…", "info");
    const r = await fluxActions.testWebhook(w.id);
    if (r && r.ok) toast(r.simulated ? "Test delivered (simulated)" : "Test delivered", "success");
    else toast("Test failed — check URL / CORS", "error");
  };
  return (
    <div className="card" style={{ padding: 16, display: "flex", alignItems: "center", gap: 16 }}>
      <div style={{ width: 38, height: 38, borderRadius: 9, background: "var(--elev-2)", display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 }}>
        <Ic.discord style={{ width: 19, height: 19, color: w.active ? "#b3b7ff" : "var(--text-3)" }} />
      </div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
          <span style={{ fontSize: 14, fontWeight: 600, color: "var(--text)" }}>{w.name || "Untitled webhook"}</span>
          {w.mode === "global" ? <span className="pill indigo">GLOBAL FEED</span> : <span className="pill teal">FILTERED</span>}
        </div>
        <div className="mono-sm muted" style={{ marginTop: 4, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", maxWidth: 460 }}>{w.discordUrl}</div>
        {filterBits.length > 0 && <div style={{ marginTop: 6, fontSize: 11.5, color: "var(--text-3)" }}>Matches: {filterBits.join(" · ")}</div>}
      </div>
      <button className="btn ghost sm" onClick={test} title="Send a test embed"><Ic.zap className="ico" />Test</button>
      <button className="btn ghost sm" onClick={onEdit}><Ic.edit className="ico" />Edit</button>
      <Switch on={w.active} onChange={() => fluxActions.toggleWebhook(w.id)} />
    </div>
  );
}

function WebhookEditor({ w, onClose }) {
  const editing = !!w.id;
  const [f, setF] = useWS(w);
  const set = (k, v) => setF((p) => ({ ...p, [k]: v }));
  const setFilter = (k, v) => setF((p) => ({ ...p, filters: { ...p.filters, [k]: v } }));
  const toggleIn = (k, val) => setF((p) => {
    const arr = p.filters[k] || [];
    return { ...p, filters: { ...p.filters, [k]: arr.includes(val) ? arr.filter((x) => x !== val) : [...arr, val] } };
  });

  const save = () => {
    if (!f.name.trim()) return toast("Give the webhook a name", "error");
    if (!/^https:\/\/(discord\.com|discordapp\.com)\/api\/webhooks\//.test(f.discordUrl.trim())) return toast("Enter a valid Discord webhook URL", "error");
    fluxActions.upsertWebhook({ ...f, name: f.name.trim(), discordUrl: f.discordUrl.trim() });
    toast(editing ? "Webhook saved" : "Webhook created", "success");
    onClose();
  };

  return (
    <Modal title={editing ? "Edit webhook" : "New webhook"} icon={Ic.discord} onClose={onClose} size="lg"
      footer={<>
        {editing && <DangerButton className="btn danger" confirmLabel="Click again to delete" onConfirm={() => { fluxActions.deleteWebhook(w.id); toast("Webhook deleted", "success"); onClose(); }}><Ic.trash className="ico" />Delete</DangerButton>}
        <span style={{ flex: 1 }} />
        <button className="btn" onClick={onClose}>Cancel</button>
        <button className="btn primary" onClick={save}><Ic.check className="ico" />{editing ? "Save" : "Create"}</button>
      </>}>
      <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
        <Field label="Name" hint="how it shows in the dashboard">
          <input className="input" autoFocus value={f.name} onChange={(e) => set("name", e.target.value)} placeholder="Discord · #all-deals" />
        </Field>
        <Field label="Discord webhook URL">
          <input className="input mono" style={{ fontSize: 12 }} value={f.discordUrl} onChange={(e) => set("discordUrl", e.target.value)} placeholder="https://discord.com/api/webhooks/…" />
        </Field>

        <Field label="Trigger">
          <Seg value={f.mode} onChange={(v) => set("mode", v)} options={[{ value: "global", label: "Every new discount" }, { value: "filtered", label: "Only matching filters" }]} />
        </Field>

        {f.mode === "filtered" && (
          <div className="card" style={{ padding: 16, background: "var(--bg)", display: "flex", flexDirection: "column", gap: 16 }}>
            <Field label="Categories" hint="any selected matches — leave empty for all">
              <div className="chip-row">
                {CATEGORIES.map((c) => (
                  <div key={c} className={`chip ${(f.filters.categories || []).includes(c) ? "on" : ""}`} onClick={() => toggleIn("categories", c)}>{c}</div>
                ))}
              </div>
            </Field>
            <Field label="Retailers" hint="leave empty for all">
              <div className="chip-row">
                {RETAILER_LIST.map((r) => (
                  <div key={r} className={`chip ${(f.filters.retailers || []).includes(r) ? "on" : ""}`} onClick={() => toggleIn("retailers", r)}>{r}</div>
                ))}
              </div>
            </Field>
            <Field label={`Minimum discount · ${f.filters.minPct || 0}% off`}>
              <input type="range" min="0" max="80" step="5" value={f.filters.minPct || 0} onChange={(e) => setFilter("minPct", Number(e.target.value))} style={{ width: "100%", accentColor: "var(--indigo)" }} />
            </Field>
          </div>
        )}

        <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
          <Switch on={f.active} onChange={(v) => set("active", v)} />
          <span style={{ fontSize: 13, color: "var(--text-2)" }}>Active — fire on matching discounts</span>
        </div>
      </div>
    </Modal>
  );
}

function DeliveryLog({ deliveries, go }) {
  return (
    <div className="card" style={{ padding: 0, overflow: "hidden" }}>
      <div style={{ display: "flex", alignItems: "center", padding: "12px 18px", borderBottom: "1px solid var(--border)" }}>
        <div style={{ fontSize: 13, fontWeight: 600 }}>Delivery log</div>
        <span className="muted" style={{ fontSize: 12, marginLeft: 10 }}>{deliveries.length} events</span>
        <span style={{ flex: 1 }} />
        {deliveries.length > 0 && <DangerButton className="btn ghost sm" confirmLabel="Clear all?" onConfirm={() => { fluxActions.clearDeliveries(); toast("Log cleared", "success"); }}><Ic.trash className="ico" />Clear</DangerButton>}
      </div>
      {deliveries.length === 0 ? (
        <div className="empty"><Ic.history className="ic" /><div className="t">No deliveries yet</div><div className="d">Push a discount via the API console to see deliveries here.</div></div>
      ) : (
        <table className="tbl">
          <thead><tr><th>Discount</th><th>Webhook</th><th>Event</th><th>Status</th><th>When</th></tr></thead>
          <tbody>
            {deliveries.map((x) => (
              <tr key={x.id}>
                <td style={{ cursor: x.discountId !== "test" ? "pointer" : "default" }} onClick={() => x.discountId !== "test" && go("detail", x.discountId)}>{x.discountTitle}</td>
                <td>{x.webhookName}</td>
                <td><span className={`pill ${x.event === "price_drop" ? "green" : x.event === "test" ? "yellow" : ""}`}>{x.event}</span></td>
                <td><DeliveryPill status={x.status} code={x.code} />{x.simulated && <span className="muted mono-sm" style={{ marginLeft: 6 }}>sim</span>}</td>
                <td className="muted">{timeAgo(x.ts)}</td>
              </tr>
            ))}
          </tbody>
        </table>
      )}
    </div>
  );
}

Object.assign(window, { Webhooks });
