"use client";

import { Fragment, useEffect, useState } from "react";
import Link from "next/link";
import { usePathname, useRouter } from "next/navigation";
import { useLang } from "@/context/LanguageContext";
import { LanguageSwitcher } from "@/components/LanguageSwitcher";
import NotificationBell from "@/components/NotificationBell";
import { IncrelogLogo } from "@/components/IncrelogLogo";
import { api } from "@/lib/client";
import {
  IconAcademic,
  IconActivity,
  IconLifeBuoy,
  IconAlign,
  IconBuilding,
  IconCard,
  IconClipboard,
  IconDashboard,
  IconLock,
  IconLogout,
  IconMore,
  IconPackage,
} from "@/components/icons";
import type { ComponentType } from "react";

export interface NavItem {
  href: string;
  label: string;
  icon: ComponentType<{ className?: string }>;
  /** opens in a new tab (public pages like the User Guide) */
  external?: boolean;
  /** sidebar section header shown above this item's run (sequence preserved) */
  group?: string;
}

export function PanelShell({
  navItems,
  panelTitle,
  userName,
  userEmail,
  roleLabel,
  accentLabel,
  logoUrl,
  children,
}: {
  navItems: NavItem[];
  panelTitle: string;
  userName: string;
  userEmail: string;
  roleLabel: string;
  accentLabel?: string;
  logoUrl?: string;
  children: React.ReactNode;
}) {
  const pathname = usePathname();
  const router = useRouter();
  const { t } = useLang();
  const [loggingOut, setLoggingOut] = useState(false);
  // profile dropdown open state — hover doesn't exist on touch screens, so
  // the avatar also toggles it on tap (closed by an outside tap)
  const [profileOpen, setProfileOpen] = useState(false);
  // below lg the theme collapses .nav-right > ul (avatar, language, bell) into
  // a hidden bar revealed by the "..." button — its jQuery toggle isn't loaded,
  // so we drive the same .open class from React
  const [mobileNavOpen, setMobileNavOpen] = useState(false);
  useEffect(() => {
    if (!profileOpen && !mobileNavOpen) return;
    const close = (e: MouseEvent) => {
      const el = e.target as HTMLElement;
      if (profileOpen && !el.closest(".onhover-dropdown")) setProfileOpen(false);
      if (mobileNavOpen && !el.closest(".nav-right")) setMobileNavOpen(false);
    };
    document.addEventListener("click", close);
    return () => document.removeEventListener("click", close);
  }, [profileOpen, mobileNavOpen]);

  // Optimistic menu selection: the clicked item highlights instantly (before
  // the route transition finishes) and shows an inline spinner in its icon
  // slot. Cleared as soon as the pathname actually changes.
  const [pendingHref, setPendingHref] = useState<string | null>(null);
  useEffect(() => {
    setPendingHref(null);
  }, [pathname]);

  async function logout() {
    setLoggingOut(true);
    try {
      await api("/api/auth/logout", { method: "POST" });
    } finally {
      router.replace("/login");
      router.refresh();
    }
  }

  const initials = userName
    .split(" ")
    .map((w) => w[0])
    .slice(0, 2)
    .join("")
    .toUpperCase();

  return (
    <div className="page-wrapper compact-wrapper" id="pageWrapper">
      {/* Slim indeterminate progress bar while a menu navigation is in flight */}
      {pendingHref && <div className="ems-route-progress" aria-hidden="true" />}
      {/* ---------- Page Header (Viho topbar) ---------- */}
      <div className="page-main-header">
        <div className="main-header-right row m-0">
          <div className="main-header-left">
            <div className="logo-wrapper d-flex align-items-center gap-2">
              <Link href="/">
                <IncrelogLogo size={38} />
              </Link>
              <div className="d-none d-xl-block">
                <h6 className="mb-0 f-w-800">IncrelogEMS</h6>
                <p className="mb-0 ems-fs-11 text-muted">{panelTitle}</p>
              </div>
            </div>
            <div className="toggle-sidebar cursor-pointer">
              <span className="status_toggle middle d-inline-flex">
                <IconAlign />
              </span>
            </div>
          </div>

          <div className="nav-right col pull-right right-menu p-0">
            <ul className={`nav-menus ${mobileNavOpen ? "open" : ""}`}>
              {accentLabel && (
                <li className="d-none d-sm-inline-block">
                  <span className="badge badge-primary">{accentLabel}</span>
                </li>
              )}
              <li>
                <LanguageSwitcher />
              </li>
              <NotificationBell />
              <li className={`onhover-dropdown p-0 ${profileOpen ? "open" : ""}`}>
                <div
                  className="d-flex align-items-center gap-2 cursor-pointer media user-media px-2"
                  onClick={() => setProfileOpen((o) => !o)}
                >
                  <span
                    className="rounded-circle d-flex align-items-center justify-content-center f-w-800"
                    style={{ width: 36, height: 36, background: "rgba(36,105,92,0.14)", color: "#24695c" }}
                  >
                    {initials}
                  </span>
                  <div className="d-none d-lg-block text-start">
                    <h6 className="mb-0 f-w-700 ems-fs-13">{userName}</h6>
                    <p className="mb-0 ems-fs-11 text-muted">{roleLabel}</p>
                  </div>
                </div>
                <ul className="profile-dropdown onhover-show-div" style={{ minWidth: 240 }}>
                  <li className="px-3 pt-3 pb-2">
                    <h6 className="f-w-700 mb-0">{userName}</h6>
                    <p className="mb-0 ems-fs-12 text-muted">{userEmail}</p>
                  </li>
                  <li className="px-3 pb-2">
                    <span className="badge badge-primary">{roleLabel}</span>
                  </li>
                  <li className="px-3 pb-3">
                    <button
                      className="btn btn-soft-danger w-100"
                      onClick={logout}
                      disabled={loggingOut}
                    >
                      <IconLogout className="svg-16" />
                      <span className="ms-2">{loggingOut ? t.common.processing : t.common.logout}</span>
                    </button>
                  </li>
                </ul>
              </li>
            </ul>
          </div>
          <div
            className="d-lg-none mobile-toggle pull-right w-auto cursor-pointer"
            onClick={() => setMobileNavOpen((o) => !o)}
          >
            <IconMore />
          </div>
        </div>
      </div>

      {/* ---------- Page Body ---------- */}
      <div className="page-body-wrapper sidebar-icon">
        {/* Sidebar (Viho main-nav) */}
        <header className="main-nav">
          <div className="sidebar-user text-center d-lg-none">
            {logoUrl ? (
              <img
                className="img-90 rounded-circle bg-white"
                src={logoUrl}
                alt={userName}
                style={{ width: 90, height: 90, objectFit: "contain", padding: 6 }}
              />
            ) : (
              <img className="img-90 rounded-circle" src="/assets/images/dashboard/1.png" alt="user" />
            )}
            <div className="badge-bottom">
              <span className="badge badge-primary">{roleLabel}</span>
            </div>
            <h6 className="mt-3 f-14 f-w-600">{userName}</h6>
            <p className="mb-0 font-roboto ems-fs-12">{userEmail}</p>
          </div>
          <nav>
            <div className="main-navbar">
              <div id="mainnav">
                <ul className="nav-menu custom-scrollbar">
                  <li className="back-btn">
                    <div className="mobile-back text-end">
                      <span>{t.common.back}</span>
                      <i className="fa fa-angle-right ps-2" />
                    </div>
                  </li>
                  <li className="sidebar-main-title">
                    <div>
                      <h6>{panelTitle}</h6>
                    </div>
                  </li>
                  {navItems.map((item, index) => {
                    const isActive =
                      item.href === pathname ||
                      (item.href !== "/central" &&
                        item.href !== "/portal" &&
                        item.href !== "/me" &&
                        pathname.startsWith(item.href));
                    const pending = pendingHref === item.href && !isActive;
                    const Icon = item.icon;
                    // Section header whenever the group label changes; items
                    // keep their given order — groups only insert breaks.
                    const showGroup =
                      !!item.group && item.group !== navItems[index - 1]?.group;
                    return (
                      <Fragment key={item.href}>
                        {showGroup && (
                          <li className="ems-nav-group" aria-hidden="true">
                            <span>{item.group}</span>
                          </li>
                        )}
                        <li
                          className={`dropdown ${isActive || pending ? "active" : ""}`}
                        >
                          <Link
                            className="nav-link menu-title"
                            href={item.href}
                            target={item.external ? "_blank" : undefined}
                            onClick={() => {
                              if (!isActive && !item.external) setPendingHref(item.href);
                            }}
                          >
                            {pending ? (
                              <span className="ems-nav-pending">
                                <span className="spinner-border" role="status" />
                              </span>
                            ) : (
                              <Icon />
                            )}
                            <span>{item.label}</span>
                          </Link>
                        </li>
                      </Fragment>
                    );
                  })}
                  {/* logout — always the last item, at the bottom of the menu */}
                  <li className="ems-nav-logout">
                    <a
                      className="nav-link menu-title"
                      role="button"
                      onClick={(e) => {
                        e.preventDefault();
                        if (!loggingOut) logout();
                      }}
                    >
                      <IconLogout />
                      <span>{loggingOut ? t.common.processing : t.common.logout}</span>
                    </a>
                  </li>
                </ul>
              </div>
            </div>
          </nav>

        </header>

        {/* Content — <main> is the page-content landmark (scoped by base text styles).
            key={pathname} replays a short slide-in on every navigation. */}
        <div className="page-body">
          <main className="container-fluid">
            <div key={pathname} className="ems-page-enter">
              {children}
            </div>
          </main>
        </div>

        {/* Body footer — the menu footer moved out of the sidebar */}
        <footer className="ems-body-footer text-center">
          <div className="ems-body-footer-line d-inline-flex align-items-center justify-content-center gap-2 flex-wrap">
            <IncrelogLogo size={22} />
            <p className="mb-0">
              © {new Date().getFullYear()} IncrelogEMS — {t.landing.rights}
            </p>
            <span className="ems-body-footer-sep" />
            <p className="mb-0">{t.landing.poweredBy}</p>
          </div>
        </footer>
      </div>
    </div>
  );
}

export const centralNavIcons = {
  support: IconLifeBuoy,
  dashboard: IconDashboard,
  packages: IconPackage,
  institutions: IconBuilding,
  accounts: IconLock,
  requests: IconClipboard,
  payments: IconCard,
  academic: IconAcademic,
  monitoring: IconActivity,
};
