/* admin — Control Center: dashboard, bookings, real Mr. Wing transcripts,
   leads/inquiries, and plug-and-play API management. */

function timeAgo(ts) {
  const s = Math.max(0, Math.floor((Date.now() - ts) / 1000));
  if (s < 60) return s + "s ago";
  const m = Math.floor(s / 60); if (m < 60) return m + "m ago";
  const h = Math.floor(m / 60); if (h < 24) return h + "h ago";
  return Math.floor(h / 24) + "d ago";
}

/* Admin data: server-backed (Supabase) when the DB is configured and an admin
   token is present, merged over the local store by id (server is authoritative).
   Falls back to the local store otherwise, so the panel always works. */
const AdminDataContext = React.createContext(null);

function fromServer(r) {
  return {
    ...r,
    createdAt: r.created_at != null ? Date.parse(r.created_at) : r.createdAt,
    updatedAt: r.updated_at != null ? Date.parse(r.updated_at) : r.updatedAt,
    startedAt: r.started_at != null ? Date.parse(r.started_at) : r.startedAt,
    paidWith: r.paid_with != null ? r.paid_with : r.paidWith,
    paymentRef: r.payment_ref != null ? r.payment_ref : r.paymentRef,
  };
}
function mergeById(serverRows, localRows) {
  if (!serverRows) return localRows || [];
  const map = new Map();
  (localRows || []).forEach(r => map.set(r.id, r));
  serverRows.forEach(r => map.set(r.id, fromServer(r)));
  return Array.from(map.values()).sort((a, b) => (b.createdAt || b.updatedAt || 0) - (a.createdAt || a.updatedAt || 0));
}

function AdminDataProvider({ children }) {
  const { bookings, leads, tickets, conversations } = useStore();
  const [server, setServer] = React.useState(null);
  const [dbLive, setDbLive] = React.useState(false);
  React.useEffect(() => {
    let alive = true;
    if (!window.apiConfig) return;
    (async () => {
      const cfg = await apiConfig();
      let token = ""; try { token = sessionStorage.getItem("tw_admin") || ""; } catch (e) {}
      if (!alive || !cfg || cfg.__unreachable || !cfg.dbEnabled) return;
      setDbLive(true);
      if (!token) return; // reading leads/tickets/bookings (PII) requires the admin token
      const [b, l, tk, c] = await Promise.all([
        window.apiBookingsList(token), window.apiLeadsList(token), window.apiTicketsList(token), window.apiConvList(token),
      ]);
      if (!alive) return;
      setServer({
        bookings: b && b.bookings ? b.bookings : null,
        leads: l && l.leads ? l.leads : null,
        tickets: tk && tk.tickets ? tk.tickets : null,
        conversations: c && c.conversations ? c.conversations : null,
      });
    })();
    return () => { alive = false; };
  }, []);
  const value = {
    bookings: mergeById(server && server.bookings, bookings),
    leads: mergeById(server && server.leads, leads),
    tickets: mergeById(server && server.tickets, tickets),
    conversations: mergeById(server && server.conversations, conversations),
    dbLive, serverLoaded: !!server,
  };
  return <AdminDataContext.Provider value={value}>{children}</AdminDataContext.Provider>;
}
function useAdminData() {
  const ctx = React.useContext(AdminDataContext);
  const store = useStore();
  return ctx || { bookings: store.bookings, leads: store.leads, tickets: store.tickets, conversations: store.conversations, dbLive: false, serverLoaded: false };
}

