import { AppShellSection, Box } from "@mantine/core";
import {
  IconChartPie,
  IconMailForward,
  IconDashboard,
  IconReportAnalytics,
  IconShieldLock,
  IconTag,
  IconUserOff,
  IconUserPlus,
} from "@tabler/icons-react";
import { useEffect, useState } from "react";
import { Outlet, useLocation, useSearchParams } from "react-router";
import PageHeader from "@/layouts/shared/page.header";
import { PromoThemeShell } from "@/routes/promo-code-campaigns/_components/PromoThemeShell";
import { useRoleAccess } from "@/hooks/useRoleAccess";

/*
 * Routes that opt into the promo appearance theme.
 *
 * An allowlist rather than "everything except KCGM", so the opt-in stays
 * explicit. KCGM is excluded outright — it ships its own styling and must be
 * left alone. The access list is excluded too: it is a permissions screen with
 * no charts, so the accent would only tint it for no benefit.
 */
const THEMED_PREFIXES = [
  "/admin/promo-codes",
  "/admin/promo-code-campaigns",
  "/admin/promo-code-bookings",
  "/admin/contact-completeness",
  "/admin/export-requests",
  "/admin/promo-access-roles",
  "/admin/member-referrals",
  "/admin/reports",
  "/admin/account-deletion",
] as const;

/*
 * Sub-pages that belong under a tab but have no tab of their own.
 *
 * The bookings page is reached from the Campaigns dashboard rather than the nav,
 * so nothing in LINKS matches its path. Without this it fell through to the
 * `-1 -> 0` fallback and highlighted whichever tab happened to be first — KCGM —
 * which told the user they were somewhere they had never been.
 */
const PARENT_TAB: Record<string, string> = {
  "/admin/promo-code-bookings": "/admin/promo-code-campaigns",
  "/admin/contact-completeness": "/admin/promo-code-campaigns",
  // Reached from the Access List rather than the nav, so it highlights that tab.
  "/admin/promo-access-roles": "/admin/access-list",
};

const PromoCodesLayout = () => {
  const [activeIndex, setActiveIndex] = useState(0);
  const { pathname } = useLocation();
  const [searchParams] = useSearchParams();
  const from = searchParams.get("from");
  const { checkClientAccess, isSuperAdmin } = useRoleAccess();
  const canViewReports = checkClientAccess("read", "campaign-reports");
  const canViewAccessList = checkClientAccess("read", "promocode-access-list");
  const canViewKcgm = checkClientAccess("read", "kcgm");
  const canViewCampaigns = checkClientAccess("read", "promo-code-campaigns");
  const canViewPromoCodes = checkClientAccess("read", "promo-codes");

  const LINKS = [
    ...(canViewKcgm
      ? [
          {
            Icon: IconDashboard,
            label: "KCGM Dashboard",
            href: "/admin/kcgm",
          },
        ]
      : []),
    ...(canViewCampaigns
      ? [
          {
            Icon: IconChartPie,
            label: "Campaigns",
            href: "/admin/promo-code-campaigns",
          },
        ]
      : []),
    ...(canViewPromoCodes
      ? [
          {
            Icon: IconTag,
            label: "Karma Subito Promo Code",
            href: "/admin/promo-codes",
          },
        ]
      : []),
    ...(canViewPromoCodes || canViewCampaigns
      ? [
          {
            Icon: IconUserPlus,
            label: "Member Referrals",
            href: "/admin/member-referrals",
          },
        ]
      : []),
    ...(canViewReports
      ? [
          {
            Icon: IconReportAnalytics,
            label: "Reports",
            href: "/admin/reports",
          },
        ]
      : []),
    /*
     * Export approvals — super admin only.
     *
     * Everyone can *submit* a request from any export button, but only a super
     * admin works the queue, so only they get the tab. A non-admin can still
     * reach the URL and will see their own requests read-only.
     */
    ...(isSuperAdmin()
      ? [
          {
            Icon: IconMailForward,
            label: "Export Approvals",
            href: "/admin/export-requests",
          },
        ]
      : []),
    /*
     * Account deletion — super admin only, same as Export Approvals above.
     *
     * It writes an account's status to Viewpoint, the system of record, so it is
     * not delegated through a feature role. A non-super-admin who reaches the URL
     * is redirected by the page's loader, and core refuses the endpoints outright.
     */
    ...(isSuperAdmin()
      ? [
          {
            Icon: IconUserOff,
            label: "Account Deletion",
            href: "/admin/account-deletion",
          },
        ]
      : []),
    ...(canViewAccessList
      ? [
          {
            Icon: IconShieldLock,
            label: "Access List",
            href: "/admin/access-list",
          },
        ]
      : []),
  ];

  useEffect(() => {
    /*
     * A path resolves to its own tab, or to its parent's when it has none.
     *
     * Searching LINKS by href rather than by a fixed index matters because LINKS
     * is permission-filtered — the same tab sits at a different index depending
     * on what the viewer can see.
     */
    const tabFor = (path: string | null): number => {
      if (!path) return -1;
      const direct = LINKS.findIndex((item) => path.startsWith(item.href));
      if (direct !== -1) return direct;
      const parent = Object.entries(PARENT_TAB).find(([child]) =>
        path.startsWith(child),
      )?.[1];
      return parent
        ? LINKS.findIndex((item) => parent.startsWith(item.href))
        : -1;
    };

    // `from` wins so a deep page can say which tab it belongs to.
    const fromIndex = tabFor(from);
    const resolved = fromIndex !== -1 ? fromIndex : tabFor(pathname);
    /*
     * -1 means "no tab active", not "the first tab".
     *
     * Defaulting to 0 was the bug: an unrecognised path silently highlighted the
     * first tab. Showing nothing selected is honest, and makes the next unmapped
     * page obvious instead of quietly wrong.
     */
    setActiveIndex(resolved);
  }, [pathname, from]);

  // Note both prefixes are listed explicitly: "/admin/promo-code-campaigns"
  // would also match a "/admin/promo-code" prefix, so neither can stand in for
  // the other.
  const themed = THEMED_PREFIXES.some((prefix) => pathname.startsWith(prefix));

  const content = (
    <Box py={20} px={28}>
      <Outlet />
    </Box>
  );

  return (
    <AppShellSection>
      <PageHeader
        links={LINKS}
        activeIndex={activeIndex}
        setActiveIndex={setActiveIndex}
      />
      {themed ? <PromoThemeShell>{content}</PromoThemeShell> : content}
    </AppShellSection>
  );
};

export default PromoCodesLayout;
