import React, { useState, useEffect, useCallback, useRef, useMemo } from "https://esm.sh/react@18.2.0";
import { createRoot } from "https://esm.sh/react-dom@18.2.0/client";
import {
  Wallet, CreditCard, TrendingDown, ShoppingCart, LogOut, Shield,
  Users, Plus, Trash2, Download, Search, Package, Receipt,
  CheckCircle, X, Eye, EyeOff, Settings, BarChart3, Wifi, AlertCircle,
  ChevronDown, ChevronUp, Upload, Copy, Ban, Check, Clock, MapPin,
  RefreshCw, ArrowUpRight, Phone, ChevronsUpDown, ArrowRight, Send,
  Trophy, Zap, UserCheck, ArrowLeft, Power, Edit2,
} from "https://esm.sh/lucide-react@0.383.0?deps=react@18.2.0";

/* ============================================================
   MikroTik Cards Shop — النسخة 3
   ============================================================ */

const CURRENCY = "ريال";
const fmt = (n) => new Intl.NumberFormat("ar-YE").format(Math.round(n || 0));
const uid = () => Date.now().toString(36) + Math.random().toString(36).slice(2, 7);
const now = () => new Date().toISOString();
const fmtDate = (iso) => iso ? new Date(iso).toLocaleString("ar-YE", { year: "numeric", month: "short", day: "numeric", hour: "2-digit", minute: "2-digit" }) : "-";
const fmtDay = (iso) => iso ? new Date(iso).toLocaleDateString("ar-YE", { year: "numeric", month: "short", day: "numeric" }) : "-";

function randomPass() {
  const chars = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz23456789";
  let s = "";
  for (let i = 0; i < 8; i++) s += chars[Math.floor(Math.random() * chars.length)];
  return s;
}

/* ============================================================
   Auth + Encrypted API Layer
   - JWT في localStorage
   - مفتاح جلسة AES-256-GCM لتشفير كل الطلبات والردود
   ============================================================ */
const AUTH = { token: null, key: null, keyB64: null, role: null, uid: null, name: null };

function b64ToBytes(b64) { return Uint8Array.from(atob(b64), (c) => c.charCodeAt(0)); }
function bytesToB64(bytes) { let s = ""; bytes.forEach((b) => (s += String.fromCharCode(b))); return btoa(s); }

async function deriveKey(b64) {
  return crypto.subtle.importKey("raw", b64ToBytes(b64), { name: "AES-GCM" }, false, ["encrypt", "decrypt"]);
}
async function aesEncrypt(plain) {
  const iv = crypto.getRandomValues(new Uint8Array(12));
  const ct = await crypto.subtle.encrypt({ name: "AES-GCM", iv }, AUTH.key, new TextEncoder().encode(plain));
  const out = new Uint8Array(iv.length + ct.byteLength);
  out.set(iv); out.set(new Uint8Array(ct), iv.length);
  return bytesToB64(out);
}
async function aesDecrypt(cipherB64) {
  const data = b64ToBytes(cipherB64);
  const iv = data.slice(0, 12), ct = data.slice(12);
  const plain = await crypto.subtle.decrypt({ name: "AES-GCM", iv }, AUTH.key, ct);
  return new TextDecoder().decode(plain);
}

async function setAuth({ token, sessionKey, user }) {
  AUTH.token = token;
  AUTH.keyB64 = sessionKey;
  AUTH.key = await deriveKey(sessionKey);
  AUTH.role = user?.role; AUTH.uid = user?.id; AUTH.name = user?.name;
  try {
    localStorage.setItem("netcard_token", token);
    localStorage.setItem("netcard_skey", sessionKey);
    localStorage.setItem("netcard_user", JSON.stringify(user));
  } catch (e) {}
}
function clearAuth() {
  AUTH.token = AUTH.key = AUTH.keyB64 = AUTH.role = AUTH.uid = AUTH.name = null;
  try {
    localStorage.removeItem("netcard_token");
    localStorage.removeItem("netcard_skey");
    localStorage.removeItem("netcard_user");
  } catch (e) {}
}
async function restoreAuth() {
  try {
    const token = localStorage.getItem("netcard_token");
    const skey = localStorage.getItem("netcard_skey");
    const user = JSON.parse(localStorage.getItem("netcard_user") || "null");
    if (token && skey && user) {
      AUTH.token = token; AUTH.keyB64 = skey; AUTH.key = await deriveKey(skey);
      AUTH.role = user.role; AUTH.uid = user.id; AUTH.name = user.name;
      return user;
    }
  } catch (e) {}
  return null;
}

/** نداء API مصادق + مشفّر. يُرجع الكائن المفكوك. */
async function api(action, body = null) {
  const opts = { method: body !== null ? "POST" : "GET", headers: {} };
  if (AUTH.token) opts.headers["Authorization"] = "Bearer " + AUTH.token;
  if (body !== null) {
    opts.headers["Content-Type"] = "application/json";
    if (AUTH.key) {
      const enc = await aesEncrypt(JSON.stringify(body));
      opts.body = JSON.stringify({ enc });
    } else {
      opts.body = JSON.stringify(body);
    }
  }
  const res = await fetch("api.php?action=" + action, opts);
  const text = await res.text();
  let data;
  try { data = JSON.parse(text); } catch (e) { return { error: "invalid_response", raw: text }; }
  if (res.status === 401) { clearAuth(); return { error: "unauthorized" }; }
  if (data && data.enc && AUTH.key) {
    try { return JSON.parse(await aesDecrypt(data.enc)); } catch (e) { return { error: "decrypt_failed" }; }
  }
  return data;
}

/** تسجيل الدخول (غير مشفّر — نقطة عامة) */
async function apiLogin(role, phone, password) {
  try {
    const res = await fetch("api.php?action=login", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ role, phone, password }),
    });
    return await res.json();
  } catch (e) {
    return { error: "network", message: String(e.message || e) };
  }
}

/* ============================================================
   Telegram — عبر الـ backend (مشفّر + مصادق)
   ============================================================ */
async function notifyTelegram(_t, _c, text) {
  const r = await api("tg-message", { text });
  return r.ok ? { ok: true } : { ok: false, reason: r.reason || r.description || r.error || "telegram_err" };
}
async function sendTelegramFile(_t, _c, filename, _content, caption) {
  const r = await api("tg-backup", { filename, caption });
  return r.ok ? { ok: true } : { ok: false, reason: r.reason || r.description || r.error || "telegram_err" };
}

/* ============================================================
   Data layer
   ============================================================ */
const DEFAULT_DB = {
  defaultDebtLimit: 5000,
  telegramBotToken: "",
  telegramChatId: "",
  lastBackupAt: 0,
  customers: {},
  agents: {},
  categories: [],
  transactions: [],
  depositRequests: [],
};

function migrate(db) {
  const d = { ...DEFAULT_DB, ...db };
  if (!d.agents) d.agents = {};
  d.customers = d.customers || {};
  Object.values(d.customers).forEach((c) => {
    if (c.region == null) c.region = "";
    if (typeof c.banned !== "boolean") c.banned = false;
    if (!c.createdAt) c.createdAt = now();
  });
  Object.values(d.agents).forEach((a) => {
    if (!a.regions) a.regions = [];
    if (!a.createdAt) a.createdAt = now();
  });
  (d.categories || []).forEach((cat) => {
    (cat.codes || []).forEach((c) => { if (!c.addedAt) c.addedAt = now(); });
  });
  return d;
}

async function loadDB() {
  const data = await api("load");
  if (data && !data.error && typeof data === "object") return migrate(data);
  return null;
}
async function saveDB(db) {
  const r = await api(AUTH.role === "customer" ? "customer-save" : "save", { state: db });
  return !!(r && r.ok);
}

/* ============================================================
   App
   ============================================================ */
function App() {
  const [db, setDb] = useState(null);
  const [booting, setBooting] = useState(true);
  const [session, setSession] = useState(null);
  const [toast, setToast] = useState(null);
  const [modal, setModal] = useState(null);
  const [dialog, setDialog] = useState(null);

  const showToast = useCallback((msg, kind = "ok") => {
    setToast({ msg, kind });
    setTimeout(() => setToast(null), 2800);
  }, []);

  const askConfirm = useCallback((opts, onYes) => {
    setDialog({ kind: "confirm", ...opts, onYes: () => { setDialog(null); onYes && onYes(); } });
  }, []);
  const askPrompt = useCallback((opts, onSubmit) => {
    setDialog({ kind: "prompt", ...opts, onSubmit: (v) => { setDialog(null); onSubmit && onSubmit(v); } });
  }, []);

  // جلب البيانات بعد المصادقة
  const refresh = useCallback(async () => {
    const data = await loadDB();
    if (data) setDb(data);
    return data;
  }, []);

  // استعادة جلسة محفوظة عند بدء التطبيق
  useEffect(() => {
    (async () => {
      const user = await restoreAuth();
      if (user) {
        const data = await loadDB();
        if (data) {
          setDb(data);
          setSession({ role: user.role, phone: user.id });
        } else {
          clearAuth();
        }
      }
      setBooting(false);
    })();
  }, []);

  const persist = useCallback((updater) => {
    setDb((prev) => {
      const next = typeof updater === "function" ? updater(prev) : updater;
      saveDB(next);
      return next;
    });
  }, []);

  // عند نجاح تسجيل الدخول
  const onLoggedIn = useCallback(async (user) => {
    const data = await loadDB();
    setDb(data || JSON.parse(JSON.stringify(DEFAULT_DB)));
    setSession({ role: user.role, phone: user.id });
  }, []);

  const onLogout = useCallback(async () => {
    try { await api("logout"); } catch (e) {}
    clearAuth();
    setSession(null);
    setDb(null);
  }, []);

  // نسخة احتياطية تلقائية يومية لتيليجرام (عند دخول الأدمن)
  useEffect(() => {
    if (!db || !session || session.role !== "admin") return;
    if (!db.telegramBotToken || !db.telegramChatId) return;
    const DAY = 24 * 60 * 60 * 1000;
    if (Date.now() - (db.lastBackupAt || 0) < DAY) return;
    (async () => {
      const stamp = new Date().toISOString().slice(0, 10);
      const r = await sendTelegramFile(null, null, `netcard_backup_${stamp}.json`, null,
        `🗄️ نسخة احتياطية تلقائية\n📅 ${stamp}`);
      if (r.ok) { await refresh(); showToast("تم رفع نسخة احتياطية تلقائية إلى تيليجرام", "ok"); }
    })();
  }, [db, session, refresh, showToast]);

  if (booting) return <SplashLoader />;

  const helpers = { showToast, askConfirm, askPrompt, setModal, refresh };

  return (
    <Shell>
      {!session ? (
        <LoginScreen onLoggedIn={onLoggedIn} showToast={showToast} />
      ) : !db ? (
        <SplashLoader />
      ) : session.role === "admin" ? (
        <AdminPanel db={db} persist={persist} onLogout={onLogout} helpers={helpers} />
      ) : session.role === "agent" ? (
        <AgentPanel db={db} persist={persist} agentPhone={session.phone} onLogout={onLogout} helpers={helpers} />
      ) : (
        <CustomerPanel db={db} persist={persist} phone={session.phone} onLogout={onLogout} helpers={helpers} />
      )}
      <Toast toast={toast} />
      <Modal modal={modal} onClose={() => setModal(null)} />
      <Dialog dialog={dialog} onClose={() => setDialog(null)} />
    </Shell>
  );
}

/* ============================================================
   Shell + Loader
   ============================================================ */
function Shell({ children }) {
  return (
    <div dir="rtl" style={S.root}>
      <style>{globalCss}</style>
      <div style={S.bgGrid} />
      <div style={S.bgGlow} />
      <div style={{ position: "relative", zIndex: 2, minHeight: "100vh" }}>{children}</div>
    </div>
  );
}
function SplashLoader() {
  return (
    <Shell>
      <div style={{ display: "grid", placeItems: "center", minHeight: "100vh", color: "#7ee0c8" }}>
        <div style={{ textAlign: "center" }}>
          <Wifi size={48} className="pulse" />
          <p style={{ marginTop: 16, fontFamily: "Tajawal", letterSpacing: 1 }}>جارٍ التحميل…</p>
        </div>
      </div>
    </Shell>
  );
}

/* ============================================================
   Login (3 tabs: customer / agent / admin)
   ============================================================ */
function LoginScreen({ onLoggedIn, showToast }) {
  const [tab, setTab] = useState("customer");
  const [phone, setPhone] = useState("");
  const [p, setP] = useState("");
  const [show, setShow] = useState(false);
  const [busy, setBusy] = useState(false);
  const [lockUntil, setLockUntil] = useState(0); // timestamp ms
  const [secsLeft, setSecsLeft] = useState(0);

  // عدّاد القفل التنازلي
  useEffect(() => {
    if (!lockUntil) return;
    const tick = () => {
      const left = Math.ceil((lockUntil - Date.now()) / 1000);
      setSecsLeft(left > 0 ? left : 0);
      if (left <= 0) setLockUntil(0);
    };
    tick();
    const id = setInterval(tick, 500);
    return () => clearInterval(id);
  }, [lockUntil]);

  const locked = secsLeft > 0;

  const submit = async () => {
    if (busy || locked) return;
    if (tab !== "admin" && !phone.trim()) return showToast("أدخل رقم الهاتف", "err");
    if (!p) return showToast("أدخل كلمة المرور", "err");
    setBusy(true);
    const res = await apiLogin(tab, phone.trim(), p);
    setBusy(false);

    if (res.ok && res.token) {
      await setAuth({ token: res.token, sessionKey: res.sessionKey, user: res.user });
      setP("");
      onLoggedIn(res.user);
      return;
    }
    if (res.error === "locked") {
      setLockUntil(Date.now() + (res.secondsLeft || 120) * 1000);
      showToast(res.message || "تم قفل الحساب مؤقتاً", "err");
    } else if (res.error === "banned") {
      showToast(res.message || "تم حظر هذا الحساب", "err");
    } else if (res.error === "invalid") {
      const rem = res.remaining;
      showToast(rem != null ? `بيانات خاطئة. تبقّى ${rem} ${rem === 1 ? "محاولة" : "محاولات"}` : "بيانات الدخول غير صحيحة", "err");
    } else if (res.error === "network") {
      showToast("تعذّر الاتصال بالخادم. تأكّد أن Apache يعمل", "err");
    } else {
      showToast(res.message || "فشل تسجيل الدخول", "err");
    }
  };

  const mmss = (s) => `${Math.floor(s / 60)}:${String(s % 60).padStart(2, "0")}`;

  return (
    <div style={{ display: "grid", placeItems: "center", minHeight: "100vh", padding: 20 }}>
      <div style={S.loginCard} className="rise">
        <div style={{ textAlign: "center", marginBottom: 26 }}>
          <div style={S.logoBadge}><Wifi size={30} /></div>
          <h1 style={S.brand}>NET<span style={{ color: "#22e0a1" }}>CARD</span></h1>
          <p style={S.brandSub}>منصة بيع كروت المايكروتك</p>
        </div>

        <div style={S.tabRow}>
          <button onClick={() => setTab("customer")} style={{ ...S.tabBtn, ...(tab === "customer" ? S.tabActive : {}) }}>
            <Users size={14} /> زبون
          </button>
          <button onClick={() => setTab("agent")} style={{ ...S.tabBtn, ...(tab === "agent" ? S.tabActive : {}) }}>
            <UserCheck size={14} /> وكيل
          </button>
          <button onClick={() => setTab("admin")} style={{ ...S.tabBtn, ...(tab === "admin" ? S.tabActive : {}) }}>
            <Shield size={14} /> أدمن
          </button>
        </div>

        {tab !== "admin" && (
          <Field label="رقم الهاتف">
            <div style={{ position: "relative" }}>
              <Phone size={15} style={{ position: "absolute", right: 12, top: 13, color: "#6b8a82" }} />
              <input
                style={{ ...S.input, paddingRight: 36 }}
                value={phone} onChange={(e) => setPhone(e.target.value)}
                placeholder="7XXXXXXXX" inputMode="tel" disabled={locked}
                onKeyDown={(e) => e.key === "Enter" && submit()}
              />
            </div>
          </Field>
        )}
        <Field label="كلمة المرور">
          <div style={{ position: "relative" }}>
            <input style={S.input} type={show ? "text" : "password"} value={p} disabled={locked}
              onChange={(e) => setP(e.target.value)} placeholder="••••••"
              onKeyDown={(e) => e.key === "Enter" && submit()} />
            <button onClick={() => setShow((s) => !s)} style={S.eyeBtn}>{show ? <EyeOff size={16} /> : <Eye size={16} />}</button>
          </div>
        </Field>

        {locked ? (
          <div style={S.lockBox}>
            <Clock size={16} />
            <span>محظور مؤقتاً بسبب المحاولات الخاطئة — حاول بعد <b style={{ fontVariantNumeric: "tabular-nums" }}>{mmss(secsLeft)}</b></span>
          </div>
        ) : null}

        <button onClick={submit} style={{ ...S.primaryBtn, opacity: busy || locked ? 0.6 : 1 }} className="press" disabled={busy || locked}>
          {busy ? <><RefreshCw size={16} className="pulse" /> جارٍ الدخول…</> : "دخول"}
        </button>
      </div>
    </div>
  );
}

