"use client";

import React, { useMemo, useState, useEffect, useCallback } from "react";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { useTranslations } from "next-intl";
import { useSession } from "next-auth/react";
import type { BreadcrumbItem } from "@limitless/ui";

import subBarMenu from "@/config/sub-bar-menu.json";
import topBarMenu from "@/config/top-bar-menu.json";
import siteInformation from "@/config/site-informations.json";

import { LogoutButton } from "@/components/LogoutButton";

type RawMenuItem = {
  id: number;
  name: string;
  url: string;
  icon?: string;
  key: string;
  submenulvl1?: { id?: number; name: string; url: string; key: string; icon?: string }[];
};

type SidebarChild = {
  label: string;
  href?: string;
  key: string;
  iconClass?: string;
  active?: boolean;
};

type SidebarItem = {
  label: string;
  href?: string;
  iconClass?: string;
  active?: boolean;
  isOpen?: boolean;
  onToggle?: () => void;
  children?: SidebarChild[];
  key: string;
};

function mapSidebarItems(
  menu: RawMenuItem[],
  pathname: string,
  openSubmenus: Set<string>,
  toggleSubmenu: (key: string) => void
): SidebarItem[] {
  return menu.map((item) => {
    const hasChildren = item.submenulvl1 && item.submenulvl1.length > 0;
    const isActive = item.url !== "#"
      ? pathname.startsWith(item.url)
      : item.submenulvl1?.some(child => pathname.startsWith(child.url)) ?? false;
    const isOpen = openSubmenus.has(item.key);

    return {
      label: item.name,
      href: item.url === "#" ? undefined : item.url,
      iconClass: item.icon,
      active: isActive,
      isOpen,
      onToggle: hasChildren ? () => toggleSubmenu(item.key) : undefined,
      key: item.key,
      children: hasChildren
        ? item.submenulvl1!.map((child) => ({
            label: child.name,
            href: child.url,
            key: child.key,
            iconClass: child.icon,
            active: child.url !== "#" ? pathname.startsWith(child.url) : false,
          }))
        : undefined,
    };
  });
}

function buildBreadcrumbs(pathname: string): BreadcrumbItem[] {
  const pathData = pathname.split("/").filter(Boolean);
  const breadcrumbs: BreadcrumbItem[] = [
    { label: <i className="ph-house" />, href: "/" }
  ];

  if (pathData.length === 0) {
    breadcrumbs.push({ label: "My Settings" });
  } else if (pathData.length === 1) {
    breadcrumbs.push({
      label: pathData[0].charAt(0).toUpperCase() + pathData[0].slice(1).toLowerCase(),
    });
  } else {
    breadcrumbs.push({
      label: pathData[pathData.length - 2].charAt(0).toUpperCase() +
             pathData[pathData.length - 2].slice(1).toLowerCase(),
    });
    breadcrumbs.push({
      label: pathData[pathData.length - 1].charAt(0).toUpperCase() +
             pathData[pathData.length - 1].slice(1).toLowerCase(),
    });
  }

  return breadcrumbs;
}

function getPageTitle(pathname: string): string {
  const pathData = pathname.split("/").filter(Boolean);
  if (pathData.length === 0) return "My Settings";
  const lastSegment = pathData[pathData.length - 1];
  return lastSegment.charAt(0).toUpperCase() + lastSegment.slice(1).toLowerCase();
}

const SIDEBAR_COLLAPSED_KEY = "my-sidebar-collapsed";

type MyShellProps = {
  sidebarMenu: RawMenuItem[];
  displayName?: string;
  givenName?: string;
  children: React.ReactNode;
};

