// @File: src/pages/admin/cms/CmsLayout.tsx
// @Desc: Admin CMS shell with a grouped, collapsible sidebar. The navigation
//        was flattening into 20+ items; related entries are now aggregated
//        into foldable sections for scannability.
import { ReactNode, useEffect, useMemo, useState } from "react";
import { Link, useLocation } from "react-router-dom";
import {
  Palette, ShieldCheck, Bell, DollarSign, Users, Settings, UserCircle,
  Menu, X, ArrowLeft, LayoutDashboard, LogIn, UserPlus, Activity, Shield,
  ClipboardList, Radar, Plug, CreditCard, Server, Mail, MessageSquare,
  Globe, ChevronDown, ChevronRight, Boxes, Eye, Hammer, Truck,
} from "lucide-react";

type NavItem = {
  to: string;
  label: string;
  icon: typeof Palette;
  desc?: string;
  badge?: string;
};

type NavGroup = {
  id: string;
  label: string;
  icon: typeof Palette;
  items: NavItem[];
};

const NAV_GROUPS: NavGroup[] = [
  {
    id: "site",
    label: "Site & Brand",
    icon: Palette,
    items: [
      { to: "/admin/cms/branding", label: "Branding", icon: Palette, desc: "Logo, slider, colors, fonts" },
      { to: "/admin/cms/general", label: "General", icon: Settings, desc: "Site info & SEO" },
      { to: "/admin/cms/login-page", label: "Login Page", icon: LogIn, desc: "Layouts & auth branding" },
      { to: "/admin/cms/registration", label: "Registration", icon: UserPlus, desc: "Signup rules & approvals" },
    ],
  },
  {
    id: "access",
    label: "Security & Access",
    icon: ShieldCheck,
    items: [
      { to: "/admin/cms/security", label: "Security", icon: ShieldCheck, desc: "Password, sessions, IPs" },
      { to: "/admin/cms/mfa", label: "MFA (SMS)", icon: ShieldCheck, desc: "Two-factor authentication" },
      { to: "/admin/cms/users", label: "Users & Roles", icon: Users, desc: "Accounts & permissions" },
      { to: "/admin/cms/roles", label: "Roles Management", icon: Shield, desc: "Grant admin / staff access" },
      { to: "/admin/cms/audit-log", label: "Audit Log", icon: ClipboardList, desc: "Admin actions & logins" },
    ],
  },
  {
    id: "messaging",
    label: "Notifications & Pricing",
    icon: Bell,
    items: [
      { to: "/admin/cms/notifications", label: "Notifications", icon: Bell, desc: "SMTP & event emails" },
      { to: "/admin/cms/pricing", label: "Pricing Plans", icon: DollarSign, desc: "Plans & layout" },
    ],
  },
  {
    id: "integrations",
    label: "Integrations",
    icon: Plug,
    items: [
      { to: "/admin/cms/api-hub", label: "API Hub", icon: Plug, desc: "All integrations, one console" },
      { to: "/admin/cms/api-hub/integrations", label: "· Integrations", icon: Activity, desc: "WHMCS, CRM, analytics" },
      { to: "/admin/cms/api-hub/notifications", label: "· Notifications", icon: Bell, desc: "SMS, WhatsApp, email, push" },
      { to: "/admin/cms/api-hub/payments", label: "· Payments", icon: CreditCard, desc: "PayPal, Stripe, bank transfer" },
      { to: "/admin/cms/whmcs-logs", label: "WHMCS Diagnostics", icon: Activity, desc: "API logs & health checks" },
      { to: "/admin/cms/whmcs-health", label: "WHMCS Health", icon: Activity, desc: "Live ping, outbound IP, 24h uptime" },
    ],
  },
  {
    id: "reseller",
    label: "Reseller Modules",
    icon: Boxes,
    items: [
      { to: "/admin/cms/uptimerobot", label: "UptimeRobot", icon: Activity, desc: "Monitoring plans & client monitors" },
      { to: "/admin/cms/uptimerobot/mcp", label: "· MCP Integration", icon: Activity, desc: "AI assistant access via Model Context Protocol" },
      { to: "/admin/cms/uptimerobot/sync", label: "· Data Fetch", icon: Activity, desc: "Clients / monitors / domains" },
      { to: "/admin/cms/bizmail", label: "Bizmail360", icon: Mail, desc: "SmarterMail plans & mailboxes" },
      { to: "/admin/cms/bizmail/sync", label: "· Data Fetch", icon: Activity, desc: "Clients / mailboxes / domains" },
      { to: "/admin/cms/cpanel", label: "WHM / cPanel", icon: Server, desc: "Hosting packages & accounts" },
      { to: "/admin/cms/cpanel/servers", label: "· Servers", icon: Server, desc: "WHM endpoints" },
      { to: "/admin/cms/cpanel/packages", label: "· Packages", icon: Hammer, desc: "Reseller hosting plans" },
      { to: "/admin/cms/cpanel/accounts", label: "· Accounts", icon: Users, desc: "Client cPanel accounts" },
      { to: "/admin/cms/whatsapp", label: "WhatsApp Business", icon: MessageSquare, desc: "Reseller packages & devices" },
      { to: "/admin/cms/whatsapp/packages", label: "· Packages", icon: Hammer, desc: "WhatsApp plan quotas & features" },
      { to: "/admin/cms/whatsapp/subscriptions", label: "· Subscriptions", icon: Users, desc: "Client WhatsApp subscriptions" },
      { to: "/admin/cms/whatsapp/audit-log", label: "· Audit & API Log", icon: ClipboardList, desc: "Admin actions & upstream calls" },
      { to: "/admin/cms/whatsapp/sync", label: "· Data Fetch", icon: Activity, desc: "Clients / devices / domains" },
    ],
  },
  {
    id: "shipping",
    label: "Shipping",
    icon: Truck,
    items: [
      { to: "/admin/cms/shipping/dhl", label: "DHL Business", icon: Truck, desc: "DHL account, pickup, shipments" },
      { to: "/admin/cms/shipping/dhl/notifications", label: "DHL Notifications", icon: Truck, desc: "Email delivery log & re-poll tracking" },
    ],
  },
  {
    id: "sync",
    label: "Module Sync Center",
    icon: Globe,
    items: [
      { to: "/admin/cms/module-sync/logs", label: "Sync Logs", icon: ClipboardList, desc: "All modules' sync history" },
      { to: "/admin/cms/module-sync/diagnostics", label: "Diagnostics", icon: Activity, desc: "Live health for every module" },
    ],
  },
  {
    id: "ops",
    label: "Monitoring",
    icon: Eye,
    items: [
      { to: "/admin/cms/visitor-monitor", label: "Visitor Monitor", icon: Radar, desc: "Live visitors & campaigns" },
    ],
  },
  {
    id: "profile",
    label: "Account",
    icon: UserCircle,
    items: [
      { to: "/admin/cms/profile", label: "Admin Profile", icon: UserCircle, desc: "Your account" },
    ],
  },
];

