// @File: src/pages/AdminDashboard.tsx
// @Desc: Live admin dashboard. Fetches real KPIs, revenue series, top products,
//        recent orders and ticket queue from /api/v1/admin/dashboard. Uses live
//        admin identity from fetchMe(). Search bar hits /api/v1/admin/search.
//        Non-admins are redirected to /login.
import { useEffect, useMemo, useRef, useState } from "react";
import { Link, useNavigate } from "react-router-dom";
import {
  LayoutDashboard, Building2, Users, ShoppingCart, Package, Tag, TicketCheck,
  ShieldCheck, Menu as MenuIcon, Settings, Palette, KeyRound, Lock, LogOut, Search,
  Bell, TrendingUp, DollarSign, ChevronRight, Loader2, AlertTriangle,
  FileText, UserPlus,
} from "lucide-react";
import { client } from "@/lib/api";
import { fetchMe, signOut, extractErrorMessage } from "@/lib/auth";

const NAV_GROUPS = [
  {
    title: "Overview",
    items: [{ icon: LayoutDashboard, label: "Dashboard", to: "/admin" }],
  },
  {
    title: "Business",
    items: [
      { icon: Building2, label: "Tenants", to: "/admin/cms/tenants" },
      { icon: Users, label: "Clients", to: "/admin/cms/users" },
      { icon: ShoppingCart, label: "Orders", to: "/admin/cms/orders" },
      { icon: DollarSign, label: "Billing", to: "/admin/cms/billing" },
    ],
  },
  {
    title: "Catalog",
    items: [
      { icon: Package, label: "Products", to: "/admin/cms/products" },
      { icon: Tag, label: "Plans", to: "/admin/cms/plans" },
    ],
  },
  {
    title: "Support",
    items: [
      { icon: TicketCheck, label: "Tickets", to: "/admin/cms/tickets" },
      { icon: UserPlus, label: "Users & Roles", to: "/admin/cms/users" },
    ],
  },
  {
    title: "Configuration",
    items: [
      { icon: MenuIcon, label: "General", to: "/admin/cms/general" },
      { icon: Palette, label: "Branding", to: "/admin/cms/branding" },
      { icon: Settings, label: "Notifications", to: "/admin/cms/notifications" },
      { icon: KeyRound, label: "Security", to: "/admin/cms/security" },
      { icon: Lock, label: "WHMCS Diagnostics", to: "/admin/cms/whmcs-logs" },
    ],
  },
];

interface KpiCard { label: string; value: string; raw: number; trend?: string | null; }
interface RevenuePoint { label: string; value: number; }
interface TopProduct { name: string; count: number; revenue: string; pct: number; }
interface RecentOrder { id: string; client: string; product: string; total: string; status: string; }
interface TicketQueueItem { id: string; subject: string; dept: string; priority: string; agent?: string | null; }
interface DashboardPayload {
  kpis: KpiCard[];
  revenue_series: RevenuePoint[];
  top_products: TopProduct[];
  recent_orders: RecentOrder[];
  ticket_queue: TicketQueueItem[];
  whmcs_ok: boolean;
  errors: string[];
}

interface SearchItem { type: string; id: string; title: string; subtitle?: string | null; link: string; }

const KPI_ICONS: Record<string, typeof DollarSign> = {
  "MRR": DollarSign,
  "Active Clients": Users,
  "New Orders (30d)": ShoppingCart,
  "Open Tickets": TicketCheck,
};

function Avatar({ name }: { name: string }) {
  const initials = name
    .split(/\s+/)
    .filter(Boolean)
    .slice(0, 2)
    .map((s) => s[0]?.toUpperCase() ?? "")
    .join("") || "A";
  return (
    <div className="w-9 h-9 rounded-full bg-slate-900 text-white flex items-center justify-center font-bold text-sm">
      {initials}
    </div>
  );
}