export function MyShell({
  sidebarMenu,
  children,
}: MyShellProps) {
  const pathname = usePathname();
  const t = useTranslations();
  const [sidebarCollapsed, setSidebarCollapsed] = useState(false);
  const [showMobileSidebar, setShowMobileSidebar] = useState(false);
  const [openSubmenus, setOpenSubmenus] = useState<Set<string>>(() => {
    const initialOpen = new Set<string>();
    sidebarMenu.forEach((item) => {
      if (item.submenulvl1?.some(child => pathname.startsWith(child.url))) {
        initialOpen.add(item.key);
      }
    });
    return initialOpen;
  });

  useEffect(() => {
    setOpenSubmenus(prev => {
      const newSet = new Set(prev);
      sidebarMenu.forEach((item) => {
        if (item.submenulvl1?.some(child => pathname.startsWith(child.url))) {
          newSet.add(item.key);
        }
      });
      return newSet;
    });
  }, [pathname, sidebarMenu]);

  const toggleSubmenu = useCallback((key: string) => {
    setOpenSubmenus(prev => {
      const newSet = new Set(prev);
      if (newSet.has(key)) {
        newSet.delete(key);
      } else {
        newSet.add(key);
      }
      return newSet;
    });
  }, []);

  useEffect(() => {
    const stored = localStorage.getItem(SIDEBAR_COLLAPSED_KEY);
    if (stored !== null) {
      setSidebarCollapsed(stored === "true");
    }
  }, []);

  const isSidebarCollapsed = sidebarCollapsed && !showMobileSidebar;

  useEffect(() => {
    document.body.classList.toggle("sidebar-xs", isSidebarCollapsed);
    return () => {
      document.body.classList.remove("sidebar-xs");
    };
  }, [isSidebarCollapsed]);

  useEffect(() => {
    document.body.classList.toggle("sidebar-mobile-main", showMobileSidebar);
    return () => {
      document.body.classList.remove("sidebar-mobile-main");
    };
  }, [showMobileSidebar]);

  const toggleSidebar = () => {
    setSidebarCollapsed((prev) => {
      const newValue = !prev;
      localStorage.setItem(SIDEBAR_COLLAPSED_KEY, String(newValue));
      return newValue;
    });
  };

  const sidebarItems = useMemo(
    () => mapSidebarItems(sidebarMenu, pathname, openSubmenus, toggleSubmenu),
    [sidebarMenu, pathname, openSubmenus, toggleSubmenu]
  );
  const breadcrumbs = useMemo(() => buildBreadcrumbs(pathname), [pathname]);
  const pageTitle = useMemo(() => getPageTitle(pathname), [pathname]);
  const site = Array.isArray(siteInformation) ? siteInformation[0] : null;

  return (
    <>
      <MyNavbar
        showMobileSidebar={showMobileSidebar}
        setShowMobileSidebar={setShowMobileSidebar}
        t={t}
      />

      <MySubBar breadcrumbs={breadcrumbs} t={t} />

      <MyPageHeader pageTitle={pageTitle} />

      <div className="page-content d-flex align-items-start p-3 gap-3" style={{ minHeight: 0 }}>
        <MySidebar
          sidebarItems={sidebarItems}
          sidebarCollapsed={isSidebarCollapsed}
          showMobileSidebar={showMobileSidebar}
          setShowMobileSidebar={setShowMobileSidebar}
          toggleSidebar={toggleSidebar}
          pathname={pathname}
        />
        <main className="flex-grow-1" style={{ minWidth: 0 }}>
          {children}
        </main>
      </div>

      <MyFooter site={site} t={t} />
    </>
  );
}