const STORAGE_KEY = "cms.sidebar.groups";

function loadExpanded(): Record<string, boolean> {
  try {
    const raw = localStorage.getItem(STORAGE_KEY);
    if (raw) return JSON.parse(raw) as Record<string, boolean>;
  } catch {
    // ignore
  }
  return {};
}

export default function CmsLayout({ children }: { children: ReactNode }) {
  const { pathname } = useLocation();
  const [open, setOpen] = useState(false);
  const [expanded, setExpanded] = useState<Record<string, boolean>>(() => loadExpanded());
  const [filter, setFilter] = useState("");

  // Auto-expand the group that matches the current URL so users don't hit
  // "where did my active item go" after a navigation.
  const activeGroupId = useMemo(() => {
    for (const group of NAV_GROUPS) {
      if (group.items.some((it) => pathname === it.to || pathname.startsWith(it.to + "/"))) {
        return group.id;
      }
    }
    return null;
  }, [pathname]);

  useEffect(() => {
    if (!activeGroupId) return;
    setExpanded((prev) => (prev[activeGroupId] ? prev : { ...prev, [activeGroupId]: true }));
  }, [activeGroupId]);

  useEffect(() => {
    try {
      localStorage.setItem(STORAGE_KEY, JSON.stringify(expanded));
    } catch {
      // ignore quota / privacy errors
    }
  }, [expanded]);

  const toggleGroup = (id: string) =>
    setExpanded((prev) => ({ ...prev, [id]: !prev[id] }));

  const expandAll = () =>
    setExpanded(Object.fromEntries(NAV_GROUPS.map((g) => [g.id, true])));
  const collapseAll = () =>
    setExpanded(Object.fromEntries(NAV_GROUPS.map((g) => [g.id, false])));

  const normalizedFilter = filter.trim().toLowerCase();
  const filteredGroups = useMemo(() => {
    if (!normalizedFilter) return NAV_GROUPS;
    return NAV_GROUPS.map((g) => ({
      ...g,
      items: g.items.filter(
        (it) =>
          it.label.toLowerCase().includes(normalizedFilter) ||
          (it.desc ?? "").toLowerCase().includes(normalizedFilter),
      ),
    })).filter((g) => g.items.length > 0);
  }, [normalizedFilter]);

  return (
    <div className="min-h-screen bg-slate-100">
      {/* Top bar */}
      <header className="sticky top-0 z-40 bg-white border-b border-slate-200 shadow-sm">
        <div className="flex items-center justify-between px-4 md:px-6 h-16">
          <div className="flex items-center gap-3">
            <button
              onClick={() => setOpen(!open)}
              className="lg:hidden p-2 rounded-lg hover:bg-slate-100"
              aria-label="Toggle menu"
            >
              {open ? <X className="w-5 h-5" /> : <Menu className="w-5 h-5" />}
            </button>
            <Link to="/admin" className="flex items-center gap-2 text-slate-600 hover:text-[#0b6e3e]">
              <ArrowLeft className="w-4 h-4" />
              <span className="text-sm font-semibold">Dashboard</span>
            </Link>
            <div className="hidden md:block h-6 w-px bg-slate-200 mx-2" />
            <div className="flex items-center gap-2">
              <div className="w-9 h-9 rounded-lg bg-[#0b6e3e] text-white flex items-center justify-center">
                <LayoutDashboard className="w-5 h-5" />
              </div>
              <div>
                <div className="text-sm font-bold text-slate-900">Site Admin · CMS</div>
                <div className="text-[11px] text-slate-500">DoItEasy Control Panel</div>
              </div>
            </div>
          </div>
          <div className="flex items-center gap-3">
            <span className="hidden md:inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full bg-emerald-50 border border-emerald-200 text-[11px] font-semibold text-emerald-700">
              <span className="w-1.5 h-1.5 rounded-full bg-emerald-500 animate-pulse" />
              Saved
            </span>
            <div className="w-9 h-9 rounded-full bg-gradient-to-br from-[#0b6e3e] to-[#063019] text-white flex items-center justify-center font-bold text-sm">
              AD
            </div>
          </div>
        </div>
      </header>

      <div className="flex">
        {/* Sidebar */}
        <aside
          className={`${
            open ? "block" : "hidden"
          } lg:block fixed lg:static inset-0 top-16 lg:top-0 z-30 w-72 bg-white border-r border-slate-200 lg:h-[calc(100vh-4rem)] lg:sticky lg:top-16 overflow-y-auto`}
        >
          <nav className="p-4 space-y-2">
            <div className="flex items-center justify-between px-1 pt-1">
              <div className="text-[11px] uppercase tracking-wider font-bold text-slate-400">
                Configuration
              </div>
              <div className="flex gap-1 text-[10px]">
                <button
                  type="button"
                  onClick={expandAll}
                  className="px-2 py-0.5 rounded bg-slate-100 hover:bg-slate-200 text-slate-600"
                >
                  Expand
                </button>
                <button
                  type="button"
                  onClick={collapseAll}
                  className="px-2 py-0.5 rounded bg-slate-100 hover:bg-slate-200 text-slate-600"
                >
                  Collapse
                </button>
              </div>
            </div>

            <div className="px-1">
              <input
                type="search"
                value={filter}
                onChange={(e) => setFilter(e.target.value)}
                placeholder="Search settings…"
                className="w-full text-sm px-3 py-2 rounded-lg border border-slate-200 focus:outline-none focus:ring-2 focus:ring-[#0b6e3e]/30"
              />
            </div>

            <div className="space-y-1">
              {filteredGroups.length === 0 && (
                <div className="px-3 py-4 text-xs text-slate-500">
                  No settings match “{filter}”.
                </div>
              )}
              {filteredGroups.map((group) => {
                const GroupIcon = group.icon;
                // If user is filtering, keep everything expanded for visibility.
                const isExpanded = normalizedFilter
                  ? true
                  : expanded[group.id] ?? group.id === activeGroupId;
                const groupHasActive = group.items.some(
                  (it) => pathname === it.to || pathname.startsWith(it.to + "/"),
                );
                return (
                  <div key={group.id} className="rounded-xl">
                    <button
                      type="button"
                      onClick={() => !normalizedFilter && toggleGroup(group.id)}
                      className={`w-full flex items-center justify-between gap-2 px-3 py-2 rounded-xl transition ${
                        groupHasActive
                          ? "bg-emerald-50 text-emerald-900"
                          : "hover:bg-slate-100 text-slate-700"
                      }`}
                    >
                      <span className="flex items-center gap-2 min-w-0">
                        <GroupIcon className="w-4 h-4 shrink-0 text-slate-500" />
                        <span className="text-[13px] font-semibold truncate">{group.label}</span>
                        <span className="text-[10px] text-slate-400">({group.items.length})</span>
                      </span>
                      {normalizedFilter ? null : isExpanded ? (
                        <ChevronDown className="w-4 h-4 text-slate-400" />
                      ) : (
                        <ChevronRight className="w-4 h-4 text-slate-400" />
                      )}
                    </button>

                    {isExpanded && (
                      <div className="mt-1 ml-2 pl-2 border-l border-slate-200 space-y-0.5">
                        {group.items.map((item) => {
                          const active =
                            pathname === item.to || pathname.startsWith(item.to + "/");
                          const Icon = item.icon;
                          return (
                            <Link
                              key={item.to}
                              to={item.to}
                              onClick={() => setOpen(false)}
                              className={`flex items-start gap-2 px-3 py-2 rounded-lg transition ${
                                active
                                  ? "bg-[#0b6e3e] text-white shadow"
                                  : "text-slate-700 hover:bg-slate-100"
                              }`}
                            >
                              <Icon
                                className={`w-4 h-4 shrink-0 mt-0.5 ${
                                  active ? "text-[#f5c400]" : "text-slate-400"
                                }`}
                              />
                              <div className="min-w-0">
                                <div className="text-[13px] font-semibold leading-tight">
                                  {item.label}
                                </div>
                                {item.desc && (
                                  <div
                                    className={`text-[11px] leading-tight ${
                                      active ? "text-white/80" : "text-slate-500"
                                    }`}
                                  >
                                    {item.desc}
                                  </div>
                                )}
                              </div>
                            </Link>
                          );
                        })}
                      </div>
                    )}
                  </div>
                );
              })}
            </div>
          </nav>
          <div className="p-4 border-t border-slate-200 text-[11px] text-slate-500">
            <div className="font-semibold text-slate-700 mb-1">CMS v1.0</div>
            Changes apply to the live site preview. Save to persist.
          </div>
        </aside>

        {/* Main */}
        <main className="flex-1 min-w-0 p-4 md:p-8 max-w-6xl 3xl:max-w-[1500px] 4xl:max-w-[1800px] 5xl:max-w-[2200px] mx-auto w-full">
          {children}
        </main>
      </div>
    </div>
  );
}