import { AppShell, Drawer } from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
import {
  IconAnchor,
  IconArrowsExchange,
  IconBell,
  IconBook2,
  IconFingerprint,
  IconFolderOpen,
  IconHeadset,
  IconHome2,
  IconList,
  IconRubberStamp,
  IconShieldCheck,
  IconShieldOff,
  IconShip,
  IconStethoscope,
  IconTruck,
  IconUserCircle,
} from "@tabler/icons-react";
import { Outlet, useLocation, useNavigate } from "react-router-dom";
import { useMemo } from "react";
import { useTranslation } from "react-i18next";
import { useDispatch } from "react-redux";
import {
  notify,
  AppHeader,
  AppSidebar,
  filterByPermissions,
  SkipLink,
  MAIN_CONTENT_ID,
} from "@ema-platform/ui";
import type { NavItem } from "@ema-platform/ui";
import {
  BrandMark,
  logout,
  usePermissions,
  LICENSE_PERMISSIONS,
  PORTAL_PERMISSIONS,
} from "@ema-platform/auth";
import { baseApi, useGetUnseenNotificationsQuery } from "@ema-platform/api";
import { SUPPORTED_LANGUAGES } from "../i18n/config";
import { useAppSelector } from "../store/hooks";

const BADGE_POLL_MS = 60_000;

type PortalNavItem = NavItem & { i18nKey: string };

// Grant keys the server computes per portal account type (seafarer, vessel
// owner, logistics rep). Items with no `permissions` are universal.
const P = PORTAL_PERMISSIONS;
const L = LICENSE_PERMISSIONS;

/**
 * Grouped for scannability, with `soon` marking screens that have no backend
 * behind them yet. There are no per-licence-type entries: applicants pick a
 * licence from the dashboard catalogue or "My Applications", both driven by
 * the licence types configured on the server.
 */
const NAV_SECTIONS: { label?: string; items: PortalNavItem[] }[] = [
  {
    items: [
      {
        to: "/dashboard",
        label: "Dashboard",
        i18nKey: "nav.dashboard",
        icon: IconHome2,
      },
      {
        to: "/notifications",
        label: "Notifications",
        i18nKey: "nav.notifications",
        icon: IconBell,
      },
    ],
  },
  {
    label: "nav.groupLicensing",
    items: [
      {
        to: "/licensing/applications",
        label: "My Applications",
        i18nKey: "nav.myApplications",
        icon: IconTruck,
        permissions: [L.VIEW_OWN_APPLICATIONS],
      },
      {
        to: "/waiver",
        label: "Waiver",
        i18nKey: "nav.waiver",
        icon: IconShieldOff,
        permissions: [P.APPLY_WAIVER, P.VIEW_WAIVER_LETTER],
      },
    ],
  },
  {
    label: "nav.groupSeafarer",
    items: [
      {
        to: "/seafarer-registration",
        label: "Seafarer Registration",
        i18nKey: "nav.seafarerRegistration",
        icon: IconList,
        permissions: [P.APPLY_SEAFARER_REGISTRATION],
      },
      {
        to: "/seafarer/sea-service",
        label: "Sea Service",
        i18nKey: "nav.seaService",
        icon: IconAnchor,
        permissions: [P.VIEW_OWN_SEA_SERVICE],
      },
      {
        to: "/seafarer/medical",
        label: "Medical Certificate",
        i18nKey: "nav.medical",
        icon: IconStethoscope,
        permissions: [P.VIEW_OWN_MEDICAL],
      },
      {
        // One page tracks both documents; the BTC needs no entry of its own.
        to: "/seaman-book",
        label: "SeamanBook and BTC",
        i18nKey: "nav.seamanBook",
        icon: IconBook2,
        permissions: [P.VIEW_OWN_SEA_SERVICE, P.VIEW_OWN_MEDICAL],
      },
      {
        to: "/certificates",
        label: "Certificates",
        i18nKey: "nav.certificates",
        icon: IconShieldCheck,
        permissions: [P.VIEW_OWN_CERTIFICATES],
      },
      {
        to: "/seafarer/biometrics",
        label: "Biometrics",
        i18nKey: "nav.biometrics",
        icon: IconFingerprint,
        permissions: [P.VIEW_OWN_BIOMETRICS],
      },
      {
        to: "/exams",
        label: "Examinations",
        i18nKey: "nav.exams",
        icon: IconList,
        permissions: [P.VIEW_OWN_EXAM, P.APPLY_EXAM],
      },
      {
        to: "/endorsements",
        label: "Endorsement Seafarer",
        i18nKey: "nav.endorsements",
        icon: IconRubberStamp,
        permissions: [P.VIEW_OWN_CERTIFICATES],
      },
    ],
  },
  {
    label: "nav.groupVessels",
    items: [
      {
        to: "/vessel-registration",
        label: "Vessel Registration",
        i18nKey: "nav.vesselRegistration",
        icon: IconShip,
        permissions: [P.APPLY_VESSEL_REGISTRATION, P.VIEW_OWN_VESSELS],
      },
      {
        to: "/vessel-ownership-transfer",
        label: "Ownership Transfer",
        i18nKey: "nav.ownershipTransfer",
        icon: IconArrowsExchange,
        permissions: [P.APPLY_VESSEL_REGISTRATION, P.VIEW_OWN_VESSELS],
      },
    ],
  },
  {
    label: "nav.groupAccount",
    items: [
      {
        to: "/documents",
        label: "My Documents",
        i18nKey: "nav.documents",
        icon: IconFolderOpen,
      },
      {
        to: "/profile",
        label: "Profile",
        i18nKey: "nav.profile",
        icon: IconUserCircle,
      },
      {
        to: "/support",
        label: "Help & Support",
        i18nKey: "nav.support",
        icon: IconHeadset,
      },
    ],
  },
];