function AdminPage() {
  const { t } = useLang();
  const [tab, setTab] = React.useState("dashboard");
  const tabs = [
    { id: "dashboard", label: t("admin.tab.dashboard"), icon: "chart" },
    { id: "bookings", label: t("admin.tab.bookings"), icon: "doc" },
    { id: "transcripts", label: t("admin.tab.transcripts"), icon: "chat" },
    { id: "leads", label: t("admin.tab.leads"), icon: "user" },
    { id: "api", label: t("admin.tab.api"), icon: "key" },
  ];
  return (
    <main style={{ paddingTop: 72, background: "var(--paper-2)", minHeight: "100vh" }}>
      <div style={{ background: "var(--ink)", color: "#fff", paddingTop: 28 }}>
        <div className="wrap">
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", paddingBottom: 22, flexWrap: "wrap", gap: 12 }}>
            <div>
              <div style={{ fontSize: 12, letterSpacing: ".18em", textTransform: "uppercase", color: "var(--gold-l)", fontWeight: 600 }}>{t("admin.center")}</div>
              <h1 style={{ fontFamily: "var(--serif)", fontSize: 30, fontWeight: 600, marginTop: 4 }}>{t("admin.overview")}</h1>
            </div>
            <div style={{ display: "flex", alignItems: "center", gap: 12, fontSize: 13.5 }}>
              <span style={{ display: "inline-flex", gap: 7, alignItems: "center", color: "rgba(255,255,255,.7)" }}><span className="badge-dot" style={{ background: "var(--ok)" }}></span> {t("admin.ok")}</span>
              <div style={{ width: 38, height: 38, borderRadius: "50%", background: "var(--emerald)", display: "grid", placeItems: "center", fontWeight: 700 }}>TW</div>
            </div>
          </div>
          <div className="admin-tabs" style={{ display: "flex", gap: 4 }} role="tablist">
            {tabs.map(tb => (
              <button key={tb.id} role="tab" aria-selected={tab === tb.id} onClick={() => setTab(tb.id)}
                style={{ display: "flex", alignItems: "center", gap: 8, padding: "13px 18px", border: "none", background: "none", cursor: "pointer", fontFamily: "var(--sans)", fontSize: 14, fontWeight: 600, color: tab === tb.id ? "#fff" : "rgba(255,255,255,.55)", borderBottom: "2px solid " + (tab === tb.id ? "var(--gold)" : "transparent") }}>
                <Icon name={tb.icon} size={16} /> {tb.label}
              </button>
            ))}
          </div>
        </div>
      </div>

      <div className="wrap" style={{ paddingTop: 30, paddingBottom: 70 }}>
        <AdminDataProvider>
          {tab === "dashboard" && <AdminDashboard />}
          {tab === "bookings" && <AdminBookings />}
          {tab === "transcripts" && <AdminTranscripts />}
          {tab === "leads" && <AdminLeads />}
          {tab === "api" && <AdminAPI />}
        </AdminDataProvider>
      </div>
    </main>
  );
}

function StatCard({ label, value, delta, icon, tone = "emerald" }) {
  const tones = { emerald: ["var(--emerald-wash)", "var(--emerald)"], gold: ["var(--gold-wash)", "var(--gold-d)"], ink: ["var(--paper-3)", "var(--ink)"] };
  const [bg, fg] = tones[tone];
  return (
    <div className="card card-pad">
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start" }}>
        <div style={{ width: 44, height: 44, borderRadius: 12, background: bg, color: fg, display: "grid", placeItems: "center" }}><Icon name={icon} size={22} /></div>
        {delta && <span style={{ fontSize: 12.5, fontWeight: 700, color: "var(--ok)", background: "var(--emerald-wash)", padding: "3px 9px", borderRadius: 100 }}>{delta}</span>}
      </div>
      <div style={{ fontFamily: "var(--serif)", fontSize: 38, fontWeight: 600, marginTop: 16, color: "var(--ink)" }}>{value}</div>
      <div className="muted" style={{ fontSize: 13, marginTop: 2 }}>{label}</div>
    </div>
  );
}