export default function AdminDashboard() {
  const navigate = useNavigate();
  const [me, setMe] = useState<{ name?: string; email: string; role?: string } | null>(null);
  const [authChecked, setAuthChecked] = useState(false);
  const [data, setData] = useState<DashboardPayload | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  // Search state
  const [searchQ, setSearchQ] = useState("");
  const [searchResults, setSearchResults] = useState<SearchItem[]>([]);
  const [searchOpen, setSearchOpen] = useState(false);
  const searchDebounce = useRef<number | null>(null);

  // Notifications count
  const [unread, setUnread] = useState(0);

  // --- Auth gate ---
  useEffect(() => {
    let cancelled = false;
    (async () => {
      const user = await fetchMe();
      if (cancelled) return;
      if (!user) {
        navigate("/login", { replace: true });
        return;
      }
      const role = (user.role || "").toLowerCase();
      const isAdmin =
        role === "admin" || role === "superadmin" ||
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        (user as any).is_admin === true || (user as any).is_superuser === true;
      if (!isAdmin) {
        navigate("/dashboard", { replace: true });
        return;
      }
      setMe({ name: user.name || user.email, email: user.email, role: user.role });
      setAuthChecked(true);
    })();
    return () => { cancelled = true; };
  }, [navigate]);

  // --- Load dashboard ---
  useEffect(() => {
    if (!authChecked) return;
    let cancelled = false;
    (async () => {
      setLoading(true);
      setError(null);
      try {
        const res = await client.apiCall.invoke({
          method: "GET",
          url: "/api/v1/admin/dashboard",
        });
        if (cancelled) return;
        setData(res.data as DashboardPayload);
      } catch (err) {
        if (cancelled) return;
        setError(extractErrorMessage(err, "Failed to load dashboard."));
      } finally {
        if (!cancelled) setLoading(false);
      }
    })();
    return () => { cancelled = true; };
  }, [authChecked]);

  // --- Load unread notifications ---
  useEffect(() => {
    if (!authChecked) return;
    (async () => {
      try {
        const res = await client.apiCall.invoke({
          method: "GET",
          url: "/api/v1/notifications/unread-count",
        });
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        const count = (res.data as any)?.count ?? 0;
        setUnread(Number(count) || 0);
      } catch {
        setUnread(0);
      }
    })();
  }, [authChecked]);

  // --- Search (debounced) ---
  useEffect(() => {
    if (searchDebounce.current) window.clearTimeout(searchDebounce.current);
    if (!searchQ.trim()) {
      setSearchResults([]);
      setSearchOpen(false);
      return;
    }
    searchDebounce.current = window.setTimeout(async () => {
      try {
        const res = await client.apiCall.invoke({
          method: "GET",
          url: `/api/v1/admin/search?q=${encodeURIComponent(searchQ.trim())}`,
        });
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        setSearchResults(((res.data as any)?.items ?? []) as SearchItem[]);
        setSearchOpen(true);
      } catch {
        setSearchResults([]);
      }
    }, 300);
  }, [searchQ]);

  const chartPath = useMemo(() => {
    if (!data?.revenue_series?.length) return { area: "", line: "", dots: [] as { x: number; y: number }[] };
    const series = data.revenue_series;
    const w = 600, h = 200, pad = 30;
    const max = Math.max(...series.map((s) => s.value), 1);
    const step = (w - pad * 2) / Math.max(series.length - 1, 1);
    const pts = series.map((s, i) => ({
      x: pad + i * step,
      y: h - pad - (s.value / max) * (h - pad * 2),
    }));
    const line = pts.map((p, i) => `${i === 0 ? "M" : "L"}${p.x.toFixed(1)},${p.y.toFixed(1)}`).join(" ");
    const area = `${line} L${pts[pts.length - 1].x.toFixed(1)},${h - pad} L${pts[0].x.toFixed(1)},${h - pad} Z`;
    return { area, line, dots: pts };
  }, [data]);

  const onSignOut = () => signOut("/login");

  if (!authChecked) {
    return (
      <div className="min-h-screen flex items-center justify-center bg-slate-50">
        <Loader2 className="w-6 h-6 animate-spin text-slate-400" />
      </div>
    );
  }

  return (
    <div className="min-h-screen bg-slate-50 flex">
      {/* SIDEBAR */}
      <aside className="w-64 bg-slate-900 text-white flex flex-col sticky top-0 h-screen">
        <div className="p-5 border-b border-white/10">
          <Link to="/" className="flex items-center gap-2">
            <img src="/logo.svg" alt="DoItEasy" className="h-10 md:h-12 w-auto brightness-0 invert" />
          </Link>
          <div className="mt-2 inline-flex items-center gap-1 bg-[#f5c400] text-slate-900 text-[10px] font-bold px-2 py-0.5 rounded">
            <ShieldCheck className="w-3 h-3" /> ADMIN CONSOLE
          </div>
        </div>
        <nav className="flex-1 overflow-y-auto py-3">
          {NAV_GROUPS.map((g) => (
            <div key={g.title} className="mb-3">
              <p className="px-5 text-[10px] font-bold text-slate-500 uppercase tracking-wider mb-1">{g.title}</p>
              {g.items.map((n) => {
                const isActive = typeof window !== "undefined" && window.location.pathname === n.to;
                return (
                  <Link
                    key={n.to}
                    to={n.to}
                    className={`w-full flex items-center gap-3 px-5 py-2 text-sm transition ${
                      isActive
                        ? "bg-[#0b6e3e] text-white border-l-4 border-[#f5c400]"
                        : "text-slate-300 hover:bg-white/5 border-l-4 border-transparent"
                    }`}
                  >
                    <n.icon className="w-4 h-4" />
                    {n.label}
                  </Link>
                );
              })}
            </div>
          ))}
        </nav>
        <div className="p-4 border-t border-white/10">
          <button
            onClick={onSignOut}
            className="flex items-center gap-2 text-sm text-slate-300 hover:text-[#f5c400]"
          >
            <LogOut className="w-4 h-4" /> Sign out
          </button>
        </div>
      </aside>

      {/* MAIN */}
      <div className="flex-1 flex flex-col">
        {/* TOPBAR */}
        <header className="h-16 bg-white border-b border-slate-200 flex items-center justify-between px-6 sticky top-0 z-10">
          <h1 className="text-lg font-bold text-slate-900">Admin Dashboard</h1>
          <div className="flex items-center gap-4">
            <div className="relative hidden md:block">
              <Search className="w-4 h-4 absolute left-3 top-1/2 -translate-y-1/2 text-slate-400" />
              <input
                value={searchQ}
                onChange={(e) => setSearchQ(e.target.value)}
                onFocus={() => searchResults.length && setSearchOpen(true)}
                onBlur={() => window.setTimeout(() => setSearchOpen(false), 200)}
                placeholder="Search clients, orders…"
                className="pl-9 pr-4 py-2 bg-slate-100 rounded-lg text-sm w-72 outline-none focus:ring-2 focus:ring-[#0b6e3e]/20"
              />
              {searchOpen && searchResults.length > 0 && (
                <div className="absolute top-full left-0 mt-1 w-80 bg-white rounded-lg border border-slate-200 shadow-lg z-50 max-h-96 overflow-y-auto">
                  {searchResults.map((r, i) => (
                    <Link
                      key={`${r.type}-${r.id}-${i}`}
                      to={r.link}
                      className="block px-4 py-2.5 hover:bg-slate-50 border-b border-slate-100 last:border-0"
                    >
                      <div className="flex items-center gap-2">
                        <span className={`text-[10px] font-bold px-1.5 py-0.5 rounded uppercase ${
                          r.type === "client" ? "bg-blue-100 text-blue-700" :
                          r.type === "order" ? "bg-emerald-100 text-emerald-700" :
                          "bg-amber-100 text-amber-700"
                        }`}>{r.type}</span>
                        <span className="font-semibold text-sm text-slate-900 truncate">{r.title}</span>
                      </div>
                      {r.subtitle && <div className="text-xs text-slate-500 mt-0.5 truncate">{r.subtitle}</div>}
                    </Link>
                  ))}
                </div>
              )}
              {searchOpen && searchQ && searchResults.length === 0 && (
                <div className="absolute top-full left-0 mt-1 w-80 bg-white rounded-lg border border-slate-200 shadow-lg z-50 px-4 py-3 text-sm text-slate-500">
                  No results for "{searchQ}".
                </div>
              )}
            </div>
            <Link to="/admin/cms/notifications" className="relative w-10 h-10 rounded-lg hover:bg-slate-100 flex items-center justify-center">
              <Bell className="w-5 h-5 text-slate-600" />
              {unread > 0 && (
                <span className="absolute top-1 right-1 min-w-[18px] h-[18px] px-1 bg-rose-500 text-white text-[10px] font-bold rounded-full flex items-center justify-center">
                  {unread > 99 ? "99+" : unread}
                </span>
              )}
            </Link>
            <div className="flex items-center gap-2">
              <Avatar name={me?.name || me?.email || "Admin"} />
              <div className="hidden md:block">
                <div className="text-sm font-bold text-slate-900">{me?.name || me?.email}</div>
                <div className="text-xs text-slate-500">{me?.role ? me.role.charAt(0).toUpperCase() + me.role.slice(1) : "Administrator"}</div>
              </div>
            </div>
          </div>
        </header>

        <main className="flex-1 p-6 space-y-6">
          {/* Error / WHMCS status banner */}
          {data && !data.whmcs_ok && (
            <div className="bg-amber-50 border border-amber-200 text-amber-800 rounded-xl p-4 flex items-start gap-3">
              <AlertTriangle className="w-5 h-5 flex-shrink-0 mt-0.5" />
              <div className="flex-1 text-sm">
                <div className="font-bold">WHMCS connection issue</div>
                <div className="text-xs mt-1">
                  Some live data could not be loaded. {data.errors.slice(0, 2).join(" · ")}
                </div>
                <Link to="/admin/cms/whmcs-logs" className="text-xs font-semibold underline mt-1 inline-block">
                  Open WHMCS Diagnostics →
                </Link>
              </div>
            </div>
          )}

          {error && (
            <div className="bg-rose-50 border border-rose-200 text-rose-800 rounded-xl p-4 flex items-center gap-3">
              <AlertTriangle className="w-5 h-5 flex-shrink-0" />
              <div className="text-sm">{error}</div>
            </div>
          )}

          {/* KPIs */}
          <div className="grid grid-cols-2 lg:grid-cols-4 gap-4">
            {loading && !data
              ? Array.from({ length: 4 }).map((_, i) => (
                  <div key={i} className="bg-white rounded-2xl p-5 border border-slate-200 shadow-sm animate-pulse">
                    <div className="h-3 w-20 bg-slate-200 rounded" />
                    <div className="h-8 w-24 bg-slate-200 rounded mt-3" />
                    <div className="h-3 w-16 bg-slate-200 rounded mt-2" />
                  </div>
                ))
              : (data?.kpis ?? []).map((k) => {
                  const Icon = KPI_ICONS[k.label] || DollarSign;
                  return (
                    <div key={k.label} className="bg-white rounded-2xl p-5 border border-slate-200 shadow-sm">
                      <div className="flex items-start justify-between">
                        <div>
                          <p className="text-sm text-slate-500">{k.label}</p>
                          <p className="text-2xl font-bold text-slate-900 mt-1">{k.value}</p>
                          {k.trend && (
                            <p className="text-xs mt-1 flex items-center gap-1 text-emerald-600 font-semibold">
                              <TrendingUp className="w-3 h-3" /> {k.trend}
                            </p>
                          )}
                        </div>
                        <div className="w-11 h-11 rounded-xl bg-[#0b6e3e] text-white flex items-center justify-center">
                          <Icon className="w-5 h-5" />
                        </div>
                      </div>
                    </div>
                  );
                })}
          </div>

          {/* CHARTS + TOP PRODUCTS */}
          <div className="grid lg:grid-cols-3 gap-6">
            <div className="lg:col-span-2 bg-white rounded-2xl border border-slate-200 shadow-sm p-5">
              <div className="flex items-center justify-between mb-5">
                <div>
                  <h3 className="font-bold text-slate-900">Revenue (last 12 months)</h3>
                  <p className="text-xs text-slate-500">Paid invoices, grouped by month</p>
                </div>
              </div>
              {loading && !data ? (
                <div className="h-48 flex items-center justify-center"><Loader2 className="w-5 h-5 animate-spin text-slate-400" /></div>
              ) : !data?.revenue_series?.length ? (
                <div className="h-48 flex items-center justify-center text-sm text-slate-500">No revenue data yet.</div>
              ) : (
                <svg viewBox="0 0 600 220" className="w-full h-48">
                  <defs>
                    <linearGradient id="ag" x1="0" y1="0" x2="0" y2="1">
                      <stop offset="0%" stopColor="#0b6e3e" stopOpacity="0.35" />
                      <stop offset="100%" stopColor="#0b6e3e" stopOpacity="0" />
                    </linearGradient>
                  </defs>
                  {[40, 80, 120, 160, 200].map(y => (
                    <line key={y} x1="30" x2="590" y1={y} y2={y} stroke="#e2e8f0" strokeDasharray="4 4" />
                  ))}
                  <path d={chartPath.area} fill="url(#ag)" />
                  <path d={chartPath.line} fill="none" stroke="#0b6e3e" strokeWidth="2.5" />
                  {chartPath.dots.map((p, i) => (
                    <circle key={i} cx={p.x} cy={p.y} r="3" fill="#f5c400" />
                  ))}
                  {data.revenue_series.map((s, i) => {
                    const step = (600 - 60) / Math.max(data.revenue_series.length - 1, 1);
                    const x = 30 + i * step;
                    return (
                      <text key={i} x={x} y={215} fontSize="9" fill="#64748b" textAnchor="middle">
                        {s.label.slice(5)}
                      </text>
                    );
                  })}
                </svg>
              )}
            </div>

            <div className="bg-white rounded-2xl border border-slate-200 shadow-sm p-5">
              <h3 className="font-bold text-slate-900 mb-4">Top Products</h3>
              {loading && !data ? (
                <div className="flex items-center justify-center py-8"><Loader2 className="w-5 h-5 animate-spin text-slate-400" /></div>
              ) : !data?.top_products?.length ? (
                <div className="text-sm text-slate-500 py-8 text-center">No products available.</div>
              ) : (
                <div className="space-y-4">
                  {data.top_products.map((p) => (
                    <div key={p.name}>
                      <div className="flex justify-between text-sm mb-1">
                        <span className="font-semibold text-slate-800 truncate">{p.name}</span>
                        <span className="text-slate-500 flex-shrink-0 ml-2">{p.revenue}</span>
                      </div>
                      <div className="h-1.5 rounded-full bg-slate-100 overflow-hidden">
                        <div className="h-full bg-[#0b6e3e]" style={{ width: `${p.pct}%` }} />
                      </div>
                    </div>
                  ))}
                </div>
              )}
            </div>
          </div>

          {/* RECENT ORDERS + TICKETS */}
          <div className="grid lg:grid-cols-2 gap-6">
            <div className="bg-white rounded-2xl border border-slate-200 shadow-sm">
              <div className="flex items-center justify-between p-5 border-b border-slate-100">
                <h3 className="font-bold text-slate-900">Recent Orders</h3>
                <Link to="/admin/cms/orders" className="text-sm text-[#0b6e3e] font-semibold flex items-center gap-1 hover:underline">
                  View all <ChevronRight className="w-4 h-4" />
                </Link>
              </div>
              {loading && !data ? (
                <div className="p-8 flex items-center justify-center"><Loader2 className="w-5 h-5 animate-spin text-slate-400" /></div>
              ) : !data?.recent_orders?.length ? (
                <div className="p-8 text-center text-sm text-slate-500">No recent orders.</div>
              ) : (
                <table className="w-full text-sm">
                  <thead className="bg-slate-50 text-slate-600">
                    <tr>
                      <th className="text-left p-3 font-semibold">Order</th>
                      <th className="text-left p-3 font-semibold">Client</th>
                      <th className="text-left p-3 font-semibold">Total</th>
                      <th className="text-left p-3 font-semibold">Status</th>
                    </tr>
                  </thead>
                  <tbody>
                    {data.recent_orders.map((o) => (
                      <tr key={o.id} className="border-t border-slate-100 hover:bg-slate-50">
                        <td className="p-3">
                          <div className="font-semibold text-slate-900">#{o.id}</div>
                          <div className="text-xs text-slate-500">{o.product}</div>
                        </td>
                        <td className="p-3">{o.client}</td>
                        <td className="p-3 font-bold">{o.total}</td>
                        <td className="p-3">
                          <span className={`text-xs font-semibold px-2.5 py-1 rounded-full ${
                            o.status.toLowerCase() === "active" || o.status.toLowerCase() === "paid" ? "bg-emerald-100 text-emerald-700" :
                            o.status.toLowerCase() === "pending" ? "bg-amber-100 text-amber-700" :
                            "bg-rose-100 text-rose-700"
                          }`}>{o.status}</span>
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              )}
            </div>

            <div className="bg-white rounded-2xl border border-slate-200 shadow-sm">
              <div className="flex items-center justify-between p-5 border-b border-slate-100">
                <h3 className="font-bold text-slate-900">Ticket Queue</h3>
                <Link to="/admin/cms/tickets" className="text-sm text-[#0b6e3e] font-semibold flex items-center gap-1 hover:underline">
                  Open <ChevronRight className="w-4 h-4" />
                </Link>
              </div>
              {loading && !data ? (
                <div className="p-8 flex items-center justify-center"><Loader2 className="w-5 h-5 animate-spin text-slate-400" /></div>
              ) : !data?.ticket_queue?.length ? (
                <div className="p-8 text-center text-sm text-slate-500">No open tickets.</div>
              ) : (
                <div className="divide-y divide-slate-100">
                  {data.ticket_queue.map((t) => (
                    <div key={t.id} className="p-4 hover:bg-slate-50 flex items-center justify-between">
                      <div className="min-w-0">
                        <div className="font-bold text-slate-900 text-sm truncate">{t.id} · {t.subject}</div>
                        <div className="text-xs text-slate-500 truncate">
                          {t.dept}{t.agent ? ` · Assigned to ${t.agent}` : " · Unassigned"}
                        </div>
                      </div>
                      <span className={`text-xs font-semibold px-2.5 py-1 rounded-full flex-shrink-0 ml-2 ${
                        t.priority.toLowerCase() === "critical" ? "bg-rose-100 text-rose-700" :
                        t.priority.toLowerCase() === "high" ? "bg-amber-100 text-amber-700" :
                        t.priority.toLowerCase() === "medium" ? "bg-blue-100 text-blue-700" :
                        "bg-slate-100 text-slate-700"
                      }`}>{t.priority}</span>
                    </div>
                  ))}
                </div>
              )}
            </div>
          </div>

          {/* QUICK SETTINGS */}
          <div className="grid md:grid-cols-3 gap-4">
            {[
              { icon: Palette, title: "Branding", desc: "Logo, colors, legal links", to: "/admin/cms/branding" },
              { icon: KeyRound, title: "Security", desc: "MFA & password policies", to: "/admin/cms/security" },
              { icon: FileText, title: "WHMCS Diagnostics", desc: "API health, logs, error classifier", to: "/admin/cms/whmcs-logs" },
            ].map((c) => (
              <Link
                key={c.title}
                to={c.to}
                className="bg-white rounded-2xl border border-slate-200 p-5 flex items-center gap-4 hover:shadow-md transition"
              >
                <div className="w-12 h-12 rounded-xl bg-[#0b6e3e] text-white flex items-center justify-center">
                  <c.icon className="w-5 h-5" />
                </div>
                <div className="flex-1">
                  <h4 className="font-bold text-slate-900">{c.title}</h4>
                  <p className="text-xs text-slate-500">{c.desc}</p>
                </div>
                <ChevronRight className="w-4 h-4 text-slate-400" />
              </Link>
            ))}
          </div>
        </main>
      </div>
    </div>
  );
}