const PAGE_META: Record<string, { i18nKey: string }> = {
  "/dashboard": { i18nKey: "nav.dashboard" },
  "/vessel-registration-dashboard": {
    i18nKey: "nav.vesselRegistrationDashboard",
  },
  "/vessel-registration": { i18nKey: "nav.vesselRegistration" },
  "/vessel-ownership-transfer": { i18nKey: "nav.ownershipTransfer" },
  "/licensing/applications": { i18nKey: "nav.myApplications" },
  "/waiver": { i18nKey: "nav.waiver" },
  "/seafarer-registration": { i18nKey: "nav.seafarerRegistration" },
  "/seafarer/sea-service": { i18nKey: "nav.seaService" },
  "/seafarer/medical": { i18nKey: "nav.medical" },
  "/seaman-book": { i18nKey: "nav.seamanBook" },
  "/basic-training-certificate": { i18nKey: "nav.btc" },
  "/certificates": { i18nKey: "nav.certificates" },
  "/seafarer/biometrics": { i18nKey: "nav.biometrics" },
  "/exams": { i18nKey: "nav.exams" },
  "/endorsements": { i18nKey: "nav.endorsements" },
  "/documents": { i18nKey: "nav.documents" },
  "/notifications": { i18nKey: "nav.notifications" },
  "/profile": { i18nKey: "nav.profile" },
  "/support": { i18nKey: "nav.support" },
};