/* ============================================================
   Customer Panel
   ============================================================ */
function CustomerPanel({ db, persist, phone, onLogout, helpers }) {
  const c = db.customers[phone];
  const [view, setView] = useState("shop");
  const [purchasedCard, setPurchasedCard] = useState(null); // { code, category, price, speed, validity }
  const myTx = db.transactions.filter((t) => t.customer === phone).sort((a, b) => b.date.localeCompare(a.date));
  const myDeposits = db.depositRequests.filter((r) => r.customer === phone).sort((a, b) => b.date.localeCompare(a.date));

  const buy = async (cat) => {
    const available = cat.codes.some((x) => !x.used);
    if (!available) return helpers.showToast("لا توجد كروت متاحة في هذه الفئة", "err");
    const r = await api("customer-buy", { categoryId: cat.id });
    if (!r || !r.ok) return helpers.showToast(r?.error || "تعذّر الشراء", "err");
    await helpers.refresh();
    setPurchasedCard({ code: r.code, category: cat.name, price: cat.price, speed: cat.speed, validity: cat.validity });
  };

  return (
    <div style={{ maxWidth: 1100, margin: "0 auto", padding: "22px 18px 60px" }}>
      <TopBar
        title={`أهلاً، ${c.name}`}
        sub={`📞 ${c.phone}${c.region ? ` · ${c.region}` : ""}`}
        onLogout={onLogout}
        nav={[
          { id: "shop", label: "المتجر", icon: <Package size={16} /> },
          { id: "deposit", label: "إيداع", icon: <ArrowUpRight size={16} /> },
          { id: "history", label: "سجل المعاملات", icon: <Receipt size={16} /> },
          { id: "settings", label: "الإعدادات", icon: <Settings size={16} /> },
        ]}
        view={view} setView={setView}
      />

      <div style={S.statGrid}>
        <StatCard icon={<Wallet size={22} />} label="رصيد المحفظة" value={`${fmt(c.balance)} ${CURRENCY}`} tone="green"
          action={<button style={S.depositChip} onClick={() => setView("deposit")} className="press"><ArrowUpRight size={13} /> إيداع</button>} />
        <StatCard icon={<TrendingDown size={22} />} label="المديونية" value={`${fmt(c.debt)} ${CURRENCY}`} tone="red" />
        <StatCard icon={<CreditCard size={22} />} label="حد المديونية" value={`${fmt(c.debtLimit)} ${CURRENCY}`} tone="blue" />
      </div>

      {view === "shop" && (
        <div style={S.cardGrid}>
          {db.categories.length === 0 && <Empty text="لا توجد فئات متاحة حالياً" />}
          {db.categories.map((cat) => {
            const available = cat.codes.some((x) => !x.used);
            return (
              <div key={cat.id} style={S.netCard} className="lift">
                <div style={S.netCardTop}>
                  <Wifi size={20} />
                  {!available && <span style={S.availBadge(0)}>نفدت</span>}
                </div>
                <h3 style={S.netCardName}>{cat.name}</h3>
                <div style={S.netCardMeta}><span>السرعة: {cat.speed}</span><span>المدة: {cat.validity}</span></div>
                <div style={S.netCardPrice}>{fmt(cat.price)} <small>{CURRENCY}</small></div>
                <button style={{ ...S.buyBtn, ...(!available ? S.buyBtnDisabled : {}) }} disabled={!available} onClick={() => buy(cat)} className={!available ? "" : "press"}>
                  <ShoppingCart size={16} /> {available ? "شراء الآن" : "غير متاح"}
                </button>
              </div>
            );
          })}
        </div>
      )}

      {view === "deposit" && <CustomerDeposit db={db} persist={persist} phone={phone} helpers={helpers} myDeposits={myDeposits} />}
      {view === "history" && <CustomerTxTable rows={myTx} />}
      {view === "settings" && <CustomerSettings phone={phone} db={db} persist={persist} helpers={helpers} />}

      {purchasedCard && <PurchaseModal card={purchasedCard} onClose={() => setPurchasedCard(null)} showToast={helpers.showToast} />}
    </div>
  );
}

function PurchaseModal({ card, onClose, showToast }) {
  const copy = () => { navigator.clipboard.writeText(card.code); showToast("تم نسخ الكود", "ok"); };
  return (
    <div style={S.modalBg} onClick={onClose}>
      <div style={{ ...S.modal, maxWidth: 440, padding: 0, overflow: "hidden" }} onClick={(e) => e.stopPropagation()} className="rise">
        {/* Header */}
        <div style={S.purchaseHead}>
          <div style={S.purchaseSuccess} className="pulse"><Check size={28} /></div>
          <h2 style={{ margin: "12px 0 4px", fontFamily: "Tajawal", fontSize: 22, color: "#06120f" }}>تمّت العملية بنجاح!</h2>
          <p style={{ margin: 0, fontSize: 13, color: "rgba(6,18,15,.7)" }}>كرتك جاهز للاستخدام</p>
        </div>
        {/* The Card */}
        <div style={{ padding: "20px 22px 6px" }}>
          <div style={S.purchaseCard}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 14 }}>
              <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                <Wifi size={20} color="#22e0a1" />
                <span style={{ color: "#22e0a1", fontWeight: 800, letterSpacing: 1, fontSize: 14 }}>NETCARD</span>
              </div>
              <span style={S.purchaseCatBadge}>{card.category}</span>
            </div>
            <div style={{ borderTop: "1px dashed rgba(34,224,161,.25)", paddingTop: 16, marginBottom: 16 }}>
              <p style={{ margin: 0, fontSize: 11, color: "#9fbdb4", letterSpacing: 2 }}>رقم الكرت</p>
              <p style={{ margin: "8px 0 0", fontFamily: "monospace", fontSize: 26, fontWeight: 800, color: "#22e0a1", letterSpacing: 4, textAlign: "center", direction: "ltr", wordBreak: "break-all" }}>
                {card.code}
              </p>
            </div>
            <div style={{ display: "flex", justifyContent: "space-between", fontSize: 12, color: "#9fbdb4", flexWrap: "wrap", gap: 8 }}>
              <span>السرعة: <b style={{ color: "#cfe6df" }}>{card.speed}</b></span>
              <span>المدة: <b style={{ color: "#cfe6df" }}>{card.validity}</b></span>
              <span>السعر: <b style={{ color: "#cfe6df" }}>{fmt(card.price)} {CURRENCY}</b></span>
            </div>
          </div>
          <button onClick={copy} style={{ ...S.primaryBtn, width: "100%", marginTop: 14 }} className="press"><Copy size={16} /> نسخ رقم الكرت</button>
          <button onClick={onClose} style={{ ...S.miniBtnGray, width: "100%", marginTop: 8, padding: "11px", justifyContent: "center" }}>إغلاق</button>
        </div>
      </div>
    </div>
  );
}

function CustomerSettings({ phone, db, persist, helpers }) {
  const [cur, setCur] = useState("");
  const [np, setNp] = useState("");
  const [cf, setCf] = useState("");
  const [show, setShow] = useState(false);
  const c = db.customers[phone];

  const change = async () => {
    if (!cur || !np || !cf) return helpers.showToast("املأ جميع الحقول", "err");
    if (np.length < 4) return helpers.showToast("كلمة المرور الجديدة قصيرة جداً", "err");
    if (np !== cf) return helpers.showToast("كلمتا المرور غير متطابقتين", "err");
    const r = await api("change-my-password", { current: cur, new: np });
    if (r && r.ok) {
      setCur(""); setNp(""); setCf("");
      helpers.showToast("تم تغيير كلمة المرور بنجاح", "ok");
    } else if (r && r.reason === "wrong_current") {
      helpers.showToast("كلمة المرور الحالية غير صحيحة", "err");
    } else {
      helpers.showToast("تعذّر تغيير كلمة المرور", "err");
    }
  };

  return (
    <Section title="تغيير كلمة المرور">
      <div style={{ display: "grid", gap: 14, maxWidth: 420 }}>
        <Field label="كلمة المرور الحالية">
          <input style={S.input} type={show ? "text" : "password"} value={cur} onChange={(e) => setCur(e.target.value)} />
        </Field>
        <Field label="كلمة المرور الجديدة">
          <input style={S.input} type={show ? "text" : "password"} value={np} onChange={(e) => setNp(e.target.value)} />
        </Field>
        <Field label="تأكيد كلمة المرور الجديدة">
          <input style={S.input} type={show ? "text" : "password"} value={cf} onChange={(e) => setCf(e.target.value)} />
        </Field>
        <label style={{ display: "flex", alignItems: "center", gap: 8, fontSize: 13, color: "#9fbdb4", cursor: "pointer" }}>
          <input type="checkbox" checked={show} onChange={(e) => setShow(e.target.checked)} /> إظهار كلمات المرور
        </label>
        <button onClick={change} style={S.primaryBtn} className="press"><Check size={16} /> حفظ كلمة المرور الجديدة</button>
      </div>
    </Section>
  );
}

function CustomerDeposit({ db, persist, phone, helpers, myDeposits }) {
  const [amount, setAmount] = useState("");
  const [note, setNote] = useState("");
  const pending = myDeposits.filter((r) => r.status === "pending");
  const history = myDeposits.filter((r) => r.status !== "pending");

  const submit = async () => {
    const v = Number(amount);
    if (!v || v <= 0) return helpers.showToast("أدخل مبلغاً صحيحاً", "err");
    const r = await api("customer-deposit-request", { amount: v, note: note.trim() });
    if (!r || !r.ok) return helpers.showToast(r?.error || "تعذّر إرسال الطلب", "err");
    await helpers.refresh();
    setAmount(""); setNote("");
    helpers.showToast("تم إرسال طلب الإيداع. بانتظار الموافقة", "ok");
    // إشعار تيليجرام يُرسَل تلقائياً من الخادم عند إنشاء الطلب
  };

  return (
    <>
      <Section title="طلب إيداع جديد">
        <div style={{ display: "grid", gap: 12, maxWidth: 460 }}>
          <Field label={`المبلغ (${CURRENCY})`}>
            <input style={S.input} type="number" placeholder="مثال: 5000" value={amount} onChange={(e) => setAmount(e.target.value)} />
          </Field>
          <Field label="ملاحظة (اختياري — رقم العملية، طريقة الدفع، إلخ)">
            <textarea style={{ ...S.input, minHeight: 70, resize: "vertical" }} value={note} onChange={(e) => setNote(e.target.value)} placeholder="مثال: تحويل بنكي رقم 12345" />
          </Field>
          <button style={S.primaryBtn} onClick={submit} className="press"><ArrowUpRight size={16} /> إرسال الطلب</button>
          <p style={{ color: "#9fbdb4", fontSize: 12.5, margin: 0 }}>عند الموافقة، يُسدَّد الدين أولاً تلقائياً ثم يُضاف الباقي للرصيد.</p>
        </div>
      </Section>

      <Section title={`طلبات قيد المراجعة (${pending.length})`}>
        {pending.length === 0 ? <Empty text="لا توجد طلبات معلقة" /> : (
          <div style={{ display: "grid", gap: 10 }}>
            {pending.map((r) => (
              <div key={r.id} style={S.reqRow}>
                <div>
                  <div style={{ fontWeight: 700, fontSize: 16 }}>{fmt(r.amount)} {CURRENCY}</div>
                  <div style={{ fontSize: 12, color: "#9fbdb4" }}>{fmtDate(r.date)}</div>
                  {r.note && <div style={{ fontSize: 12, color: "#cfe6df", marginTop: 4 }}>📝 {r.note}</div>}
                </div>
                <span style={S.statusPending}><Clock size={13} /> قيد المراجعة</span>
              </div>
            ))}
          </div>
        )}
      </Section>

      <Section title="السجل">
        {history.length === 0 ? <Empty text="لا يوجد سجل بعد" /> : (
          <div style={{ display: "grid", gap: 10 }}>
            {history.map((r) => (
              <div key={r.id} style={S.reqRow}>
                <div>
                  <div style={{ fontWeight: 700, fontSize: 16 }}>{fmt(r.amount)} {CURRENCY}</div>
                  <div style={{ fontSize: 12, color: "#9fbdb4" }}>{fmtDate(r.date)}</div>
                  {r.note && <div style={{ fontSize: 12, color: "#cfe6df", marginTop: 4 }}>📝 {r.note}</div>}
                  {r.rejectReason && <div style={{ fontSize: 12, color: "#ff8585", marginTop: 4 }}>سبب الرفض: {r.rejectReason}</div>}
                </div>
                {r.status === "approved" ? <span style={S.statusOk}><Check size={13} /> موافق</span> : <span style={S.statusBad}><X size={13} /> مرفوض</span>}
              </div>
            ))}
          </div>
        )}
      </Section>
    </>
  );
}