function MyNavbar({
  showMobileSidebar,
  setShowMobileSidebar,
  t,
}: {
  showMobileSidebar: boolean;
  setShowMobileSidebar: (show: boolean) => void;
  t: (key: string) => string;
}) {
  const { data: session } = useSession();
  const [showNavMenu, setShowNavMenu] = useState(false);

  const user = session?.user as { displayName?: string; givenName?: string; image?: string } | undefined;
  const userName = user?.givenName || user?.displayName || session?.user?.name || "User";
  const userInitials = userName
    .split(" ")
    .map((n: string) => n[0])
    .join("")
    .slice(0, 2)
    .toUpperCase() || "?";

  return (
    <div className="navbar navbar-dark navbar-expand-lg navbar-static">
      <div className="container-fluid">
        <div className="d-flex d-lg-none me-2">
          <button
            type="button"
            className="navbar-toggler sidebar-mobile-main-toggle rounded-pill"
            onClick={() => setShowMobileSidebar(!showMobileSidebar)}
          >
            <i className="ph-list"></i>
          </button>
        </div>

        <div className="navbar-brand wmin-200">
          <Link href="/" className="d-inline-block">
            <img src="https://assets.gosec.cloud/logos/logo.svg" className="h-36px" alt="Logo" />
          </Link>
        </div>

        <ul className="nav flex-row justify-content-end order-1 order-lg-2 ms-auto">
          <li
            className="nav-item nav-item-dropdown-lg dropdown ms-lg-2"
            onMouseLeave={() => setShowNavMenu(false)}
          >
            <button
              type="button"
              className="navbar-nav-link align-items-center rounded-pill p-1 border-0 bg-transparent"
              onClick={() => setShowNavMenu(!showNavMenu)}
            >
              <div className="status-indicator-container">
                <span
                  className="w-32px h-32px rounded-pill bg-primary bg-opacity-20 text-primary d-inline-flex align-items-center justify-content-center fw-semibold"
                  style={{ fontSize: "0.75rem" }}
                >
                  {userInitials}
                </span>
                <span className="status-indicator bg-success"></span>
              </div>
              <span className="d-none d-lg-inline-block mx-lg-2">
                {userName}
              </span>
            </button>

            <div
              className={showNavMenu ? "dropdown-menu dropdown-menu-end show" : "dropdown-menu dropdown-menu-end"}
              style={{
                position: "absolute",
                inset: "0px 0px auto auto",
                margin: "0px",
                transform: "translate3d(0px, 44px, 0px)",
              }}
            >
              {topBarMenu.map((menuItem) => (
                <Link
                  href={menuItem.url}
                  className="dropdown-item"
                  key={menuItem.id}
                >
                  <i className={`${menuItem.icon} me-2`}></i>
                  {menuItem.name}
                </Link>
              ))}
              <LogoutButton label={t("menu.logout")} />
            </div>
          </li>
        </ul>
      </div>
    </div>
  );
}