function AdminDashboard() {
  const { t, lang } = useLang();
  const { bookings } = useAdminData();
  const active = bookings.filter(b => b.status === "Confirmed").length;
  const revenue = bookings.filter(b => b.status !== "Cancelled").reduce((s, b) => s + (b.amount || 0), 0);
  const wingCount = bookings.filter(b => b.channel === "Mr. Wing").length;

  // Weekly volume — real booking counts for the last 7 calendar days (no fabricated figures).
  const DAY = 86400000;
  const now = Date.now();
  const week = [];
  for (let i = 6; i >= 0; i--) {
    const d = new Date(now - i * DAY);
    const start = new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime();
    const count = bookings.filter(b => { const ts = b.createdAt || 0; return ts >= start && ts < start + DAY; }).length;
    let label = ""; try { label = new Date(start).toLocaleDateString(lang === "ar" ? "ar-SA" : "en-US", { weekday: "short" }); } catch (e) {}
    week.push({ label, count, today: i === 0 });
  }
  const maxCount = Math.max(1, ...week.map(w => w.count));

  // Channel mix — real share of non-cancelled bookings by acquisition channel.
  const live = bookings.filter(b => b.status !== "Cancelled");
  const totalCh = live.length || 1;
  const wing = live.filter(b => b.channel === "Mr. Wing").length;
  const web = live.filter(b => b.channel === "Web").length;
  const other = live.length - wing - web;
  const mix = [
    [t("admin.ch.wing"), Math.round(wing / totalCh * 100), "var(--emerald)"],
    [t("admin.ch.web"), Math.round(web / totalCh * 100), "var(--gold)"],
    [t("admin.ch.egypt"), Math.round(other / totalCh * 100), "var(--ink-3)"],
  ];

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 22 }}>
      <div className="rcol-2" style={{ display: "grid", gridTemplateColumns: "repeat(4,1fr)", gap: 18 }}>
        <StatCard label={t("admin.stat.active")} value={active} icon="doc" tone="emerald" />
        <StatCard label={t("admin.stat.revenue")} value={"SAR " + (revenue / 1000).toFixed(1) + "k"} icon="chart" tone="gold" />
        <StatCard label={t("admin.stat.wing")} value={wingCount} icon="chat" tone="emerald" />
        <StatCard label={t("admin.stat.sat")} value="95%" icon="spark" tone="ink" />
      </div>

      <div className="split" style={{ display: "grid", gridTemplateColumns: "1.6fr 1fr", gap: 22 }}>
        <div className="card card-pad">
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 24 }}>
            <h3 style={{ fontFamily: "var(--serif)", fontSize: 22, fontWeight: 600 }}>{t("admin.week")}</h3>
            <span className="chip chip-emerald">{t("admin.flightsHotels")}</span>
          </div>
          <div style={{ display: "flex", alignItems: "flex-end", gap: 14, height: 200 }}>
            {week.map((w, i) => (
              <div key={i} style={{ flex: 1, display: "flex", flexDirection: "column", alignItems: "center", gap: 10 }}>
                <div style={{ width: "100%", height: Math.max(2, (w.count / maxCount) * 170), background: w.today ? "var(--gold)" : "var(--emerald)", borderRadius: "8px 8px 0 0", transition: "height .4s", position: "relative", opacity: w.count ? 1 : 0.32 }}>
                  <span style={{ position: "absolute", top: -22, insetInline: 0, textAlign: "center", fontSize: 12, fontWeight: 700, color: "var(--ink-2)" }}>{w.count}</span>
                </div>
                <span className="muted" style={{ fontSize: 12 }}>{w.label}</span>
              </div>
            ))}
          </div>
        </div>

        <div className="card card-pad">
          <h3 style={{ fontFamily: "var(--serif)", fontSize: 22, fontWeight: 600, marginBottom: 18 }}>{t("admin.channelMix")}</h3>
          {mix.map(([l, v, c]) => (
            <div key={l} style={{ marginBottom: 18 }}>
              <div style={{ display: "flex", justifyContent: "space-between", fontSize: 13.5, fontWeight: 600, marginBottom: 7 }}><span>{l}</span><span>{v}%</span></div>
              <div style={{ height: 8, background: "var(--paper-2)", borderRadius: 100, overflow: "hidden" }}><div style={{ width: v + "%", height: "100%", background: c, borderRadius: 100 }}></div></div>
            </div>
          ))}
          <div className="hr" style={{ margin: "20px 0 16px" }}></div>
          <div style={{ display: "flex", gap: 10, alignItems: "center", fontSize: 13, color: "var(--ink-2)" }}><Icon name="bolt" size={16} color="var(--gold-d)" /> {t("admin.aiDrives")}</div>
        </div>
      </div>

      <AdminBookings compact />
    </div>
  );
}