export function PortalLayout() {
  const { t } = useTranslation();
  const navigate = useNavigate();
  const location = useLocation();
  const dispatch = useDispatch();
  const user = useAppSelector((state) => state.auth.user);
  const [navOpened, { toggle: toggleNav, close: closeNav }] = useDisclosure();
  const [sidebarCollapsed, { toggle: toggleSidebar }] = useDisclosure(false);
  const { data: unseen } = useGetUnseenNotificationsQuery(undefined, {
    pollingInterval: BADGE_POLL_MS,
    refetchOnMountOrArgChange: false,
  });
  const { permissions: granted, known } = usePermissions();

  const sections = useMemo(() => {
    const translated = NAV_SECTIONS.map((section) => ({
      label: section.label,
      items: section.items.map(({ i18nKey, ...rest }) => ({
        ...rest,
        label: t(i18nKey),
        badge:
          rest.to === "/notifications" && unseen?.count
            ? unseen.count
            : undefined,
      })),
    }));
    // Unfiltered until the grant list has loaded — same fail-open rule as
    // RequirePermission: a moment of extra nav beats a flash of empty nav.
    return known ? filterByPermissions(translated, granted) : translated;
  }, [t, unseen?.count, granted, known]);

  // Breadcrumb trail
  const segments = location.pathname.split("/").filter(Boolean);
  const crumbs = [
    { label: t("nav.dashboard"), path: "/dashboard" },
    ...segments
      .map((_, i) => "/" + segments.slice(0, i + 1).join("/"))
      .filter((path) => PAGE_META[path] && path !== "/dashboard")
      .map((path) => ({ label: t(PAGE_META[path].i18nKey), path })),
  ];

  const go = (item: NavItem) => {
    if (item.soon) {
      notify.info(`${item.label} — coming soon.`);
      return;
    }
    if (item.to) {
      navigate(item.to);
      closeNav();
    }
  };

  const handleLogout = () => {
    dispatch(logout());
    dispatch(baseApi.util.resetApiState());
    navigate("/");
  };

  const displayName = user?.name?.en || user?.username || "";
  const initials = displayName
    ? displayName
        .split(/\s+/)
        .map((s) => s[0])
        .join("")
        .toUpperCase()
        .slice(0, 2)
    : "?";

  return (
    <>
      {/* First focusable element on the page, so a keyboard user can bypass
          the nav instead of tabbing through it on every navigation. */}
      <SkipLink />
    <AppShell
      header={{ height: 74 }}
      navbar={{
        width: sidebarCollapsed ? 72 : 264,
        breakpoint: "sm",
        // Mobile has its own Drawer below — AppShell's built-in mobile
        // navbar takes over the full viewport width, which felt like it
        // swallowed the page. Always collapsed here on mobile.
        collapsed: { mobile: true },
      }}
      padding="lg"
    >
      <AppShell.Header
        style={{
          background: "var(--mantine-color-body)",
          borderBottom: "1px solid var(--mantine-color-gray-2)",
        }}
      >
        <AppHeader
          onToggleNav={toggleNav}
          onToggleSidebar={toggleSidebar}
          navOpened={navOpened}
          breadcrumbs={crumbs}
          onNavigate={navigate}
          onLogout={handleLogout}
          userName={displayName || t("app.name")}
          userInitials={initials}
          supportedLanguages={SUPPORTED_LANGUAGES}
          onNotificationsClick={() => navigate("/notifications")}
          notificationCount={unseen?.count}
        />
      </AppShell.Header>

      <AppShell.Navbar
        p={0}
        style={{
          overflow: "hidden",
          transition: "width 200ms ease",
          background: "var(--mantine-color-body)",
          borderRight: "1px solid var(--mantine-color-gray-2)",
        }}
      >
        <AppSidebar
          navItems={sections}
          collapsed={sidebarCollapsed}
          activePath={location.pathname}
          onToggleCollapse={toggleSidebar}
          onNavigate={go}
          brandName={t("app.name")}
          brandSubtitle={t("app.authority")}
          brandLogo={<BrandMark size={32} />}
        />
      </AppShell.Navbar>

      <AppShell.Main id={MAIN_CONTENT_ID}>
        <div key={location.pathname} className="ema-page-enter">
          <Outlet />
        </div>
      </AppShell.Main>

      {/* Mobile nav: a proper Drawer (sized, backdrop, closes on outside
          click) instead of AppShell's full-width mobile navbar. Mirrors the
          landing page's mobile menu. */}
      <Drawer
        opened={navOpened}
        onClose={closeNav}
        hiddenFrom="sm"
        size="75%"
        padding={0}
        withCloseButton={false}
      >
        <AppSidebar
          navItems={sections}
          collapsed={false}
          activePath={location.pathname}
          onToggleCollapse={toggleSidebar}
          onNavigate={go}
          brandName={t("app.name")}
          brandSubtitle={t("app.authority")}
          brandLogo={<BrandMark size={32} />}
        />
      </Drawer>
    </AppShell>
    </>
  );
}