function MySubBar({
  breadcrumbs,
  t,
}: {
  breadcrumbs: BreadcrumbItem[];
  t: (key: string) => string;
}) {
  const [showCollapsedSubMenu, setShowCollapsedSubMenu] = useState(false);
  const [showSubNavBarMenu, setShowSubNavBarMenu] = useState(false);

  return (
    <div className="page-header page-header-light shadow">
      <div className="page-header-content d-lg-flex">
        <div className="d-flex">
          <div className="breadcrumb py-2">
            {breadcrumbs.map((bc, idx) => (
              <span
                key={idx}
                className={idx === breadcrumbs.length - 1 ? "breadcrumb-item active" : "breadcrumb-item"}
              >
                {bc.href ? <Link href={bc.href}>{bc.label}</Link> : bc.label}
              </span>
            ))}
          </div>

          <button
            type="button"
            className="btn btn-light align-self-center collapsed d-lg-none border-transparent rounded-pill p-0 ms-auto"
            onClick={() => setShowCollapsedSubMenu(!showCollapsedSubMenu)}
          >
            <i className={showCollapsedSubMenu ? "ph-caret-left ph-sm m-1" : "ph-caret-down ph-sm m-1"}></i>
          </button>
        </div>

        <div
          className={showCollapsedSubMenu ? "collapse d-lg-block ms-lg-auto show" : "collapse d-lg-block ms-lg-auto"}
        >
          <div className="d-lg-flex mb-2 mb-lg-0">
            <div
              className="dropdown"
              onMouseLeave={() => setShowSubNavBarMenu(false)}
            >
              <Link
                href="#"
                className={showSubNavBarMenu
                  ? "d-flex align-items-center text-body py-2 active"
                  : "d-flex align-items-center text-body py-2"
                }
                onClick={() => setShowSubNavBarMenu(!showSubNavBarMenu)}
              >
                <i className="ph-gear me-2"></i>
                <span className="flex-1">{t("menu.settings")}</span>
                <i className={showSubNavBarMenu ? "ph-caret-up ms-1" : "ph-caret-down ms-1"}></i>
              </Link>

              <div
                className={showSubNavBarMenu
                  ? "dropdown-menu dropdown-menu-end w-100 w-lg-auto show"
                  : "dropdown-menu dropdown-menu-end w-100 w-lg-auto"
                }
                style={{
                  position: "absolute",
                  inset: "0px 0px auto auto",
                  margin: "0px",
                  transform: "translate3d(0px, 44px, 0px)",
                }}
              >
                {subBarMenu.map((menuItem) => (
                  <Link
                    href={menuItem.url}
                    className="dropdown-item"
                    key={menuItem.key}
                  >
                    <i className={`${menuItem.icon} me-2`}></i>
                    {menuItem.name}
                  </Link>
                ))}
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

function MyPageHeader({ pageTitle }: { pageTitle: string }) {
  return (
    <div className="page-header">
      <div className="page-header-content d-lg-flex">
        <div className="d-flex">
          <h4 className="page-title mb-0">
            <span className="fw-normal">{pageTitle}</span>
          </h4>
        </div>
      </div>
    </div>
  );
}

function MySidebar({
  sidebarItems,
  sidebarCollapsed,
  showMobileSidebar,
  setShowMobileSidebar,
  toggleSidebar,
  pathname,
}: {
  sidebarItems: SidebarItem[];
  sidebarCollapsed: boolean;
  showMobileSidebar: boolean;
  setShowMobileSidebar: (show: boolean) => void;
  toggleSidebar: () => void;
  pathname: string;
}) {
  const sidebarClasses = [
    "sidebar",
    "sidebar-light",
    "sidebar-main",
    "sidebar-expand-lg",
    "align-self-start",
    sidebarCollapsed ? "sidebar-main-resized" : "",
  ].filter(Boolean).join(" ");

  return (
    <div className={sidebarClasses}>
      <div className="sidebar-content">
        <div className="sidebar-section">
          <div className="sidebar-section-body d-flex justify-content-center">
            {!sidebarCollapsed && (
              <h5 className="sidebar-resize-hide flex-grow-1 my-auto">
                Navigation
              </h5>
            )}
            <div>
              <button
                type="button"
                className="btn btn-light btn-icon btn-sm rounded-pill border-transparent sidebar-control sidebar-main-resize d-none d-lg-inline-flex"
                onClick={toggleSidebar}
                aria-label={sidebarCollapsed ? "Expand sidebar" : "Collapse sidebar"}
              >
                <i className="ph-arrows-left-right"></i>
              </button>
              <button
                type="button"
                className="btn btn-light btn-icon btn-sm rounded-pill border-transparent sidebar-mobile-main-toggle d-lg-none"
                onClick={() => setShowMobileSidebar(!showMobileSidebar)}
                aria-label="Close sidebar"
              >
                <i className="ph-x"></i>
              </button>
            </div>
          </div>
        </div>

        <div className="sidebar-section">
          <ul className="nav nav-sidebar" data-nav-type="accordion">
            <li className="nav-item-header pt-0">
              {!sidebarCollapsed ? (
                <div className="text-uppercase fs-sm lh-sm opacity-50 sidebar-resize-hide">
                  SETTINGS
                </div>
              ) : (
                <i className="ph-dots-three sidebar-resize-show"></i>
              )}
            </li>
            {sidebarItems.map((item) => (
              <SidebarNavItem
                key={item.key}
                item={item}
                collapsed={sidebarCollapsed}
                pathname={pathname}
              />
            ))}
          </ul>
        </div>
      </div>
    </div>
  );
}

function SidebarNavItem({
  item,
  collapsed,
  pathname,
}: {
  item: SidebarItem;
  collapsed: boolean;
  pathname: string;
}) {
  const hasChildren = item.children && item.children.length > 0;
  const isActive = item.active ?? (item.href ? pathname.startsWith(item.href) : false);
  const [isHovered, setIsHovered] = useState(false);

  const icon = item.iconClass ? <i className={item.iconClass}></i> : null;

  if (hasChildren) {
    const showFlyout = collapsed && isHovered;
    const showInline = !collapsed && item.isOpen;
    const navItemClasses = [
      "nav-item",
      "nav-item-submenu",
      showInline ? "nav-item-open" : "",
      showFlyout ? "nav-group-sub-visible" : "",
    ].filter(Boolean).join(" ");

    return (
      <li
        className={navItemClasses}
        onMouseEnter={collapsed ? () => setIsHovered(true) : undefined}
        onMouseLeave={collapsed ? () => setIsHovered(false) : undefined}
      >
        <a
          href="#"
          className={`nav-link ${isActive ? "active" : ""}`}
          title={collapsed ? item.label : undefined}
          onClick={(event) => {
            event.preventDefault();
            item.onToggle?.();
          }}
          onMouseEnter={collapsed ? () => setIsHovered(true) : undefined}
          onFocus={collapsed ? () => setIsHovered(true) : undefined}
        >
          {icon}
          {!collapsed && <span>{item.label}</span>}
        </a>
        <ul
          className={
            collapsed
              ? "nav-group-sub nav-group-sub-flyout collapse"
              : `nav-group-sub collapse ${item.isOpen ? "show" : ""}`
          }
          data-submenu-title={item.label}
        >
          {item.children!.map((child) => (
            <li className="nav-item" key={child.key}>
              {child.href ? (
                <Link
                  href={child.href}
                  className={`nav-link ${pathname.startsWith(child.href) ? "active" : ""}`}
                >
                  {child.iconClass && <i className={child.iconClass}></i>}
                  {child.label}
                </Link>
              ) : (
                <span className="nav-link">
                  {child.iconClass && <i className={child.iconClass}></i>}
                  {child.label}
                </span>
              )}
            </li>
          ))}
        </ul>
      </li>
    );
  }

  return (
    <li className="nav-item">
      {item.href ? (
        <Link
          href={item.href}
          className={`nav-link ${pathname.startsWith(item.href) ? "active" : ""}`}
          title={collapsed ? item.label : undefined}
        >
          {icon}
          {!collapsed && <span>{item.label}</span>}
        </Link>
      ) : (
        <span className="nav-link">
          {icon}
          {!collapsed && <span>{item.label}</span>}
        </span>
      )}
    </li>
  );
}

function MyFooter({ site, t }: { site: Record<string, unknown> | null; t: ReturnType<typeof useTranslations> }) {
  const siteData = site as { company?: { website?: string }; site?: { name?: string; product?: string } } | null;

  return (
    <div className="navbar navbar-sm navbar-footer border-top">
      <div className="container-fluid">
        <span>
          &copy; 2023 - {new Date().getFullYear()}{" "}
          <a href={siteData?.company?.website}>
            {siteData?.site?.name} - {siteData?.site?.product}
          </a>
        </span>

        <ul className="nav">
          <li className="nav-item">
            <a
              href="https://support.gosec.cloud/"
              className="navbar-nav-link navbar-nav-link-icon rounded"
              target="_blank"
              rel="noreferrer"
            >
              <div className="d-flex align-items-center mx-md-1">
                <i className="ph-lifebuoy"></i>
                <span className="d-none d-md-inline-block ms-2">Support</span>
              </div>
            </a>
          </li>
          <li className="nav-item ms-md-1">
            <a
              href="https://support.gosec.cloud/support/"
              className="navbar-nav-link navbar-nav-link-icon rounded"
              target="_blank"
              rel="noreferrer"
            >
              <div className="d-flex align-items-center mx-md-1">
                <i className="ph-file-text"></i>
                <span className="d-none d-md-inline-block ms-2">
                  {t("footer.docs")}
                </span>
              </div>
            </a>
          </li>
        </ul>
      </div>
    </div>
  );
}

export default MyShell;