function StatusPill({ status }) {
  const { t } = useLang();
  const map = {
    Confirmed: ["var(--emerald-wash)", "var(--emerald)"], Cancelled: ["var(--danger-wash)", "var(--danger)"],
    Escalated: ["var(--gold-wash)", "var(--gold-d)"], Modified: ["var(--gold-wash)", "var(--gold-d)"],
    New: ["var(--emerald-wash)", "var(--emerald)"], Contacted: ["var(--gold-wash)", "var(--gold-d)"], Closed: ["var(--paper-2)", "var(--ink-3)"],
  };
  const [bg, fg] = map[status] || map.Confirmed;
  return <span style={{ background: bg, color: fg, fontSize: 12, fontWeight: 700, padding: "4px 11px", borderRadius: 100 }}>{t("status." + status) || status}</span>;
}

function AdminBookings({ compact }) {
  const { t } = useLang();
  const { bookings } = useAdminData();
  const list = compact ? bookings.slice(0, 5) : bookings;
  return (
    <div className="card" style={{ overflow: "hidden" }}>
      <div style={{ padding: "20px 24px", display: "flex", justifyContent: "space-between", alignItems: "center", borderBottom: "1px solid var(--line)" }}>
        <h3 style={{ fontFamily: "var(--serif)", fontSize: 22, fontWeight: 600 }}>{compact ? t("admin.recent") : t("admin.all")}</h3>
        <span className="muted" style={{ fontSize: 13 }}>{t("admin.totalN", { n: bookings.length })}</span>
      </div>
      <div style={{ overflowX: "auto" }}>
        <table style={{ width: "100%", borderCollapse: "collapse", fontSize: 14 }}>
          <thead>
            <tr style={{ textAlign: "start", color: "var(--ink-3)", fontSize: 12, letterSpacing: ".08em", textTransform: "uppercase" }}>
              {["itinerary", "trip", "client", "channel", "amount", "status"].map(h => <th key={h} style={{ textAlign: "start", padding: "13px 24px", fontWeight: 600, borderBottom: "1px solid var(--line)" }}>{t("admin.col." + h)}</th>)}
            </tr>
          </thead>
          <tbody>
            {list.map(b => (
              <tr key={b.id} style={{ borderBottom: "1px solid var(--line)" }}>
                <td style={{ padding: "15px 24px", fontWeight: 700, fontFamily: "monospace", fontSize: 13 }}>{b.id}</td>
                <td style={{ padding: "15px 24px" }}><div style={{ display: "flex", gap: 9, alignItems: "center" }}><Icon name={b.type === "hotel" ? "hotel" : b.type === "package" ? "spark" : "plane"} size={16} color="var(--emerald)" /> {b.title}</div></td>
                <td style={{ padding: "15px 24px", color: "var(--ink-2)" }}>{b.who}</td>
                <td style={{ padding: "15px 24px" }}><span className="chip" style={{ fontSize: 11.5 }}>{b.channel}</span></td>
                <td style={{ padding: "15px 24px", fontWeight: 700 }}><Money value={b.amount} sar={false} /></td>
                <td style={{ padding: "15px 24px" }}><StatusPill status={b.status} /></td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}

function AdminTranscripts() {
  const { t } = useLang();
  const { conversations } = useAdminData();
  if (!conversations || conversations.length === 0) {
    return <div className="card card-pad center muted" style={{ padding: 56 }}><Icon name="chat" size={32} color="var(--ink-3)" /><div style={{ marginTop: 12 }}>{t("admin.transcripts.empty")}</div></div>;
  }
  return (
    <div className="rcol" style={{ display: "grid", gridTemplateColumns: "repeat(3,1fr)", gap: 20 }}>
      {conversations.map((c, i) => (
        <div key={c.id || i} className="card" style={{ overflow: "hidden", display: "flex", flexDirection: "column" }}>
          <div style={{ padding: "16px 20px", borderBottom: "1px solid var(--line)", display: "flex", justifyContent: "space-between", alignItems: "center" }}>
            <div><div style={{ fontWeight: 700, fontSize: 13.5 }}>{c.who || "Web visitor"}</div><div className="muted" style={{ fontSize: 12 }}>{timeAgo(c.updatedAt || c.startedAt || Date.now())} · {c.channel || "Mr. Wing"}</div></div>
            <StatusPill status={c.outcome === "Escalated" ? "Escalated" : c.outcome === "Booked" ? "Confirmed" : "New"} />
          </div>
          <div style={{ padding: 16, display: "flex", flexDirection: "column", gap: 8, background: "var(--paper)", flex: 1, maxHeight: 280, overflowY: "auto" }}>
            {(c.messages || []).filter(m => m.content).slice(0, 8).map((m, j) => (
              <div key={j} style={{ alignSelf: m.role === "user" ? "flex-end" : "flex-start", maxWidth: "88%", background: m.role === "user" ? "var(--emerald)" : "#fff", color: m.role === "user" ? "#fff" : "var(--ink)", border: m.role === "user" ? "none" : "1px solid var(--line)", padding: "8px 12px", borderRadius: 12, fontSize: 12.5, lineHeight: 1.45 }}>{m.content}</div>
            ))}
            {(c.messages || []).some(m => m.card && m.card.type === "escalate") && <div style={{ textAlign: "center", fontSize: 11.5, color: "var(--gold-d)", fontWeight: 600, padding: "4px 0" }}>— {t("wing.escalated")} —</div>}
          </div>
        </div>
      ))}
    </div>
  );
}

function AdminLeads() {
  const { t } = useLang();
  const { leads, tickets } = useAdminData();
  const all = [
    ...(leads || []).map(l => ({ ...l, _type: "inquiry", who: l.org, contact: l.email, body: l.notes || (l.sector + " · " + l.trips + " trips/yr") })),
    ...(tickets || []).map(t2 => ({ ...t2, _type: "message", who: t2.name, contact: t2.email, body: t2.message })),
  ].sort((a, b) => (b.createdAt || 0) - (a.createdAt || 0));

  if (all.length === 0) {
    return <div className="card card-pad center muted" style={{ padding: 56 }}><Icon name="user" size={32} color="var(--ink-3)" /><div style={{ marginTop: 12 }}>{t("admin.leads.empty")}</div></div>;
  }
  return (
    <div className="card" style={{ overflow: "hidden" }}>
      <div style={{ padding: "20px 24px", display: "flex", justifyContent: "space-between", alignItems: "center", borderBottom: "1px solid var(--line)" }}>
        <h3 style={{ fontFamily: "var(--serif)", fontSize: 22, fontWeight: 600 }}>{t("admin.tab.leads")}</h3>
        <span className="muted" style={{ fontSize: 13 }}>{t("admin.totalN", { n: all.length })}</span>
      </div>
      <div style={{ overflowX: "auto" }}>
        <table style={{ width: "100%", borderCollapse: "collapse", fontSize: 14 }}>
          <thead>
            <tr style={{ color: "var(--ink-3)", fontSize: 12, letterSpacing: ".08em", textTransform: "uppercase" }}>
              {[t("leads.ref"), t("admin.col.type"), t("admin.col.client"), t("admin.col.contact"), t("admin.col.status")].map(h => <th key={h} style={{ textAlign: "start", padding: "13px 24px", fontWeight: 600, borderBottom: "1px solid var(--line)" }}>{h}</th>)}
            </tr>
          </thead>
          <tbody>
            {all.map(l => (
              <tr key={l.id} style={{ borderBottom: "1px solid var(--line)" }}>
                <td style={{ padding: "15px 24px", fontFamily: "monospace", fontSize: 13, fontWeight: 700 }}>{l.id}</td>
                <td style={{ padding: "15px 24px" }}><span className="chip" style={{ fontSize: 11.5 }}>{l._type === "inquiry" ? t("admin.leads.inquiry") : t("admin.leads.message")}</span></td>
                <td style={{ padding: "15px 24px" }}><div style={{ fontWeight: 600 }}>{l.who}</div><div className="muted" style={{ fontSize: 12.5, maxWidth: 320, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{l.body}</div></td>
                <td style={{ padding: "15px 24px", color: "var(--ink-2)", fontSize: 13 }}>{l.contact}</td>
                <td style={{ padding: "15px 24px" }}><StatusPill status={l.status || "New"} /></td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}

Object.assign(window, { AdminPage, AdminDashboard, AdminBookings, AdminTranscripts, AdminLeads, StatCard, StatusPill, timeAgo, AdminDataProvider, useAdminData });