function CustomerTxTable({ rows }) {
  return (
    <Section title="سجل معاملاتي">
      {rows.length === 0 ? <Empty text="لا توجد معاملات" /> : (
        <div style={{ overflowX: "auto" }}>
          <table style={S.table}>
            <thead>
              <tr><th style={S.th}>التاريخ</th><th style={S.th}>النوع</th><th style={S.th}>المبلغ</th><th style={S.th}>فئة الكرت</th><th style={S.th}>رقم الكرت</th><th style={S.th}>الرصيد بعد</th><th style={S.th}>الدين بعد</th></tr>
            </thead>
            <tbody>
              {rows.map((t) => (
                <tr key={t.id} style={S.tr}>
                  <td style={{ ...S.td, fontSize: 12 }}>{fmtDate(t.date)}</td>
                  <td style={S.td}><TypeTag type={t.type} /></td>
                  <td style={{ ...S.td, color: t.amount >= 0 ? "#22e0a1" : "#ff6b6b", fontWeight: 700 }}>{t.amount >= 0 ? "+" : ""}{fmt(t.amount)}</td>
                  <td style={S.td}>{t.category || "-"}</td>
                  <td style={{ ...S.td, fontFamily: "monospace", fontSize: 12 }}>{t.code || "-"}</td>
                  <td style={S.td}>{fmt(t.balanceAfter)}</td>
                  <td style={{ ...S.td, color: t.debtAfter > 0 ? "#ff6b6b" : "#6b8a82" }}>{fmt(t.debtAfter)}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}
    </Section>
  );
}

/* ============================================================
   Admin Panel
   ============================================================ */
function AdminPanel({ db, persist, onLogout, helpers }) {
  const [view, setView] = useState("dash");
  const [customerView, setCustomerView] = useState(null); // phone | null
  const pendingCount = db.depositRequests.filter((r) => r.status === "pending").length;

  // عند تبديل التبويبات أعد ضبط واجهة الزبون
  useEffect(() => { setCustomerView(null); }, [view]);

  if (customerView) {
    return (
      <div style={{ maxWidth: 1100, margin: "0 auto", padding: "22px 18px 60px" }}>
        <CustomerDetail db={db} persist={persist} phone={customerView} onBack={() => setCustomerView(null)} onLogout={onLogout} helpers={helpers} />
      </div>
    );
  }

  return (
    <div style={{ maxWidth: 1280, margin: "0 auto", padding: "22px 18px 60px" }}>
      <TopBar
        title="لوحة تحكم الأدمن"
        sub="إدارة كاملة للمنصة"
        onLogout={onLogout}
        admin
        nav={[
          { id: "dash", label: "الإحصائيات", icon: <BarChart3 size={16} /> },
          { id: "customers", label: "الزبائن", icon: <Users size={16} /> },
          { id: "agents", label: "الوكلاء", icon: <UserCheck size={16} /> },
          { id: "deposits", label: "طلبات الإيداعات", icon: <ArrowUpRight size={16} />, badge: pendingCount },
          { id: "cats", label: "الفئات والكروت", icon: <Package size={16} /> },
          { id: "tx", label: "كل المعاملات", icon: <Receipt size={16} /> },
          { id: "settings", label: "الإعدادات", icon: <Settings size={16} /> },
        ]}
        view={view} setView={setView}
      />
      {view === "dash" && <AdminDash db={db} />}
      {view === "customers" && <AdminCustomers db={db} persist={persist} helpers={helpers} onOpenCustomer={setCustomerView} />}
      {view === "agents" && <AdminAgents db={db} persist={persist} helpers={helpers} />}
      {view === "deposits" && <DepositsView db={db} persist={persist} helpers={helpers} allowedRegions={null} processorName="الأدمن" />}
      {view === "cats" && <AdminCats db={db} persist={persist} helpers={helpers} />}
      {view === "tx" && <AdminTx db={db} persist={persist} helpers={helpers} />}
      {view === "settings" && <AdminSettings db={db} persist={persist} helpers={helpers} />}
    </div>
  );
}

/* ============================================================
   Admin Dashboard — Top customers + Top regions + New category viz
   ============================================================ */
function AdminDash({ db }) {
  const customers = Object.values(db.customers);
  const totalBalance = customers.reduce((s, c) => s + c.balance, 0);
  const totalDebt = customers.reduce((s, c) => s + c.debt, 0);
  const purchases = db.transactions.filter((t) => t.type === "شراء" || t.type === "مديونية");
  const revenue = purchases.reduce((s, t) => s + Math.abs(t.amount), 0);
  const codesTotal = db.categories.reduce((s, c) => s + c.codes.length, 0);
  const codesSold = db.categories.reduce((s, c) => s + c.codes.filter((x) => x.used).length, 0);

  // أكثر الزبائن شراءً
  const byCustomer = {};
  purchases.forEach((t) => {
    if (!byCustomer[t.customer]) byCustomer[t.customer] = { count: 0, amount: 0 };
    byCustomer[t.customer].count++;
    byCustomer[t.customer].amount += Math.abs(t.amount);
  });
  const topCustomers = Object.entries(byCustomer)
    .map(([phone, v]) => ({ phone, ...v, name: db.customers[phone]?.name || phone, region: db.customers[phone]?.region || "-" }))
    .sort((a, b) => b.count - a.count).slice(0, 5);

  // أكثر المناطق شراءً
  const byRegion = {};
  purchases.forEach((t) => {
    const region = db.customers[t.customer]?.region || "غير محددة";
    if (!byRegion[region]) byRegion[region] = { count: 0, amount: 0 };
    byRegion[region].count++;
    byRegion[region].amount += Math.abs(t.amount);
  });
  const topRegions = Object.entries(byRegion).map(([region, v]) => ({ region, ...v })).sort((a, b) => b.count - a.count).slice(0, 5);

  // فئات
  const catStats = db.categories.map((c) => {
    const cnt = purchases.filter((t) => t.category === c.name).length;
    const rev = purchases.filter((t) => t.category === c.name).reduce((s, t) => s + Math.abs(t.amount), 0);
    const avail = c.codes.filter((x) => !x.used).length;
    return { ...c, salesCount: cnt, salesRevenue: rev, availCount: avail };
  });

  return (
    <>
      <div style={S.statGrid}>
        <StatCard icon={<Receipt size={22} />} label="إجمالي المبيعات" value={`${fmt(revenue)} ${CURRENCY}`} tone="green" />
        <StatCard icon={<Wallet size={22} />} label="رصيد الزبائن" value={`${fmt(totalBalance)} ${CURRENCY}`} tone="blue" />
        <StatCard icon={<TrendingDown size={22} />} label="إجمالي المديونيات" value={`${fmt(totalDebt)} ${CURRENCY}`} tone="red" />
        <StatCard icon={<Users size={22} />} label="عدد الزبائن" value={fmt(customers.length)} tone="purple" />
      </div>
      <div style={S.statGrid}>
        <StatCard icon={<Package size={22} />} label="إجمالي الكروت" value={fmt(codesTotal)} tone="blue" />
        <StatCard icon={<CheckCircle size={22} />} label="كروت مباعة" value={fmt(codesSold)} tone="green" />
        <StatCard icon={<CreditCard size={22} />} label="كروت متبقية" value={fmt(codesTotal - codesSold)} tone="purple" />
      </div>

      {/* أكثر الزبائن والمناطق */}
      <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(320px,1fr))", gap: 18, marginBottom: 20 }}>
        <Section title={<><Trophy size={16} style={{ verticalAlign: "-3px", color: "#ffc94c", marginLeft: 6 }} /> أكثر الزبائن شراءً</>}>
          {topCustomers.length === 0 ? <Empty text="لا توجد مبيعات بعد" /> : (
            <Leaderboard
              rows={topCustomers.map((c, i) => ({
                rank: i + 1, primary: c.name, secondary: c.region,
                metric: `${c.count} كرت`, sub: `${fmt(c.amount)} ${CURRENCY}`,
                pct: (c.count / topCustomers[0].count) * 100,
              }))}
            />
          )}
        </Section>
        <Section title={<><MapPin size={16} style={{ verticalAlign: "-3px", color: "#4cb6ff", marginLeft: 6 }} /> أكثر المناطق شراءً</>}>
          {topRegions.length === 0 ? <Empty text="لا توجد مبيعات بعد" /> : (
            <Leaderboard
              rows={topRegions.map((r, i) => ({
                rank: i + 1, primary: r.region, secondary: `${db.customers ? Object.values(db.customers).filter(c => (c.region || "غير محددة") === r.region).length : 0} زبون`,
                metric: `${r.count} كرت`, sub: `${fmt(r.amount)} ${CURRENCY}`,
                pct: (r.count / topRegions[0].count) * 100,
              }))}
            />
          )}
        </Section>
      </div>

      {/* الفئات */}
      <Section title="أداء الفئات">
        {catStats.length === 0 ? <Empty text="لا توجد فئات" /> : (
          <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill,minmax(240px,1fr))", gap: 14 }}>
            {catStats.map((c) => {
              const pctOfRev = revenue > 0 ? (c.salesRevenue / revenue) * 100 : 0;
              return (
                <div key={c.id} style={S.catStatCard}>
                  <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 12 }}>
                    <div style={{ fontWeight: 700, fontFamily: "Tajawal", fontSize: 15 }}>{c.name}</div>
                    <div style={S.catPctBadge}>{pctOfRev.toFixed(0)}%</div>
                  </div>
                  <div style={S.catGrid}>
                    <div>
                      <div style={S.catLabel}>كروت مباعة</div>
                      <div style={{ ...S.catVal, color: "#22e0a1" }}>{fmt(c.salesCount)}</div>
                    </div>
                    <div>
                      <div style={S.catLabel}>الإيرادات</div>
                      <div style={S.catVal}>{fmt(c.salesRevenue)}</div>
                    </div>
                    <div>
                      <div style={S.catLabel}>متبقي</div>
                      <div style={{ ...S.catVal, color: c.availCount === 0 ? "#ff6b6b" : "#cfe6df" }}>{fmt(c.availCount)}</div>
                    </div>
                    <div>
                      <div style={S.catLabel}>السعر</div>
                      <div style={S.catVal}>{fmt(c.price)}</div>
                    </div>
                  </div>
                  <div style={{ ...S.barTrack, marginTop: 14 }}>
                    <div style={{ ...S.barFill, width: `${pctOfRev}%` }} />
                  </div>
                </div>
              );
            })}
          </div>
        )}
      </Section>
    </>
  );
}

function Leaderboard({ rows }) {
  return (
    <div style={{ display: "grid", gap: 12 }}>
      {rows.map((r) => (
        <div key={r.rank} style={S.leaderRow}>
          <div style={{ ...S.rankBadge, ...(r.rank === 1 ? S.rankGold : r.rank === 2 ? S.rankSilver : r.rank === 3 ? S.rankBronze : {}) }}>
            {r.rank}
          </div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ display: "flex", justifyContent: "space-between", marginBottom: 6, gap: 8, flexWrap: "wrap" }}>
              <div style={{ minWidth: 0 }}>
                <div style={{ fontSize: 14, fontWeight: 700, fontFamily: "Tajawal", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{r.primary}</div>
                <div style={{ fontSize: 11.5, color: "#9fbdb4" }}>{r.secondary}</div>
              </div>
              <div style={{ textAlign: "left" }}>
                <div style={{ fontSize: 14, fontWeight: 700, color: "#22e0a1" }}>{r.metric}</div>
                <div style={{ fontSize: 11, color: "#9fbdb4" }}>{r.sub}</div>
              </div>
            </div>
            <div style={S.barTrack}><div style={{ ...S.barFill, width: `${r.pct}%` }} /></div>
          </div>
        </div>
      ))}
    </div>
  );
}

/* ============================================================
   Admin — Customers (no per-row actions, click name → detail)
   ============================================================ */
function AdminCustomers({ db, persist, helpers, onOpenCustomer }) {
  const [q, setQ] = useState("");
  const [sort, setSort] = useState("newest");
  const [showForm, setShowForm] = useState(false);
  const [form, setForm] = useState({ phone: "", name: "", region: "", debtLimit: String(db.defaultDebtLimit) });

  useEffect(() => { setForm((f) => ({ ...f, debtLimit: String(db.defaultDebtLimit) })); }, [db.defaultDebtLimit]);

  const addCustomer = async () => {
    const phone = form.phone.trim();
    if (!phone || !form.name.trim()) return helpers.showToast("أدخل رقم الهاتف والاسم", "err");
    if (db.customers[phone]) return helpers.showToast("رقم الهاتف مسجل مسبقاً", "err");
    const pass = randomPass();
    const next = {
      ...db,
      customers: {
        ...db.customers,
        [phone]: { phone, name: form.name.trim(), region: form.region.trim(), balance: 0, debt: 0, debtLimit: Number(form.debtLimit) || 0, banned: false, createdAt: now() },
      },
    };
    persist(next);
    await saveDB(next);               // تأكّد من وجود السطر قبل ضبط كلمة المرور
    await api("set-password", { role: "customer", phone, newPassword: pass });
    setForm({ phone: "", name: "", region: "", debtLimit: String(db.defaultDebtLimit) });
    setShowForm(false);
    helpers.setModal({ title: "تم إنشاء الحساب بنجاح", body: <CredentialsCard phone={phone} pass={pass} showToast={helpers.showToast} /> });
  };

  let list = Object.values(db.customers);
  if (q) {
    const Q = q.trim();
    list = list.filter((c) => c.phone.includes(Q) || c.name.includes(Q) || (c.region || "").includes(Q));
  }
  const sorters = {
    newest: (a, b) => b.createdAt.localeCompare(a.createdAt),
    oldest: (a, b) => a.createdAt.localeCompare(b.createdAt),
    name: (a, b) => a.name.localeCompare(b.name, "ar"),
    balance: (a, b) => b.balance - a.balance,
    debt: (a, b) => b.debt - a.debt,
  };
  list = list.sort(sorters[sort]);

  return (
    <>
      <Section title="إدارة الزبائن" right={
        <button style={S.primaryBtn} onClick={() => setShowForm((s) => !s)} className="press">
          {showForm ? <><X size={15} /> إلغاء</> : <><Plus size={15} /> إضافة زبون</>}
        </button>
      }>
        {showForm && (
          <div style={S.collapseBox} className="rise">
            <h4 style={{ margin: "0 0 12px", fontSize: 14, color: "#22e0a1" }}>زبون جديد</h4>
            <div style={S.formGrid}>
              <Field label="رقم الهاتف *"><input style={S.input} value={form.phone} onChange={(e) => setForm({ ...form, phone: e.target.value })} placeholder="7XXXXXXXX" /></Field>
              <Field label="الاسم الكامل *"><input style={S.input} value={form.name} onChange={(e) => setForm({ ...form, name: e.target.value })} placeholder="محمد علي" /></Field>
              <Field label="المنطقة"><input style={S.input} value={form.region} onChange={(e) => setForm({ ...form, region: e.target.value })} placeholder="الحاطة" /></Field>
              <Field label="حد المديونية"><input style={S.input} type="number" value={form.debtLimit} onChange={(e) => setForm({ ...form, debtLimit: e.target.value })} /></Field>
            </div>
            <div style={{ display: "flex", gap: 10, marginTop: 14, flexWrap: "wrap" }}>
              <button style={S.primaryBtn} onClick={addCustomer} className="press"><Check size={16} /> حفظ وإنشاء كلمة مرور</button>
              <span style={{ fontSize: 12, color: "#9fbdb4", alignSelf: "center" }}>سيتم توليد كلمة مرور عشوائية تلقائياً</span>
            </div>
          </div>
        )}
      </Section>

      <Section
        title={`قائمة الزبائن (${list.length})`}
        right={
          <div style={{ display: "flex", gap: 8, flexWrap: "wrap", alignItems: "center" }}>
            <div style={{ position: "relative" }}>
              <Search size={15} style={{ position: "absolute", right: 10, top: 10, color: "#6b8a82" }} />
              <input style={{ ...S.input, paddingRight: 32, width: 180, margin: 0 }} placeholder="بحث…" value={q} onChange={(e) => setQ(e.target.value)} />
            </div>
            <div style={{ position: "relative" }}>
              <ChevronsUpDown size={14} style={{ position: "absolute", right: 10, top: 12, color: "#6b8a82", pointerEvents: "none" }} />
              <select style={{ ...S.input, paddingRight: 32, width: 180, margin: 0, appearance: "none" }} value={sort} onChange={(e) => setSort(e.target.value)}>
                <option value="newest">الأحدث إضافةً</option><option value="oldest">الأقدم إضافةً</option>
                <option value="name">الاسم أبجدياً</option><option value="balance">الأكبر رصيداً</option><option value="debt">الأكبر مديونيةً</option>
              </select>
            </div>
          </div>
        }
      >
        <p style={{ color: "#9fbdb4", fontSize: 12.5, margin: "0 0 12px" }}>اضغط على اسم الزبون للوصول إلى صفحته التفصيلية.</p>
        <div style={{ overflowX: "auto" }}>
          <table style={S.table}>
            <thead>
              <tr>{["الهاتف", "الاسم", "المنطقة", "تاريخ الإضافة", "الرصيد", "المديونية", "الحد", "الحالة"].map((h) => <th key={h} style={S.th}>{h}</th>)}</tr>
            </thead>
            <tbody>
              {list.length === 0 && <tr><td colSpan={8} style={S.tdEmpty}>لا يوجد زبائن</td></tr>}
              {list.map((c) => (
                <tr key={c.phone} style={{ ...S.tr, opacity: c.banned ? 0.55 : 1, cursor: "pointer" }} className="rowHover" onClick={() => onOpenCustomer(c.phone)}>
                  <td style={{ ...S.td, fontFamily: "monospace" }}>{c.phone}</td>
                  <td style={S.td}>
                    <span style={S.customerLink}>{c.name} <ArrowLeft size={12} style={{ verticalAlign: "-1px" }} /></span>
                  </td>
                  <td style={{ ...S.td, color: "#9fbdb4" }}>{c.region || "-"}</td>
                  <td style={{ ...S.td, fontSize: 12, color: "#9fbdb4" }}>{fmtDay(c.createdAt)}</td>
                  <td style={{ ...S.td, color: "#22e0a1" }}>{fmt(c.balance)}</td>
                  <td style={{ ...S.td, color: c.debt > 0 ? "#ff6b6b" : "#6b8a82" }}>{fmt(c.debt)}</td>
                  <td style={S.td}>{fmt(c.debtLimit)}</td>
                  <td style={S.td}>{c.banned ? <span style={S.tagBanned}><Ban size={12} /> محظور</span> : <span style={S.tagOk}>نشط</span>}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </Section>
    </>
  );
}

function CredentialsCard({ phone, pass, showToast }) {
  const copy = (txt) => { navigator.clipboard.writeText(txt); showToast("تم النسخ", "ok"); };
  return (
    <div style={{ display: "grid", gap: 12 }}>
      <p style={{ margin: 0, fontSize: 14, color: "#9fbdb4" }}>احفظ هذه البيانات وسلّمها للحساب. لن تظهر كلمة المرور مرة أخرى.</p>
      <div style={S.credRow}>
        <div><p style={{ margin: 0, fontSize: 12, color: "#9fbdb4" }}>رقم الهاتف</p><p style={{ margin: "2px 0 0", fontFamily: "monospace", fontSize: 16, fontWeight: 700 }}>{phone}</p></div>
        <button style={S.miniBtnBlue} onClick={() => copy(phone)}><Copy size={13} /> نسخ</button>
      </div>
      <div style={S.credRow}>
        <div><p style={{ margin: 0, fontSize: 12, color: "#9fbdb4" }}>كلمة المرور</p><p style={{ margin: "2px 0 0", fontFamily: "monospace", fontSize: 18, fontWeight: 700, color: "#22e0a1", letterSpacing: 2 }}>{pass}</p></div>
        <button style={S.miniBtnBlue} onClick={() => copy(pass)}><Copy size={13} /> نسخ</button>
      </div>
      <button style={S.miniBtn} onClick={() => copy(`📱 ${phone}\n🔑 ${pass}`)}><Copy size={13} /> نسخ الكل</button>
    </div>
  );
}

/* ============================================================
   Customer Detail Page (admin view)
   ============================================================ */
function CustomerDetail({ db, persist, phone, onBack, onLogout, helpers }) {
  const [tab, setTab] = useState("tx");
  const c = db.customers[phone];
  if (!c) return <Empty text="الزبون غير موجود" />;

  const myTx = db.transactions.filter((t) => t.customer === phone).sort((a, b) => b.date.localeCompare(a.date));
  const myDeposits = db.depositRequests.filter((r) => r.customer === phone).sort((a, b) => b.date.localeCompare(a.date));
  const purchases = myTx.filter((t) => t.type === "شراء" || t.type === "مديونية");
  const deposits = myTx.filter((t) => t.type === "إيداع");

  const totalSpent = purchases.reduce((s, t) => s + Math.abs(t.amount), 0);
  const totalDeposited = deposits.reduce((s, t) => s + t.amount, 0);

  const doDeposit = () => {
    helpers.askPrompt(
      { title: "إيداع رصيد", label: "المبلغ (سيُسدّد الدين أولاً تلقائياً)", inputType: "number", placeholder: "5000" },
      (v) => {
        const amt = Number(v);
        if (!amt || amt <= 0) return helpers.showToast("قيمة غير صحيحة", "err");
        persist((prev) => {
          const cust = prev.customers[phone];
          let bal = cust.balance, debt = cust.debt, left = amt;
          if (debt > 0) { const pay = Math.min(debt, left); debt -= pay; left -= pay; }
          bal += left;
          const next = { ...prev };
          next.customers = { ...prev.customers, [phone]: { ...cust, balance: bal, debt } };
          next.transactions = [
            { id: uid(), customer: phone, type: "إيداع", amount: amt, balanceAfter: bal, debtAfter: debt, date: now(), category: "-", code: "-", cardAddedAt: null, activated: false, activatedAt: null },
            ...prev.transactions,
          ];
          return next;
        });
        helpers.showToast("تم الإيداع", "ok");
      }
    );
  };

  const setLimit = () => {
    helpers.askPrompt(
      { title: "تغيير حد المديونية", label: "الحد الجديد", inputType: "number", placeholder: String(c.debtLimit), defaultValue: String(c.debtLimit) },
      (v) => {
        const lim = Number(v);
        if (isNaN(lim) || lim < 0) return helpers.showToast("قيمة غير صحيحة", "err");
        persist((prev) => ({ ...prev, customers: { ...prev.customers, [phone]: { ...prev.customers[phone], debtLimit: lim } } }));
        helpers.showToast("تم تحديث حد المديونية", "ok");
      }
    );
  };

  const regenPass = () => {
    helpers.askConfirm(
      { title: "توليد كلمة مرور جديدة", message: "ستُستبدل كلمة المرور الحالية بكلمة مرور عشوائية جديدة. هل تريد المتابعة؟" },
      async () => {
        const np = randomPass();
        const r = await api("set-password", { role: "customer", phone, newPassword: np });
        if (r && r.ok) helpers.setModal({ title: "كلمة مرور جديدة", body: <CredentialsCard phone={phone} pass={np} showToast={helpers.showToast} /> });
        else helpers.showToast("تعذّر تغيير كلمة المرور", "err");
      }
    );
  };

  const toggleBan = () => {
    helpers.askConfirm(
      { title: c.banned ? "فك الحظر" : "حظر الزبون", message: c.banned ? "سيتمكن الزبون من تسجيل الدخول مجدداً." : "لن يتمكن الزبون من تسجيل الدخول.", danger: !c.banned },
      () => {
        persist((prev) => ({ ...prev, customers: { ...prev.customers, [phone]: { ...prev.customers[phone], banned: !c.banned } } }));
        helpers.showToast(c.banned ? "تم فك الحظر" : "تم الحظر", "ok");
      }
    );
  };

  const editInfo = () => {
    helpers.setModal({
      title: "تعديل بيانات الزبون",
      body: <EditCustomerForm c={c} onSave={(updated) => {
        persist((prev) => ({ ...prev, customers: { ...prev.customers, [phone]: { ...prev.customers[phone], ...updated } } }));
        helpers.showToast("تم التحديث", "ok");
        helpers.setModal(null);
      }} />,
    });
  };

  const delCustomer = () => {
    helpers.askConfirm(
      { title: "حذف الزبون", message: `سيتم حذف ${c.name} نهائياً. لن تتأثر سجلات معاملاته السابقة.`, danger: true },
      () => {
        persist((prev) => {
          const cs = { ...prev.customers };
          delete cs[phone];
          return { ...prev, customers: cs };
        });
        helpers.showToast("تم حذف الزبون", "ok");
        onBack();
      }
    );
  };

  return (
    <>
      <div style={{ marginBottom: 18 }}>
        <div style={S.topRow}>
          <button style={S.backBtn} onClick={onBack} className="press"><ArrowRight size={15} /> العودة للقائمة</button>
          <button style={S.logoutBtn} onClick={onLogout} className="press"><LogOut size={16} /> خروج</button>
        </div>
      </div>

      <div style={{ ...S.section, background: "linear-gradient(160deg,rgba(15,40,33,.9),rgba(8,22,18,.75))", marginBottom: 18 }}>
        <div style={{ display: "flex", gap: 16, alignItems: "center", flexWrap: "wrap" }}>
          <div style={{ width: 60, height: 60, borderRadius: 16, background: c.banned ? "rgba(255,107,107,.2)" : "linear-gradient(135deg,#22e0a1,#0e9b6f)", display: "grid", placeItems: "center", color: c.banned ? "#ff8585" : "#06120f", fontWeight: 800, fontSize: 24, fontFamily: "Tajawal" }}>
            {c.name.charAt(0)}
          </div>
          <div style={{ flex: 1, minWidth: 200 }}>
            <h2 style={{ margin: 0, fontFamily: "Tajawal", fontSize: 22, display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap" }}>
              {c.name}
              {c.banned && <span style={S.tagBanned}><Ban size={12} /> محظور</span>}
            </h2>
            <div style={{ marginTop: 6, color: "#9fbdb4", fontSize: 13, display: "flex", gap: 14, flexWrap: "wrap" }}>
              <span><Phone size={12} style={{ verticalAlign: "-1px" }} /> {c.phone}</span>
              <span><MapPin size={12} style={{ verticalAlign: "-1px" }} /> {c.region || "بدون منطقة"}</span>
              <span><Clock size={12} style={{ verticalAlign: "-1px" }} /> منذ {fmtDay(c.createdAt)}</span>
            </div>
          </div>
        </div>

        {/* أزرار الإجراءات */}
        <div style={{ display: "flex", gap: 8, flexWrap: "wrap", marginTop: 18, paddingTop: 16, borderTop: "1px solid rgba(34,224,161,.12)" }}>
          <button style={S.primaryBtn} onClick={doDeposit} className="press"><ArrowUpRight size={14} /> إيداع رصيد</button>
          <button style={S.miniBtnBlue} onClick={setLimit}><CreditCard size={13} /> تغيير حد المديونية</button>
          <button style={S.miniBtnBlue} onClick={editInfo}><Edit2 size={13} /> تعديل البيانات</button>
          <button style={S.miniBtnGray} onClick={regenPass}><RefreshCw size={13} /> توليد كلمة مرور</button>
          <button style={c.banned ? S.miniBtn : S.miniBtnOrange} onClick={toggleBan}><Ban size={13} /> {c.banned ? "فك الحظر" : "حظر"}</button>
          <button style={S.miniBtnRed} onClick={delCustomer}><Trash2 size={13} /> حذف الزبون</button>
        </div>
      </div>

      <div style={S.statGrid}>
        <StatCard icon={<Wallet size={22} />} label="رصيد المحفظة" value={`${fmt(c.balance)} ${CURRENCY}`} tone="green" />
        <StatCard icon={<TrendingDown size={22} />} label="المديونية" value={`${fmt(c.debt)} ${CURRENCY}`} tone="red" />
        <StatCard icon={<CreditCard size={22} />} label="حد المديونية" value={`${fmt(c.debtLimit)} ${CURRENCY}`} tone="blue" />
        <StatCard icon={<ShoppingCart size={22} />} label="عدد الكروت المشتراة" value={fmt(purchases.length)} tone="purple" />
        <StatCard icon={<Receipt size={22} />} label="إجمالي المشتريات" value={`${fmt(totalSpent)} ${CURRENCY}`} tone="green" />
        <StatCard icon={<ArrowUpRight size={22} />} label="إجمالي الإيداعات" value={`${fmt(totalDeposited)} ${CURRENCY}`} tone="blue" />
      </div>

      {/* تبويبات */}
      <div style={{ ...S.navRow, marginBottom: 18 }}>
        <button onClick={() => setTab("tx")} style={{ ...S.navBtn, ...(tab === "tx" ? S.navActive : {}) }}><Receipt size={14} /> المعاملات ({myTx.length})</button>
        <button onClick={() => setTab("dep")} style={{ ...S.navBtn, ...(tab === "dep" ? S.navActive : {}) }}><ArrowUpRight size={14} /> طلبات الإيداع ({myDeposits.length})</button>
        <button onClick={() => setTab("cards")} style={{ ...S.navBtn, ...(tab === "cards" ? S.navActive : {}) }}><Package size={14} /> الكروت المشتراة ({purchases.length})</button>
      </div>

      {tab === "tx" && <CustomerTxTable rows={myTx} />}
      {tab === "dep" && <CustomerDepositsList rows={myDeposits} />}
      {tab === "cards" && <CustomerCardsList rows={purchases} />}
    </>
  );
}

function EditCustomerForm({ c, onSave }) {
  const [f, setF] = useState({ name: c.name, region: c.region || "", debtLimit: String(c.debtLimit) });
  return (
    <div style={{ display: "grid", gap: 12 }}>
      <Field label="الاسم"><input style={S.input} value={f.name} onChange={(e) => setF({ ...f, name: e.target.value })} /></Field>
      <Field label="المنطقة"><input style={S.input} value={f.region} onChange={(e) => setF({ ...f, region: e.target.value })} /></Field>
      <Field label="حد المديونية"><input style={S.input} type="number" value={f.debtLimit} onChange={(e) => setF({ ...f, debtLimit: e.target.value })} /></Field>
      <button style={S.primaryBtn} onClick={() => onSave({ name: f.name.trim(), region: f.region.trim(), debtLimit: Number(f.debtLimit) || 0 })} className="press"><Check size={15} /> حفظ</button>
    </div>
  );
}

function CustomerDepositsList({ rows }) {
  if (rows.length === 0) return <Empty text="لا توجد طلبات إيداع" />;
  return (
    <Section title="طلبات الإيداع">
      <div style={{ display: "grid", gap: 10 }}>
        {rows.map((r) => (
          <div key={r.id} style={S.reqRow}>
            <div>
              <div style={{ fontWeight: 700, fontSize: 15 }}>{fmt(r.amount)} {CURRENCY}</div>
              <div style={{ fontSize: 12, color: "#9fbdb4" }}>{fmtDate(r.date)}</div>
              {r.note && <div style={{ fontSize: 12, color: "#cfe6df", marginTop: 4 }}>📝 {r.note}</div>}
              {r.rejectReason && <div style={{ fontSize: 12, color: "#ff8585", marginTop: 4 }}>سبب الرفض: {r.rejectReason}</div>}
            </div>
            {r.status === "pending" ? <span style={S.statusPending}><Clock size={13} /> قيد المراجعة</span>
              : r.status === "approved" ? <span style={S.statusOk}><Check size={13} /> موافق</span>
                : <span style={S.statusBad}><X size={13} /> مرفوض</span>}
          </div>
        ))}
      </div>
    </Section>
  );
}

function CustomerCardsList({ rows }) {
  if (rows.length === 0) return <Empty text="لم يشترِ هذا الزبون أي كرت بعد" />;
  return (
    <Section title="الكروت المشتراة">
      <div style={{ overflowX: "auto" }}>
        <table style={S.table}>
          <thead><tr><th style={S.th}>التاريخ</th><th style={S.th}>الفئة</th><th style={S.th}>رقم الكرت</th><th style={S.th}>المبلغ</th></tr></thead>
          <tbody>
            {rows.map((t) => (
              <tr key={t.id} style={S.tr}>
                <td style={{ ...S.td, fontSize: 12 }}>{fmtDate(t.date)}</td>
                <td style={S.td}>{t.category}</td>
                <td style={{ ...S.td, fontFamily: "monospace", fontSize: 12 }}>{t.code}</td>
                <td style={{ ...S.td, color: "#ff6b6b", fontWeight: 700 }}>{fmt(Math.abs(t.amount))}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </Section>
  );
}

/* ============================================================
   Deposits View (used by Admin and Agent)
   ============================================================ */
function DepositsView({ db, persist, helpers, allowedRegions, processorName }) {
  // allowedRegions: null → admin sees all. Array → filter to those regions.
  const filterByRegion = (r) => {
    if (!allowedRegions) return true;
    const reg = db.customers[r.customer]?.region || "";
    return allowedRegions.includes(reg);
  };

  const all = db.depositRequests.filter(filterByRegion).sort((a, b) => b.date.localeCompare(a.date));
  const pending = all.filter((r) => r.status === "pending");
  const history = all.filter((r) => r.status !== "pending");

  const approve = (r) => {
    const cust = db.customers[r.customer];
    if (!cust) return helpers.showToast("الزبون غير موجود (تم حذفه؟)", "err");
    helpers.askConfirm(
      { title: "تأكيد الإيداع", message: `الموافقة على إيداع ${fmt(r.amount)} ${CURRENCY} للزبون ${cust.name}؟ سيُسدَّد الدين أولاً ثم يُضاف الباقي للرصيد.` },
      () => {
        persist((prev) => {
          const c = prev.customers[r.customer];
          if (!c) return prev;
          let bal = c.balance, debt = c.debt, left = r.amount;
          if (debt > 0) { const pay = Math.min(debt, left); debt -= pay; left -= pay; }
          bal += left;
          return {
            ...prev,
            customers: { ...prev.customers, [r.customer]: { ...c, balance: bal, debt } },
            transactions: [
              { id: uid(), customer: r.customer, type: "إيداع", amount: r.amount, balanceAfter: bal, debtAfter: debt, date: now(), category: "-", code: "-", cardAddedAt: null },
              ...prev.transactions,
            ],
            depositRequests: prev.depositRequests.map((x) => x.id === r.id ? { ...x, status: "approved", processedAt: now(), processedBy: processorName || "-" } : x),
          };
        });
        helpers.showToast("تمت الموافقة وتنفيذ الإيداع", "ok");
      }
    );
  };

  const reject = (r) => {
    helpers.askPrompt(
      { title: "رفض الطلب", label: "سبب الرفض (اختياري)", inputType: "text", placeholder: "مثلاً: لم نستلم التحويل" },
      (reason) => {
        persist((prev) => ({
          ...prev,
          depositRequests: prev.depositRequests.map((x) => x.id === r.id ? { ...x, status: "rejected", processedAt: now(), processedBy: processorName || "-", rejectReason: reason || "" } : x),
        }));
        helpers.showToast("تم رفض الطلب", "ok");
      }
    );
  };

  const info = (phone) => {
    const c = db.customers[phone];
    return c ? { name: c.name, region: c.region || "-", phone: c.phone } : { name: phone, region: "-", phone };
  };

  return (
    <>
      <Section title={`الطلبات المعلقة (${pending.length})`}>
        {pending.length === 0 ? <Empty text="لا توجد طلبات معلقة" /> : (
          <div style={{ display: "grid", gap: 12 }}>
            {pending.map((r) => {
              const ci = info(r.customer);
              return (
                <div key={r.id} style={S.depReqCard}>
                  <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", flexWrap: "wrap", gap: 10 }}>
                    <div style={{ flex: 1, minWidth: 200 }}>
                      <div style={{ display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" }}>
                        <span style={{ fontSize: 20, fontWeight: 800, color: "#22e0a1" }}>{fmt(r.amount)} {CURRENCY}</span>
                        <span style={S.statusPending}><Clock size={12} /> قيد المراجعة</span>
                      </div>
                      <div style={{ marginTop: 8, fontSize: 14, fontWeight: 700 }}>{ci.name}</div>
                      <div style={{ marginTop: 4, fontSize: 12, color: "#9fbdb4", display: "flex", gap: 14, flexWrap: "wrap" }}>
                        <span><Phone size={11} style={{ verticalAlign: "-1px" }} /> {ci.phone}</span>
                        <span><MapPin size={11} style={{ verticalAlign: "-1px" }} /> {ci.region}</span>
                        <span>{fmtDate(r.date)}</span>
                      </div>
                      {r.note && <div style={{ fontSize: 13, color: "#cfe6df", marginTop: 10, padding: "8px 12px", background: "rgba(0,0,0,.25)", borderRadius: 8 }}>📝 {r.note}</div>}
                    </div>
                    <div style={{ display: "flex", gap: 8 }}>
                      <button style={S.primaryBtn} onClick={() => approve(r)} className="press"><Check size={15} /> موافقة</button>
                      <button style={S.miniBtnRed} onClick={() => reject(r)}><X size={14} /> رفض</button>
                    </div>
                  </div>
                </div>
              );
            })}
          </div>
        )}
      </Section>

      <Section title="سجل الطلبات المعالجة">
        {history.length === 0 ? <Empty text="لا يوجد سجل" /> : (
          <div style={{ overflowX: "auto" }}>
            <table style={S.table}>
              <thead><tr>{["التاريخ", "الزبون", "المنطقة", "المبلغ", "ملاحظة", "الحالة", "بواسطة", "تاريخ المعالجة"].map((h) => <th key={h} style={S.th}>{h}</th>)}</tr></thead>
              <tbody>
                {history.map((r) => {
                  const ci = info(r.customer);
                  return (
                    <tr key={r.id} style={S.tr}>
                      <td style={{ ...S.td, fontSize: 12 }}>{fmtDate(r.date)}</td>
                      <td style={S.td}>{ci.name}</td>
                      <td style={{ ...S.td, color: "#9fbdb4" }}>{ci.region}</td>
                      <td style={{ ...S.td, color: "#22e0a1", fontWeight: 700 }}>{fmt(r.amount)}</td>
                      <td style={{ ...S.td, fontSize: 12, maxWidth: 220 }}>{r.note || "-"}</td>
                      <td style={S.td}>{r.status === "approved" ? <span style={S.statusOk}><Check size={12} /> موافق</span> : <span style={S.statusBad}><X size={12} /> {r.rejectReason ? `مرفوض: ${r.rejectReason}` : "مرفوض"}</span>}</td>
                      <td style={{ ...S.td, fontSize: 12.5, fontWeight: 600 }}>
                        <span style={S.processedByTag}><UserCheck size={11} /> {r.processedBy || "-"}</span>
                      </td>
                      <td style={{ ...S.td, fontSize: 12 }}>{fmtDate(r.processedAt)}</td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        )}
      </Section>
    </>
  );
}

/* ============================================================
   Admin — Categories
   ============================================================ */
function AdminCats({ db, persist, helpers }) {
  const [showForm, setShowForm] = useState(false);
  const [form, setForm] = useState({ name: "", price: "", speed: "", validity: "" });
  const [expanded, setExpanded] = useState({});

  const addCat = () => {
    if (!form.name.trim() || !form.price) return helpers.showToast("أدخل الاسم والسعر", "err");
    persist((prev) => ({
      ...prev,
      categories: [...prev.categories, { id: uid(), name: form.name.trim(), price: Number(form.price), speed: form.speed.trim() || "-", validity: form.validity.trim() || "-", codes: [] }],
    }));
    setForm({ name: "", price: "", speed: "", validity: "" });
    setShowForm(false);
    helpers.showToast("تمت إضافة الفئة", "ok");
  };

  return (
    <>
      <Section title="إدارة الفئات" right={
        <button style={S.primaryBtn} onClick={() => setShowForm((s) => !s)} className="press">
          {showForm ? <><X size={15} /> إلغاء</> : <><Plus size={15} /> إضافة فئة</>}
        </button>
      }>
        {showForm && (
          <div style={S.collapseBox} className="rise">
            <h4 style={{ margin: "0 0 12px", fontSize: 14, color: "#22e0a1" }}>فئة جديدة</h4>
            <div style={S.formGrid}>
              <Field label="اسم الفئة *"><input style={S.input} value={form.name} onChange={(e) => setForm({ ...form, name: e.target.value })} placeholder="فئة 1 جيجا" /></Field>
              <Field label="السعر *"><input style={S.input} type="number" value={form.price} onChange={(e) => setForm({ ...form, price: e.target.value })} /></Field>
              <Field label="السرعة"><input style={S.input} value={form.speed} onChange={(e) => setForm({ ...form, speed: e.target.value })} placeholder="6 ميجا" /></Field>
              <Field label="مدة الصلاحية"><input style={S.input} value={form.validity} onChange={(e) => setForm({ ...form, validity: e.target.value })} placeholder="3 أيام" /></Field>
            </div>
            <button style={{ ...S.primaryBtn, marginTop: 14 }} onClick={addCat} className="press"><Check size={16} /> حفظ</button>
          </div>
        )}
      </Section>

      {db.categories.length === 0 && <Empty text="لا توجد فئات. أضف فئة جديدة لتبدأ" />}
      {db.categories.map((cat) => (
        <CategoryCard key={cat.id} cat={cat} customers={db.customers} transactions={db.transactions}
          expanded={!!expanded[cat.id]} onToggle={() => setExpanded((e) => ({ ...e, [cat.id]: !e[cat.id] }))}
          persist={persist} helpers={helpers} canDeleteCat />
      ))}
    </>
  );
}

function CategoryCard({ cat, customers, transactions, expanded, onToggle, persist, helpers, canDeleteCat }) {
  const [codeInput, setCodeInput] = useState("");
  const [filter, setFilter] = useState("all");
  const fileRef = useRef(null);
  const avail = cat.codes.filter((x) => !x.used).length;
  const sold = cat.codes.length - avail;

  const addCodes = (raw) => {
    const codes = raw.split(/[\n,\r]+/).map((x) => x.trim()).filter(Boolean)
      .map((code) => ({ code, used: false, soldTo: null, soldAt: null, addedAt: now() }));
    if (codes.length === 0) return;
    persist((prev) => ({ ...prev, categories: prev.categories.map((c) => c.id === cat.id ? { ...c, codes: [...c.codes, ...codes] } : c) }));
    helpers.showToast(`تمت إضافة ${codes.length} كود`, "ok");
  };

  const handleAddText = () => {
    if (!codeInput.trim()) return helpers.showToast("أدخل الأكواد", "err");
    addCodes(codeInput);
    setCodeInput("");
  };

  const handleFile = (e) => {
    const file = e.target.files?.[0];
    if (!file) return;
    const r = new FileReader();
    r.onload = () => addCodes(String(r.result || ""));
    r.readAsText(file);
    e.target.value = "";
  };

  const delCat = () => {
    helpers.askConfirm(
      { title: "حذف الفئة", message: `سيتم حذف فئة "${cat.name}" وكل أكوادها. هذا إجراء نهائي.`, danger: true },
      () => {
        persist((prev) => ({ ...prev, categories: prev.categories.filter((c) => c.id !== cat.id) }));
        helpers.showToast("تم الحذف", "ok");
      }
    );
  };

  const delCode = (code) => {
    helpers.askConfirm(
      { title: "حذف الكود", message: "هل تريد حذف هذا الكود من الفئة؟", danger: true },
      () => {
        persist((prev) => ({ ...prev, categories: prev.categories.map((c) => c.id === cat.id ? { ...c, codes: c.codes.filter((x) => x.code !== code) } : c) }));
      }
    );
  };

  const rows = cat.codes
    .filter((x) => filter === "all" || (filter === "available" ? !x.used : x.used))
    .sort((a, b) => b.addedAt.localeCompare(a.addedAt));

  return (
    <div style={S.section}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", flexWrap: "wrap", gap: 10, cursor: "pointer" }} onClick={onToggle}>
        <div>
          <h3 style={{ margin: 0, fontSize: 16, fontFamily: "Tajawal" }}>{cat.name} <span style={{ color: "#22e0a1" }}>· {fmt(cat.price)} {CURRENCY}</span></h3>
          <div style={{ display: "flex", gap: 14, fontSize: 12.5, color: "#9fbdb4", marginTop: 6, flexWrap: "wrap" }}>
            <span>السرعة: {cat.speed}</span><span>المدة: {cat.validity}</span>
            <span style={{ color: "#22e0a1" }}>متاح: {avail}</span><span style={{ color: "#ff8585" }}>مباع: {sold}</span>
          </div>
        </div>
        <div style={{ display: "flex", gap: 8 }}>
          {canDeleteCat && <button style={S.miniBtnRed} onClick={(e) => { e.stopPropagation(); delCat(); }}><Trash2 size={12} /></button>}
          <button style={S.iconBtn} onClick={(e) => { e.stopPropagation(); onToggle(); }}>{expanded ? <ChevronUp size={18} /> : <ChevronDown size={18} />}</button>
        </div>
      </div>

      {expanded && (
        <div style={{ marginTop: 18 }}>
          <div style={{ background: "rgba(0,0,0,.2)", padding: 14, borderRadius: 12, marginBottom: 16 }}>
            <h4 style={{ margin: "0 0 10px", fontSize: 13, color: "#22e0a1" }}>إضافة أكواد</h4>
            <textarea style={{ ...S.input, minHeight: 60, fontFamily: "monospace", margin: 0 }}
              placeholder="ألصق الأكواد (كل كود في سطر، أو مفصولة بفاصلة)" value={codeInput} onChange={(e) => setCodeInput(e.target.value)} />
            <div style={{ display: "flex", gap: 8, marginTop: 10, flexWrap: "wrap" }}>
              <button style={S.primaryBtn} onClick={handleAddText} className="press"><Plus size={15} /> إضافة من النص</button>
              <button style={S.miniBtnBlue} onClick={() => fileRef.current?.click()}><Upload size={14} /> رفع ملف</button>
              <input ref={fileRef} type="file" accept=".txt,.csv,text/plain" onChange={handleFile} style={{ display: "none" }} />
            </div>
          </div>

          <div style={{ display: "flex", gap: 8, marginBottom: 12, flexWrap: "wrap" }}>
            <FilterChip active={filter === "all"} onClick={() => setFilter("all")}>الكل ({cat.codes.length})</FilterChip>
            <FilterChip active={filter === "available"} onClick={() => setFilter("available")} tone="green">المتاحة ({avail})</FilterChip>
            <FilterChip active={filter === "sold"} onClick={() => setFilter("sold")} tone="red">المباعة ({sold})</FilterChip>
          </div>

          <div style={{ overflowX: "auto" }}>
            <table style={S.table}>
              <thead>
                <tr>
                  <th style={S.th}>رقم الكرت</th>
                  <th style={S.th}>الحالة</th>
                  {filter !== "available" && <><th style={S.th}>الزبون</th><th style={S.th}>تاريخ البيع</th></>}
                  <th style={S.th}>تاريخ الإضافة</th>
                  <th style={S.th}></th>
                </tr>
              </thead>
              <tbody>
                {rows.length === 0 && <tr><td colSpan={6} style={S.tdEmpty}>لا توجد كروت بهذا الفلتر</td></tr>}
                {rows.map((x) => (
                  <tr key={x.code} style={S.tr}>
                    <td style={{ ...S.td, fontFamily: "monospace", fontWeight: 700 }}>{x.code}</td>
                    <td style={S.td}>{x.used ? <span style={S.tagSold}>مباع</span> : <span style={S.tagFree}>متاح</span>}</td>
                    {filter !== "available" && <>
                      <td style={S.td}>{x.used ? (customers[x.soldTo]?.name || x.soldTo || "-") : "-"}</td>
                      <td style={{ ...S.td, fontSize: 12, color: "#9fbdb4" }}>{x.soldAt ? fmtDate(x.soldAt) : "-"}</td>
                    </>}
                    <td style={{ ...S.td, fontSize: 12, color: "#9fbdb4" }}>{fmtDay(x.addedAt)}</td>
                    <td style={S.td}>{!x.used && <button style={S.miniBtnRed} onClick={() => delCode(x.code)}><Trash2 size={12} /></button>}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
      )}
    </div>
  );
}

/* ============================================================
   Admin/Agent — Transactions
   ============================================================ */
function AdminTx({ db, helpers, allowedRegions }) {
  const [sort, setSort] = useState("date_desc");
  const nameOf = (phone) => db.customers[phone]?.name || phone;
  const regionOf = (phone) => db.customers[phone]?.region || "-";

  let rows = [...db.transactions];
  if (allowedRegions) {
    rows = rows.filter((t) => allowedRegions.includes(db.customers[t.customer]?.region || ""));
  }

  const sorters = {
    date_desc: (a, b) => b.date.localeCompare(a.date),
    date_asc: (a, b) => a.date.localeCompare(b.date),
    amount_desc: (a, b) => Math.abs(b.amount) - Math.abs(a.amount),
    amount_asc: (a, b) => Math.abs(a.amount) - Math.abs(b.amount),
    region: (a, b) => regionOf(a.customer).localeCompare(regionOf(b.customer), "ar"),
    category: (a, b) => (a.category || "").localeCompare(b.category || "", "ar"),
  };
  rows = rows.sort(sorters[sort]);

  const exportCsv = () => {
    const head = ["التاريخ", "الزبون", "المنطقة", "النوع", "المبلغ", "الفئة", "رقم الكرت", "تاريخ إضافة الكرت", "الرصيد بعد", "الدين بعد"];
    const lines = rows.map((t) => [
      fmtDate(t.date), nameOf(t.customer), regionOf(t.customer), t.type, t.amount,
      t.category || "-", t.code || "-", t.cardAddedAt ? fmtDay(t.cardAddedAt) : "-",
      t.balanceAfter, t.debtAfter,
    ].map((v) => `"${String(v).replace(/"/g, '""')}"`).join(","));
    const csv = "\uFEFF" + [head.join(","), ...lines].join("\n");
    const blob = new Blob([csv], { type: "text/csv;charset=utf-8;" });
    const a = document.createElement("a");
    a.href = URL.createObjectURL(blob); a.download = `transactions_${Date.now()}.csv`; a.click();
  };

  return (
    <Section
      title={`كل المعاملات (${rows.length})`}
      right={
        <div style={{ display: "flex", gap: 8, flexWrap: "wrap", alignItems: "center" }}>
          <div style={{ position: "relative" }}>
            <ChevronsUpDown size={14} style={{ position: "absolute", right: 10, top: 12, color: "#6b8a82", pointerEvents: "none" }} />
            <select style={{ ...S.input, paddingRight: 32, width: 200, margin: 0, appearance: "none" }} value={sort} onChange={(e) => setSort(e.target.value)}>
              <option value="date_desc">التاريخ (الأحدث)</option>
              <option value="date_asc">التاريخ (الأقدم)</option>
              <option value="amount_desc">المبلغ (الأكبر)</option>
              <option value="amount_asc">المبلغ (الأصغر)</option>
              <option value="region">المنطقة (أبجدي)</option>
              <option value="category">الفئة (أبجدي)</option>
            </select>
          </div>
          <button style={S.primaryBtn} onClick={exportCsv} className="press"><Download size={15} /> تصدير CSV</button>
        </div>
      }
    >
      {rows.length === 0 ? <Empty text="لا توجد معاملات" /> : (
        <div style={{ overflowX: "auto" }}>
          <table style={S.table}>
            <thead>
              <tr>
                <th style={S.th}>التاريخ</th><th style={S.th}>الزبون</th><th style={S.th}>المنطقة</th>
                <th style={S.th}>النوع</th><th style={S.th}>المبلغ</th>
                <th style={S.th}>الفئة</th><th style={S.th}>رقم الكرت</th>
                <th style={S.th}>تاريخ إضافة الكرت</th>
                <th style={S.th}>الرصيد بعد</th><th style={S.th}>الدين بعد</th>
              </tr>
            </thead>
            <tbody>
              {rows.map((t) => (
                <tr key={t.id} style={S.tr}>
                  <td style={{ ...S.td, fontSize: 12 }}>{fmtDate(t.date)}</td>
                  <td style={S.td}>{nameOf(t.customer)}</td>
                  <td style={{ ...S.td, color: "#9fbdb4" }}>{regionOf(t.customer)}</td>
                  <td style={S.td}><TypeTag type={t.type} /></td>
                  <td style={{ ...S.td, color: t.amount >= 0 ? "#22e0a1" : "#ff6b6b", fontWeight: 700 }}>{t.amount >= 0 ? "+" : ""}{fmt(t.amount)}</td>
                  <td style={S.td}>{t.category || "-"}</td>
                  <td style={{ ...S.td, fontFamily: "monospace", fontSize: 12 }}>{t.code || "-"}</td>
                  <td style={{ ...S.td, fontSize: 12, color: "#9fbdb4" }}>{t.cardAddedAt ? fmtDay(t.cardAddedAt) : "-"}</td>
                  <td style={S.td}>{fmt(t.balanceAfter)}</td>
                  <td style={{ ...S.td, color: t.debtAfter > 0 ? "#ff6b6b" : "#6b8a82" }}>{fmt(t.debtAfter)}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}
    </Section>
  );
}

/* ============================================================
   Admin — Agents
   ============================================================ */
function AdminAgents({ db, persist, helpers }) {
  const [showForm, setShowForm] = useState(false);
  const [form, setForm] = useState({ phone: "", name: "", regions: [] });
  const allRegions = [...new Set(Object.values(db.customers).map((c) => c.region).filter(Boolean))];

  const addAgent = async () => {
    const phone = form.phone.trim();
    if (!phone || !form.name.trim()) return helpers.showToast("أدخل رقم الهاتف والاسم", "err");
    if (db.agents[phone]) return helpers.showToast("رقم الوكيل مسجل مسبقاً", "err");
    if (form.regions.length === 0) return helpers.showToast("اختر منطقة واحدة على الأقل", "err");
    const pass = randomPass();
    const next = {
      ...db,
      agents: { ...db.agents, [phone]: { phone, name: form.name.trim(), regions: form.regions, createdAt: now() } },
    };
    persist(next);
    await saveDB(next);
    await api("set-password", { role: "agent", phone, newPassword: pass });
    setForm({ phone: "", name: "", regions: [] });
    setShowForm(false);
    helpers.setModal({ title: "تم إنشاء حساب الوكيل", body: <CredentialsCard phone={phone} pass={pass} showToast={helpers.showToast} /> });
  };

  const regenPass = (phone) => {
    helpers.askConfirm(
      { title: "توليد كلمة مرور جديدة", message: "ستُستبدل كلمة المرور الحالية للوكيل." },
      async () => {
        const np = randomPass();
        const r = await api("set-password", { role: "agent", phone, newPassword: np });
        if (r && r.ok) helpers.setModal({ title: "كلمة مرور الوكيل الجديدة", body: <CredentialsCard phone={phone} pass={np} showToast={helpers.showToast} /> });
        else helpers.showToast("تعذّر تغيير كلمة المرور", "err");
      }
    );
  };

  const editRegions = (phone) => {
    const a = db.agents[phone];
    helpers.setModal({
      title: `تعديل مناطق الوكيل: ${a.name}`,
      body: <RegionsPicker allRegions={allRegions} selected={a.regions} onSave={(regions) => {
        persist((prev) => ({ ...prev, agents: { ...prev.agents, [phone]: { ...prev.agents[phone], regions } } }));
        helpers.showToast("تم تحديث المناطق", "ok");
        helpers.setModal(null);
      }} />,
    });
  };

  const delAgent = (phone) => {
    helpers.askConfirm(
      { title: "حذف الوكيل", message: `سيتم حذف حساب الوكيل ${db.agents[phone]?.name}.`, danger: true },
      () => {
        persist((prev) => {
          const ag = { ...prev.agents };
          delete ag[phone];
          return { ...prev, agents: ag };
        });
        helpers.showToast("تم الحذف", "ok");
      }
    );
  };

  const agents = Object.values(db.agents).sort((a, b) => b.createdAt.localeCompare(a.createdAt));

  return (
    <>
      <Section title="إدارة الوكلاء" right={
        <button style={S.primaryBtn} onClick={() => setShowForm((s) => !s)} className="press">
          {showForm ? <><X size={15} /> إلغاء</> : <><Plus size={15} /> إضافة وكيل</>}
        </button>
      }>
        {showForm && (
          <div style={S.collapseBox} className="rise">
            <h4 style={{ margin: "0 0 12px", fontSize: 14, color: "#22e0a1" }}>وكيل جديد</h4>
            <div style={S.formGrid}>
              <Field label="رقم الهاتف *"><input style={S.input} value={form.phone} onChange={(e) => setForm({ ...form, phone: e.target.value })} placeholder="7XXXXXXXX" /></Field>
              <Field label="الاسم الكامل *"><input style={S.input} value={form.name} onChange={(e) => setForm({ ...form, name: e.target.value })} placeholder="اسم الوكيل" /></Field>
            </div>
            <div style={{ marginTop: 14 }}>
              <Field label="المناطق التابعة للوكيل *">
                <RegionsPicker allRegions={allRegions} selected={form.regions} onChange={(regions) => setForm({ ...form, regions })} inline />
              </Field>
            </div>
            <button style={{ ...S.primaryBtn, marginTop: 14 }} onClick={addAgent} className="press"><Check size={16} /> حفظ وإنشاء كلمة مرور</button>
          </div>
        )}
        <p style={{ color: "#9fbdb4", fontSize: 12.5, margin: 0, marginTop: showForm ? 14 : 0 }}>
          الوكيل يستطيع: مراجعة طلبات إيداع الزبائن في مناطقه، إدارة الفئات والكروت، تأكيد تفعيل الكروت، ومتابعة معاملات منطقته.
        </p>
      </Section>

      <Section title={`قائمة الوكلاء (${agents.length})`}>
        {agents.length === 0 ? <Empty text="لا يوجد وكلاء" /> : (
          <div style={{ overflowX: "auto" }}>
            <table style={S.table}>
              <thead><tr>{["الهاتف", "الاسم", "المناطق", "تاريخ الإضافة", "إجراءات"].map((h) => <th key={h} style={S.th}>{h}</th>)}</tr></thead>
              <tbody>
                {agents.map((a) => (
                  <tr key={a.phone} style={S.tr}>
                    <td style={{ ...S.td, fontFamily: "monospace" }}>{a.phone}</td>
                    <td style={S.td}>{a.name}</td>
                    <td style={S.td}>
                      <div style={{ display: "flex", gap: 5, flexWrap: "wrap" }}>
                        {a.regions.length === 0 ? <span style={{ color: "#6b8a82" }}>لا توجد</span> :
                          a.regions.map((r) => <span key={r} style={S.regionChip}>{r}</span>)}
                      </div>
                    </td>
                    <td style={{ ...S.td, fontSize: 12, color: "#9fbdb4" }}>{fmtDay(a.createdAt)}</td>
                    <td style={S.td}>
                      <div style={{ display: "flex", gap: 6, flexWrap: "wrap" }}>
                        <button style={S.miniBtnBlue} onClick={() => editRegions(a.phone)}><Edit2 size={12} /> المناطق</button>
                        <button style={S.miniBtnGray} onClick={() => regenPass(a.phone)} title="كلمة مرور جديدة"><RefreshCw size={12} /></button>
                        <button style={S.miniBtnRed} onClick={() => delAgent(a.phone)}><Trash2 size={12} /></button>
                      </div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}
      </Section>
    </>
  );
}

function RegionsPicker({ allRegions, selected, onChange, onSave, inline }) {
  const [list, setList] = useState(selected || []);
  const [newRegion, setNewRegion] = useState("");

  const toggle = (r) => {
    const next = list.includes(r) ? list.filter((x) => x !== r) : [...list, r];
    setList(next);
    if (inline && onChange) onChange(next);
  };
  const addCustom = () => {
    const r = newRegion.trim();
    if (!r || list.includes(r)) return;
    const next = [...list, r];
    setList(next);
    setNewRegion("");
    if (inline && onChange) onChange(next);
  };

  return (
    <div>
      <div style={{ display: "flex", gap: 6, flexWrap: "wrap", marginBottom: 10 }}>
        {allRegions.map((r) => (
          <button key={r} onClick={() => toggle(r)} style={{ ...S.regionChip, ...(list.includes(r) ? S.regionChipActive : {}), border: "1px solid transparent", cursor: "pointer" }}>
            {list.includes(r) && <Check size={11} />} {r}
          </button>
        ))}
        {list.filter((r) => !allRegions.includes(r)).map((r) => (
          <button key={r} onClick={() => toggle(r)} style={{ ...S.regionChipActive, border: "1px solid transparent", cursor: "pointer" }}>
            <Check size={11} /> {r}
          </button>
        ))}
      </div>
      <div style={{ display: "flex", gap: 8 }}>
        <input style={{ ...S.input, margin: 0, flex: 1 }} value={newRegion} onChange={(e) => setNewRegion(e.target.value)} placeholder="إضافة منطقة يدوياً…" onKeyDown={(e) => e.key === "Enter" && (e.preventDefault(), addCustom())} />
        <button style={S.miniBtn} onClick={addCustom}><Plus size={13} /> أضف</button>
      </div>
      {!inline && (
        <button style={{ ...S.primaryBtn, marginTop: 14, width: "100%" }} onClick={() => onSave(list)} className="press"><Check size={15} /> حفظ</button>
      )}
    </div>
  );
}

/* ============================================================
   Admin — Settings
   ============================================================ */
function AdminSettings({ db, persist, helpers }) {
  const [np, setNp] = useState("");
  const [dl, setDl] = useState(String(db.defaultDebtLimit));
  const [tgToken, setTgToken] = useState(db.telegramBotToken);
  const [tgChat, setTgChat] = useState(db.telegramChatId);
  const [busyBackup, setBusyBackup] = useState(false);

  useEffect(() => { setDl(String(db.defaultDebtLimit)); }, [db.defaultDebtLimit]);

  const changePass = async () => {
    if (!np || np.length < 4) return helpers.showToast("كلمة المرور قصيرة جداً", "err");
    const r = await api("set-admin-password", { newPassword: np });
    if (r && r.ok) { setNp(""); helpers.showToast("تم تغيير كلمة مرور الأدمن", "ok"); }
    else helpers.showToast("تعذّر تغيير كلمة المرور", "err");
  };
  const saveDl = () => {
    const v = Number(dl);
    if (isNaN(v) || v < 0) return helpers.showToast("قيمة غير صحيحة", "err");
    persist((prev) => ({ ...prev, defaultDebtLimit: v }));
    helpers.showToast("تم الحفظ", "ok");
  };
  const saveTg = () => {
    persist((prev) => ({ ...prev, telegramBotToken: tgToken.trim(), telegramChatId: tgChat.trim() }));
    helpers.showToast("تم حفظ إعدادات تيليجرام", "ok");
  };
  const testTg = async () => {
    if (!tgToken.trim() || !tgChat.trim()) return helpers.showToast("أدخل التوكن والمعرّف أولاً", "err");
    helpers.showToast("جارٍ إرسال رسالة تجريبية…", "ok");
    const r = await notifyTelegram(tgToken.trim(), tgChat.trim(), "✅ <b>اختبار</b>\nالتكامل مع تيليجرام يعمل بنجاح من منصة NETCARD.");
    if (r.ok) helpers.showToast("تم الإرسال — تحقق من تيليجرام", "ok");
    else helpers.showToast(`فشل الإرسال: ${r.reason}`, "err");
  };

  const backupNow = async () => {
    if (!db.telegramBotToken || !db.telegramChatId) return helpers.showToast("أعدّ تيليجرام أولاً وحدّد التوكن ومعرّف الدردشة", "err");
    setBusyBackup(true);
    const stamp = new Date().toISOString().slice(0, 19).replace("T", "_").replace(/:/g, "-");
    const payload = JSON.stringify(db, null, 2);
    const r = await sendTelegramFile(
      db.telegramBotToken, db.telegramChatId,
      `netcard_backup_${stamp}.json`, payload,
      `📦 نسخة احتياطية يدوية\n📅 ${new Date().toLocaleString("ar-YE")}\n📊 ${Object.keys(db.customers).length} زبون · ${db.transactions.length} معاملة · ${(payload.length / 1024).toFixed(1)} ك.ب`
    );
    setBusyBackup(false);
    if (r.ok) {
      persist((prev) => ({ ...prev, lastBackupAt: Date.now() }));
      helpers.showToast("تم رفع النسخة الاحتياطية لتيليجرام", "ok");
    } else {
      helpers.showToast(`فشل الرفع: ${r.reason}`, "err");
    }
  };

  const exportAll = () => {
    const blob = new Blob([JSON.stringify(db, null, 2)], { type: "application/json" });
    const a = document.createElement("a");
    a.href = URL.createObjectURL(blob); a.download = `backup_${Date.now()}.json`; a.click();
  };

  const lastBackupText = db.lastBackupAt
    ? `آخر نسخة لتيليجرام: ${new Date(db.lastBackupAt).toLocaleString("ar-YE")}`
    : "لم تُرفع أي نسخة لتيليجرام بعد";

  return (
    <>
      <Section title="حد المديونية الافتراضي للزبائن الجدد">
        <div style={{ display: "flex", gap: 10, alignItems: "center", flexWrap: "wrap" }}>
          <input style={{ ...S.input, margin: 0, maxWidth: 200 }} type="number" value={dl} onChange={(e) => setDl(e.target.value)} />
          <span style={{ color: "#9fbdb4", fontSize: 13 }}>{CURRENCY}</span>
          <button style={S.primaryBtn} onClick={saveDl} className="press"><Check size={15} /> حفظ</button>
        </div>
      </Section>

      <Section title={<><Send size={15} style={{ verticalAlign: "-2px", marginLeft: 6, color: "#4cb6ff" }} /> إشعارات تيليجرام لطلبات الإيداع</>}>
        <p style={{ color: "#9fbdb4", fontSize: 13, margin: "0 0 14px" }}>
          أنشئ بوت من <b style={{ color: "#cfe6df" }}>@BotFather</b> للحصول على التوكن، ثم احصل على معرّف الدردشة من <b style={{ color: "#cfe6df" }}>@userinfobot</b> أو من <b style={{ color: "#cfe6df" }}>@getidsbot</b>.
        </p>
        <div style={S.formGrid}>
          <Field label="Bot Token"><input style={{ ...S.input, fontFamily: "monospace", fontSize: 13 }} value={tgToken} onChange={(e) => setTgToken(e.target.value)} placeholder="123456:ABC-DEF1234..." /></Field>
          <Field label="Chat ID"><input style={{ ...S.input, fontFamily: "monospace", fontSize: 13 }} value={tgChat} onChange={(e) => setTgChat(e.target.value)} placeholder="123456789" /></Field>
        </div>
        <div style={{ display: "flex", gap: 10, marginTop: 14, flexWrap: "wrap" }}>
          <button style={S.primaryBtn} onClick={saveTg} className="press"><Check size={15} /> حفظ الإعدادات</button>
          <button style={S.miniBtnBlue} onClick={testTg}><Send size={13} /> إرسال رسالة تجريبية</button>
        </div>
        <div style={{ marginTop: 14, padding: "10px 12px", background: "rgba(255,170,80,.08)", border: "1px solid rgba(255,170,80,.2)", borderRadius: 8 }}>
          <p style={{ margin: 0, fontSize: 12.5, color: "#ffc488" }}>
            <AlertCircle size={13} style={{ verticalAlign: "-2px", marginLeft: 4 }} />
            <b> ملاحظة:</b> بيئة المعاينة في Claude (هذه الواجهة الحالية) تمنع الاتصالات الخارجية لأسباب أمنية، لذلك زر التجربة يُظهر "Failed to fetch". عند نشر الكود على استضافتك الخاصة، سيعمل بشكل طبيعي.
          </p>
        </div>
      </Section>

      <Section title={<><Download size={15} style={{ verticalAlign: "-2px", marginLeft: 6, color: "#22e0a1" }} /> النسخ الاحتياطي إلى تيليجرام</>}>
        <p style={{ color: "#9fbdb4", fontSize: 13, margin: "0 0 14px", lineHeight: 1.7 }}>
          المنصة ترفع نسخة احتياطية كاملة (ملف JSON) تلقائياً إلى محادثة البوت <b style={{ color: "#cfe6df" }}>مرة كل 24 ساعة</b> بمجرد دخولك كأدمن.
          لو حصل أي تخريب أو فقد للبيانات يبقى عندك سجل في تيليجرام تستطيع استعادته منه.
        </p>
        <div style={{ padding: "10px 12px", background: "rgba(34,224,161,.06)", border: "1px solid rgba(34,224,161,.18)", borderRadius: 8, marginBottom: 14 }}>
          <p style={{ margin: 0, fontSize: 13, color: "#cfe6df" }}>
            <Clock size={13} style={{ verticalAlign: "-2px", marginLeft: 4, color: "#22e0a1" }} />
            {lastBackupText}
          </p>
        </div>
        <button style={S.primaryBtn} onClick={backupNow} disabled={busyBackup} className="press">
          {busyBackup ? <><RefreshCw size={15} className="pulse" /> جارٍ الرفع…</> : <><Send size={15} /> رفع نسخة احتياطية الآن</>}
        </button>
      </Section>

      <Section title="تغيير كلمة مرور الأدمن">
        <div style={{ display: "flex", gap: 10, alignItems: "center", flexWrap: "wrap" }}>
          <input style={{ ...S.input, margin: 0, maxWidth: 240 }} type="password" placeholder="كلمة مرور جديدة" value={np} onChange={(e) => setNp(e.target.value)} />
          <button style={S.primaryBtn} onClick={changePass} className="press">حفظ</button>
        </div>
      </Section>

      <Section title="تنزيل نسخة احتياطية على الجهاز">
        <p style={{ color: "#9fbdb4", fontSize: 13.5, marginBottom: 14 }}>تنزيل كل البيانات كملف JSON على جهازك مباشرةً.</p>
        <button style={S.miniBtnBlue} onClick={exportAll} className="press"><Download size={15} /> تنزيل</button>
      </Section>
    </>
  );
}

/* ============================================================
   Agent Panel
   ============================================================ */
function AgentPanel({ db, persist, agentPhone, onLogout, helpers }) {
  const agent = db.agents[agentPhone];
  const [view, setView] = useState("deposits");
  if (!agent) return <Empty text="حساب الوكيل غير موجود" />;

  const myRegions = agent.regions || [];
  const myCustomers = Object.values(db.customers).filter((c) => myRegions.includes(c.region));
  const pendingForMe = db.depositRequests.filter((r) => {
    const reg = db.customers[r.customer]?.region;
    return reg && myRegions.includes(reg) && r.status === "pending";
  }).length;

  return (
    <div style={{ maxWidth: 1280, margin: "0 auto", padding: "22px 18px 60px" }}>
      <TopBar
        title={`الوكيل: ${agent.name}`}
        sub={`📞 ${agent.phone} · المناطق: ${myRegions.join("، ") || "—"}`}
        onLogout={onLogout}
        admin
        nav={[
          { id: "deposits", label: "طلبات الإيداعات", icon: <ArrowUpRight size={16} />, badge: pendingForMe },
          { id: "customers", label: "زبائن المديونية", icon: <Users size={16} /> },
        ]}
        view={view} setView={setView}
      />
      {view === "deposits" && <DepositsView db={db} persist={persist} helpers={helpers} allowedRegions={myRegions} processorName={agent.name} />}
      {view === "customers" && <AgentCustomersView customers={myCustomers.filter((c) => c.debt > 0)} />}
    </div>
  );
}

function AgentCustomersView({ customers }) {
  if (customers.length === 0) return <Empty text="لا يوجد زبائن عليهم مديونية في مناطقك حالياً" />;
  return (
    <Section title={`الزبائن المديونون (${customers.length})`}>
      <p style={{ color: "#9fbdb4", fontSize: 12.5, margin: "0 0 14px" }}>عرض الزبائن الذين عليهم مديونية في مناطقك للمتابعة.</p>
      <div style={{ overflowX: "auto" }}>
        <table style={S.table}>
          <thead><tr>{["الهاتف", "الاسم", "المنطقة", "الرصيد", "المديونية", "حد المديونية", "الحالة"].map((h) => <th key={h} style={S.th}>{h}</th>)}</tr></thead>
          <tbody>
            {customers.sort((a, b) => b.debt - a.debt).map((c) => (
              <tr key={c.phone} style={{ ...S.tr, opacity: c.banned ? 0.55 : 1 }}>
                <td style={{ ...S.td, fontFamily: "monospace" }}>{c.phone}</td>
                <td style={S.td}>{c.name}</td>
                <td style={{ ...S.td, color: "#9fbdb4" }}>{c.region}</td>
                <td style={{ ...S.td, color: "#22e0a1" }}>{fmt(c.balance)}</td>
                <td style={{ ...S.td, color: "#ff6b6b", fontWeight: 700 }}>{fmt(c.debt)}</td>
                <td style={S.td}>{fmt(c.debtLimit)}</td>
                <td style={S.td}>{c.banned ? <span style={S.tagBanned}><Ban size={12} /> محظور</span> : <span style={S.tagOk}>نشط</span>}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </Section>
  );
}

/* ============================================================
   Shared components
   ============================================================ */
function TopBar({ title, sub, onLogout, nav, view, setView, admin }) {
  return (
    <div style={{ marginBottom: 24 }}>
      <div style={S.topRow}>
        <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
          <div style={{ ...S.logoBadge, width: 44, height: 44 }}>{admin ? <Shield size={22} /> : <Wifi size={22} />}</div>
          <div>
            <h2 style={{ margin: 0, fontFamily: "Tajawal", fontSize: 20 }}>{title}</h2>
            <p style={{ margin: 0, color: "#6b8a82", fontSize: 13 }}>{sub}</p>
          </div>
        </div>
        <button style={S.logoutBtn} onClick={onLogout} className="press"><LogOut size={16} /> خروج</button>
      </div>
      <div style={S.navRow}>
        {nav.map((n) => (
          <button key={n.id} onClick={() => setView(n.id)} style={{ ...S.navBtn, ...(view === n.id ? S.navActive : {}) }}>
            {n.icon} {n.label}
            {n.badge > 0 && <span style={S.navBadge}>{n.badge}</span>}
          </button>
        ))}
      </div>
    </div>
  );
}

function StatCard({ icon, label, value, tone, action }) {
  const tones = { green: ["#0e2e26", "#22e0a1"], red: ["#33161a", "#ff6b6b"], blue: ["#10283a", "#4cb6ff"], purple: ["#241a36", "#b08cff"] };
  const [bg, fg] = tones[tone] || tones.green;
  return (
    <div style={S.stat} className="lift">
      <div style={{ ...S.statIcon, background: bg, color: fg }}>{icon}</div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <p style={{ margin: 0, color: "#9fbdb4", fontSize: 13 }}>{label}</p>
        <p style={{ margin: "2px 0 0", fontSize: 19, fontWeight: 700, fontFamily: "Tajawal" }}>{value}</p>
      </div>
      {action}
    </div>
  );
}

function Section({ title, children, right }) {
  return (
    <div style={S.section}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 16, gap: 10, flexWrap: "wrap" }}>
        <h3 style={{ margin: 0, fontSize: 16, fontFamily: "Tajawal" }}>{title}</h3>
        {right}
      </div>
      {children}
    </div>
  );
}

function TypeTag({ type }) {
  if (type === "إيداع") return <span style={S.tagGreen}>إيداع</span>;
  if (type === "شراء") return <span style={S.tagBlue}>شراء</span>;
  if (type === "مديونية") return <span style={S.tagOrange}>مديونية</span>;
  return <span style={S.tagGray}>{type}</span>;
}

function ActivationTag({ activated }) {
  if (activated) return <span style={S.tagGreen}><Zap size={11} style={{ verticalAlign: "-1px" }} /> مفعّل</span>;
  return <span style={S.tagGray}><Clock size={11} style={{ verticalAlign: "-1px" }} /> بانتظار التفعيل</span>;
}

function Field({ label, children }) {
  return (
    <div>
      <label style={{ display: "block", marginBottom: 6, fontSize: 13, color: "#9fbdb4" }}>{label}</label>
      {children}
    </div>
  );
}

function Empty({ text }) {
  return (
    <div style={{ textAlign: "center", padding: 36, color: "#6b8a82" }}>
      <AlertCircle size={28} style={{ marginBottom: 8, opacity: 0.6 }} />
      <p style={{ margin: 0, fontSize: 14 }}>{text}</p>
    </div>
  );
}

function FilterChip({ active, onClick, children, tone }) {
  const styles = { ...S.filterChip };
  if (active) {
    if (tone === "green") Object.assign(styles, S.filterChipGreen);
    else if (tone === "red") Object.assign(styles, S.filterChipRed);
    else Object.assign(styles, S.filterChipActive);
  }
  return <button style={styles} onClick={onClick} className="press">{children}</button>;
}

function Toast({ toast }) {
  if (!toast) return null;
  const ok = toast.kind === "ok";
  return (
    <div style={{ ...S.toast, borderColor: ok ? "#22e0a1" : "#ff6b6b" }} className="toastIn">
      {ok ? <CheckCircle size={18} color="#22e0a1" /> : <AlertCircle size={18} color="#ff6b6b" />}
      <span>{toast.msg}</span>
    </div>
  );
}

function Modal({ modal, onClose }) {
  if (!modal) return null;
  return (
    <div style={S.modalBg} onClick={onClose}>
      <div style={S.modal} onClick={(e) => e.stopPropagation()} className="rise">
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 16 }}>
          <h3 style={{ margin: 0, fontFamily: "Tajawal", fontSize: 17 }}>{modal.title}</h3>
          <button style={S.iconBtn} onClick={onClose}><X size={18} /></button>
        </div>
        {modal.body}
      </div>
    </div>
  );
}

function Dialog({ dialog, onClose }) {
  const [val, setVal] = useState("");
  useEffect(() => { if (dialog?.kind === "prompt") setVal(dialog.defaultValue || ""); }, [dialog]);
  if (!dialog) return null;

  const onSubmit = (e) => {
    if (e) e.preventDefault();
    if (dialog.kind === "prompt") dialog.onSubmit(val);
  };

  return (
    <div style={S.modalBg} onClick={onClose}>
      <div style={{ ...S.modal, maxWidth: 420 }} onClick={(e) => e.stopPropagation()} className="rise">
        <h3 style={{ margin: "0 0 10px", fontFamily: "Tajawal", fontSize: 17, color: dialog.danger ? "#ff8585" : "#e8f5f0" }}>{dialog.title}</h3>
        <p style={{ margin: "0 0 18px", fontSize: 14, color: "#9fbdb4", lineHeight: 1.6 }}>{dialog.message || dialog.label}</p>
        {dialog.kind === "prompt" && (
          <form onSubmit={onSubmit}>
            <input
              autoFocus type={dialog.inputType || "text"} style={{ ...S.input, marginBottom: 18 }}
              placeholder={dialog.placeholder} value={val} onChange={(e) => setVal(e.target.value)}
            />
          </form>
        )}
        <div style={{ display: "flex", gap: 10, justifyContent: "flex-end" }}>
          <button style={S.miniBtnGray} onClick={onClose}>إلغاء</button>
          {dialog.kind === "confirm"
            ? <button style={dialog.danger ? { ...S.primaryBtn, background: "linear-gradient(135deg,#ff6b6b,#cc4040)", color: "#fff" } : S.primaryBtn} onClick={dialog.onYes} className="press">{dialog.danger ? "تأكيد الحذف" : "موافق"}</button>
            : <button style={S.primaryBtn} onClick={onSubmit} className="press">حفظ</button>}
        </div>
      </div>
    </div>
  );
}

/* ============================================================
   Styles
   ============================================================ */
const S = {
  root: { minHeight: "100vh", background: "#06120f", color: "#e8f5f0", fontFamily: "Tajawal, system-ui, sans-serif", position: "relative", overflow: "hidden" },
  bgGrid: { position: "fixed", inset: 0, backgroundImage: "linear-gradient(rgba(34,224,161,.04) 1px,transparent 1px),linear-gradient(90deg,rgba(34,224,161,.04) 1px,transparent 1px)", backgroundSize: "44px 44px", zIndex: 1 },
  bgGlow: { position: "fixed", top: "-20%", right: "-10%", width: 600, height: 600, background: "radial-gradient(circle,rgba(34,224,161,.12),transparent 70%)", zIndex: 1, pointerEvents: "none" },

  loginCard: { width: "100%", maxWidth: 380, background: "rgba(11,28,23,.85)", backdropFilter: "blur(14px)", border: "1px solid rgba(34,224,161,.18)", borderRadius: 22, padding: 32, boxShadow: "0 24px 70px rgba(0,0,0,.5)" },
  logoBadge: { width: 60, height: 60, borderRadius: 16, background: "linear-gradient(135deg,#22e0a1,#0e9b6f)", display: "grid", placeItems: "center", margin: "0 auto", color: "#06120f", boxShadow: "0 8px 24px rgba(34,224,161,.35)" },
  brand: { margin: "16px 0 2px", fontSize: 30, fontFamily: "Tajawal", fontWeight: 800, letterSpacing: 1 },
  brandSub: { margin: 0, color: "#6b8a82", fontSize: 13 },

  tabRow: { display: "flex", gap: 6, marginBottom: 22, background: "rgba(0,0,0,.25)", padding: 5, borderRadius: 12 },
  tabBtn: { flex: 1, display: "flex", alignItems: "center", justifyContent: "center", gap: 5, padding: "10px 6px", border: "none", borderRadius: 9, background: "transparent", color: "#9fbdb4", cursor: "pointer", fontFamily: "Tajawal", fontSize: 13, transition: ".2s" },
  tabActive: { background: "linear-gradient(135deg,#22e0a1,#0e9b6f)", color: "#06120f", fontWeight: 700 },

  input: { width: "100%", boxSizing: "border-box", padding: "11px 13px", borderRadius: 10, border: "1px solid rgba(34,224,161,.2)", background: "rgba(0,0,0,.3)", color: "#e8f5f0", fontFamily: "Tajawal", fontSize: 14, outline: "none" },
  eyeBtn: { position: "absolute", left: 10, top: 9, background: "none", border: "none", color: "#6b8a82", cursor: "pointer" },
  primaryBtn: { display: "inline-flex", alignItems: "center", justifyContent: "center", gap: 7, padding: "11px 18px", borderRadius: 10, border: "none", background: "linear-gradient(135deg,#22e0a1,#0e9b6f)", color: "#06120f", fontWeight: 700, fontFamily: "Tajawal", fontSize: 14, cursor: "pointer", whiteSpace: "nowrap" },
  hint: { textAlign: "center", color: "#6b8a82", fontSize: 12, marginTop: 14, marginBottom: 0 },
  lockBox: { display: "flex", alignItems: "center", gap: 8, padding: "11px 14px", borderRadius: 10, background: "rgba(255,107,107,.1)", border: "1px solid rgba(255,107,107,.25)", color: "#ff8585", fontSize: 13, marginBottom: 14, lineHeight: 1.6 },
  iconBtn: { background: "rgba(34,224,161,.1)", border: "1px solid rgba(34,224,161,.2)", color: "#22e0a1", width: 32, height: 32, borderRadius: 8, display: "inline-flex", alignItems: "center", justifyContent: "center", cursor: "pointer" },
  backBtn: { display: "inline-flex", alignItems: "center", gap: 6, padding: "9px 14px", borderRadius: 10, border: "1px solid rgba(34,224,161,.2)", background: "rgba(34,224,161,.08)", color: "#22e0a1", cursor: "pointer", fontFamily: "Tajawal", fontSize: 13 },

  topRow: { display: "flex", justifyContent: "space-between", alignItems: "center", gap: 12, flexWrap: "wrap", marginBottom: 16 },
  logoutBtn: { display: "inline-flex", alignItems: "center", gap: 6, padding: "9px 14px", borderRadius: 10, border: "1px solid rgba(255,107,107,.3)", background: "rgba(255,107,107,.08)", color: "#ff8585", cursor: "pointer", fontFamily: "Tajawal", fontSize: 13 },
  navRow: { display: "flex", gap: 8, flexWrap: "wrap" },
  navBtn: { position: "relative", display: "inline-flex", alignItems: "center", gap: 6, padding: "9px 15px", borderRadius: 10, border: "1px solid rgba(34,224,161,.15)", background: "rgba(11,28,23,.6)", color: "#9fbdb4", cursor: "pointer", fontFamily: "Tajawal", fontSize: 13.5, transition: ".2s" },
  navActive: { background: "linear-gradient(135deg,#22e0a1,#0e9b6f)", color: "#06120f", fontWeight: 700, border: "1px solid transparent" },
  navBadge: { background: "#ff6b6b", color: "#fff", borderRadius: 10, padding: "1px 7px", fontSize: 11, fontWeight: 700, marginRight: 4 },

  statGrid: { display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(220px,1fr))", gap: 14, marginBottom: 22 },
  stat: { display: "flex", alignItems: "center", gap: 14, padding: 18, borderRadius: 16, background: "rgba(11,28,23,.7)", border: "1px solid rgba(34,224,161,.12)" },
  statIcon: { width: 48, height: 48, borderRadius: 12, display: "grid", placeItems: "center", flexShrink: 0 },
  depositChip: { display: "inline-flex", alignItems: "center", gap: 4, padding: "5px 10px", borderRadius: 8, border: "none", background: "rgba(34,224,161,.18)", color: "#22e0a1", fontFamily: "Tajawal", fontSize: 12, fontWeight: 700, cursor: "pointer", whiteSpace: "nowrap" },

  cardGrid: { display: "grid", gridTemplateColumns: "repeat(auto-fill,minmax(250px,1fr))", gap: 16 },
  netCard: { padding: 20, borderRadius: 18, background: "linear-gradient(160deg,rgba(15,40,33,.9),rgba(8,22,18,.9))", border: "1px solid rgba(34,224,161,.18)", position: "relative", overflow: "hidden" },
  netCardTop: { display: "flex", justifyContent: "space-between", alignItems: "center", color: "#22e0a1", marginBottom: 14 },
  netCardName: { margin: "0 0 10px", fontSize: 18, fontFamily: "Tajawal" },
  netCardMeta: { display: "flex", flexDirection: "column", gap: 4, fontSize: 13, color: "#9fbdb4", marginBottom: 14 },
  netCardPrice: { fontSize: 26, fontWeight: 800, fontFamily: "Tajawal", color: "#22e0a1", marginBottom: 16 },
  availBadge: (n) => ({ fontSize: 12, padding: "3px 10px", borderRadius: 20, background: n > 0 ? "rgba(34,224,161,.15)" : "rgba(255,107,107,.15)", color: n > 0 ? "#22e0a1" : "#ff6b6b" }),
  buyBtn: { width: "100%", display: "inline-flex", alignItems: "center", justifyContent: "center", gap: 7, padding: "11px", borderRadius: 11, border: "none", background: "linear-gradient(135deg,#22e0a1,#0e9b6f)", color: "#06120f", fontWeight: 700, fontFamily: "Tajawal", fontSize: 14, cursor: "pointer" },
  buyBtnDisabled: { background: "rgba(255,255,255,.06)", color: "#6b8a82", cursor: "not-allowed" },

  section: { background: "rgba(11,28,23,.6)", border: "1px solid rgba(34,224,161,.12)", borderRadius: 18, padding: 22, marginBottom: 20 },
  collapseBox: { background: "rgba(0,0,0,.2)", borderRadius: 12, padding: 16, marginBottom: 4 },
  formGrid: { display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(200px,1fr))", gap: 12 },

  table: { width: "100%", borderCollapse: "collapse", fontSize: 13.5 },
  th: { textAlign: "right", padding: "10px 12px", color: "#6b8a82", fontWeight: 600, borderBottom: "1px solid rgba(34,224,161,.12)", whiteSpace: "nowrap", fontSize: 12.5 },
  tr: { borderBottom: "1px solid rgba(255,255,255,.04)" },
  td: { padding: "11px 12px", color: "#cfe6df" },
  tdEmpty: { padding: 28, textAlign: "center", color: "#6b8a82" },
  customerLink: { color: "#22e0a1", fontWeight: 700, display: "inline-flex", alignItems: "center", gap: 4 },

  miniBtn: { display: "inline-flex", alignItems: "center", gap: 4, padding: "5px 10px", borderRadius: 8, border: "none", background: "rgba(34,224,161,.15)", color: "#22e0a1", cursor: "pointer", fontFamily: "Tajawal", fontSize: 12.5 },
  miniBtnBlue: { display: "inline-flex", alignItems: "center", gap: 4, padding: "5px 10px", borderRadius: 8, border: "none", background: "rgba(76,182,255,.15)", color: "#4cb6ff", cursor: "pointer", fontFamily: "Tajawal", fontSize: 12.5 },
  miniBtnRed: { display: "inline-flex", alignItems: "center", gap: 4, padding: "5px 10px", borderRadius: 8, border: "none", background: "rgba(255,107,107,.15)", color: "#ff6b6b", cursor: "pointer", fontFamily: "Tajawal", fontSize: 12.5 },
  miniBtnGray: { display: "inline-flex", alignItems: "center", gap: 4, padding: "5px 10px", borderRadius: 8, border: "none", background: "rgba(255,255,255,.08)", color: "#9fbdb4", cursor: "pointer", fontFamily: "Tajawal", fontSize: 12.5 },
  miniBtnOrange: { display: "inline-flex", alignItems: "center", gap: 4, padding: "5px 10px", borderRadius: 8, border: "none", background: "rgba(255,170,80,.15)", color: "#ffa050", cursor: "pointer", fontFamily: "Tajawal", fontSize: 12.5 },
  tinyBtn: { padding: "2px 8px", borderRadius: 6, border: "1px solid rgba(34,224,161,.3)", background: "transparent", color: "#22e0a1", cursor: "pointer", fontFamily: "Tajawal", fontSize: 11 },

  tagFree: { padding: "3px 9px", borderRadius: 6, background: "rgba(34,224,161,.15)", color: "#22e0a1", fontSize: 12 },
  tagSold: { padding: "3px 9px", borderRadius: 6, background: "rgba(255,255,255,.08)", color: "#9fbdb4", fontSize: 12 },
  tagOk: { padding: "3px 9px", borderRadius: 6, background: "rgba(34,224,161,.12)", color: "#22e0a1", fontSize: 12 },
  tagBanned: { display: "inline-flex", alignItems: "center", gap: 4, padding: "3px 9px", borderRadius: 6, background: "rgba(255,107,107,.15)", color: "#ff6b6b", fontSize: 12 },
  tagGreen: { display: "inline-flex", alignItems: "center", gap: 3, padding: "3px 9px", borderRadius: 6, background: "rgba(34,224,161,.15)", color: "#22e0a1", fontSize: 12 },
  tagBlue: { padding: "3px 9px", borderRadius: 6, background: "rgba(76,182,255,.15)", color: "#4cb6ff", fontSize: 12 },
  tagOrange: { padding: "3px 9px", borderRadius: 6, background: "rgba(255,170,80,.15)", color: "#ffa050", fontSize: 12 },
  tagGray: { display: "inline-flex", alignItems: "center", gap: 3, padding: "3px 9px", borderRadius: 6, background: "rgba(255,255,255,.08)", color: "#9fbdb4", fontSize: 12 },

  barTrack: { height: 8, borderRadius: 4, background: "rgba(255,255,255,.06)", overflow: "hidden" },
  barFill: { height: "100%", borderRadius: 4, background: "linear-gradient(90deg,#0e9b6f,#22e0a1)" },

  leaderRow: { display: "flex", alignItems: "center", gap: 14 },
  rankBadge: { width: 32, height: 32, borderRadius: "50%", background: "rgba(34,224,161,.12)", color: "#22e0a1", display: "grid", placeItems: "center", fontWeight: 800, fontSize: 14, flexShrink: 0 },
  rankGold: { background: "linear-gradient(135deg,#ffd84c,#c89110)", color: "#1a1300" },
  rankSilver: { background: "linear-gradient(135deg,#d6dfe6,#8b9aa3)", color: "#1a1d20" },
  rankBronze: { background: "linear-gradient(135deg,#d9874c,#8c5022)", color: "#1f120a" },

  catStatCard: { padding: 18, borderRadius: 14, background: "linear-gradient(160deg,rgba(15,40,33,.85),rgba(8,22,18,.85))", border: "1px solid rgba(34,224,161,.15)" },
  catPctBadge: { padding: "3px 10px", borderRadius: 20, background: "rgba(34,224,161,.15)", color: "#22e0a1", fontSize: 12, fontWeight: 700, fontFamily: "Tajawal" },
  catGrid: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10 },
  catLabel: { fontSize: 11, color: "#6b8a82", marginBottom: 2 },
  catVal: { fontSize: 15, fontWeight: 700, fontFamily: "Tajawal", color: "#cfe6df" },

  filterChip: { padding: "7px 14px", borderRadius: 20, border: "1px solid rgba(34,224,161,.18)", background: "rgba(11,28,23,.7)", color: "#9fbdb4", cursor: "pointer", fontFamily: "Tajawal", fontSize: 13 },
  filterChipActive: { background: "linear-gradient(135deg,#22e0a1,#0e9b6f)", color: "#06120f", borderColor: "transparent", fontWeight: 700 },
  filterChipGreen: { background: "rgba(34,224,161,.18)", color: "#22e0a1", borderColor: "rgba(34,224,161,.4)", fontWeight: 700 },
  filterChipRed: { background: "rgba(255,107,107,.18)", color: "#ff8585", borderColor: "rgba(255,107,107,.4)", fontWeight: 700 },

  regionChip: { display: "inline-flex", alignItems: "center", gap: 4, padding: "4px 10px", borderRadius: 16, background: "rgba(255,255,255,.06)", color: "#9fbdb4", fontSize: 12 },
  regionChipActive: { display: "inline-flex", alignItems: "center", gap: 4, padding: "4px 10px", borderRadius: 16, background: "rgba(34,224,161,.18)", color: "#22e0a1", fontSize: 12, fontWeight: 700 },

  reqRow: { display: "flex", justifyContent: "space-between", alignItems: "center", gap: 10, padding: 14, background: "rgba(0,0,0,.22)", borderRadius: 12, border: "1px solid rgba(255,255,255,.04)", flexWrap: "wrap" },
  depReqCard: { padding: 16, background: "rgba(0,0,0,.22)", borderRadius: 14, border: "1px solid rgba(34,224,161,.2)" },
  statusPending: { display: "inline-flex", alignItems: "center", gap: 4, padding: "4px 10px", borderRadius: 20, background: "rgba(255,170,80,.15)", color: "#ffa050", fontSize: 12 },
  statusOk: { display: "inline-flex", alignItems: "center", gap: 4, padding: "4px 10px", borderRadius: 20, background: "rgba(34,224,161,.15)", color: "#22e0a1", fontSize: 12 },
  statusBad: { display: "inline-flex", alignItems: "center", gap: 4, padding: "4px 10px", borderRadius: 20, background: "rgba(255,107,107,.15)", color: "#ff6b6b", fontSize: 12 },

  credRow: { display: "flex", justifyContent: "space-between", alignItems: "center", padding: 14, background: "rgba(0,0,0,.3)", borderRadius: 10, gap: 12, flexWrap: "wrap" },

  modalBg: { position: "fixed", inset: 0, background: "rgba(0,0,0,.65)", backdropFilter: "blur(6px)", display: "grid", placeItems: "center", zIndex: 200, padding: 20 },
  modal: { width: "100%", maxWidth: 460, background: "linear-gradient(160deg,rgba(15,40,33,.96),rgba(8,22,18,.96))", border: "1px solid rgba(34,224,161,.25)", borderRadius: 18, padding: 22, boxShadow: "0 24px 70px rgba(0,0,0,.6)" },

  purchaseHead: { background: "linear-gradient(160deg,#22e0a1,#0e9b6f)", padding: "28px 22px 24px", textAlign: "center" },
  purchaseSuccess: { width: 64, height: 64, borderRadius: "50%", background: "rgba(255,255,255,.18)", color: "#06120f", display: "grid", placeItems: "center", margin: "0 auto", border: "3px solid rgba(255,255,255,.35)" },
  purchaseCard: { background: "linear-gradient(160deg,rgba(8,22,18,.95),rgba(15,40,33,.95))", border: "1px solid rgba(34,224,161,.25)", borderRadius: 14, padding: 18, position: "relative", overflow: "hidden" },
  purchaseCatBadge: { padding: "4px 12px", borderRadius: 20, background: "rgba(34,224,161,.15)", color: "#22e0a1", fontSize: 11.5, fontWeight: 700, fontFamily: "Tajawal" },

  processedByTag: { display: "inline-flex", alignItems: "center", gap: 4, padding: "3px 9px", borderRadius: 6, background: "rgba(176,140,255,.15)", color: "#b08cff", fontSize: 12 },

  toast: { position: "fixed", bottom: 24, left: "50%", transform: "translateX(-50%)", display: "flex", alignItems: "center", gap: 10, padding: "13px 20px", borderRadius: 12, background: "rgba(8,22,18,.95)", border: "1px solid", backdropFilter: "blur(10px)", zIndex: 300, fontSize: 14, maxWidth: "90vw", boxShadow: "0 12px 40px rgba(0,0,0,.5)" },
};

const globalCss = `
@import url('https://fonts.googleapis.com/css2?family=Tajawal:wght@400;500;700;800&display=swap');
* { box-sizing: border-box; }
::-webkit-scrollbar { height: 8px; width: 8px; }
::-webkit-scrollbar-thumb { background: rgba(34,224,161,.25); border-radius: 8px; }
input::placeholder, textarea::placeholder { color: #5a7771; }
select option { background: #0b1c17; color: #e8f5f0; }
.lift { transition: transform .2s, box-shadow .2s; }
.lift:hover { transform: translateY(-3px); box-shadow: 0 14px 36px rgba(0,0,0,.35); }
.press:active { transform: scale(.96); }
.rise { animation: rise .35s cubic-bezier(.2,.8,.2,1); }
@keyframes rise { from { opacity:0; transform: translateY(12px); } to { opacity:1; transform:none; } }
.pulse { animation: pulse 1.4s ease-in-out infinite; }
@keyframes pulse { 0%,100%{opacity:.4;transform:scale(.92)} 50%{opacity:1;transform:scale(1)} }
.toastIn { animation: toastIn .3s ease; }
@keyframes toastIn { from { opacity:0; transform: translate(-50%,16px); } to { opacity:1; transform: translate(-50%,0); } }
.rowHover:hover { background: rgba(34,224,161,.04); }
@media (max-width:520px){ table { font-size: 12px; } }
`;

/* ============================================================
   Mount
   ============================================================ */
createRoot(document.getElementById("root")).render(<App />);
