import type { LucideIcon } from "lucide-react";
import {
  CalendarDaysIcon,
  LayoutDashboardIcon,
  Building2Icon,
  PackageIcon,
  SparklesIcon,
  UsersIcon,
} from "lucide-react";
import { UserRole } from "@/types/auth";
import type { AccessCheck } from "@/types/rbac";
import { ROUTES } from "@/lib/constants/routes";
import { resolveRouteAccess } from "@/lib/constants/route-access";

export interface NavItem {
  /** Dictionary key resolved through useTranslation() — also used as the route/header title */
  titleKey: string;
  href: string;
  icon: LucideIcon;
  /** Show this item in the mobile bottom navigation (keep ≤ 5 per role) */
  inBottomNav?: boolean;
  /**
   * Optional permission/role/panel gate. When set, the item is only shown if the
   * user passes the check (see `filterNavByAccess`). Items WITHOUT a gate always
   * show for their role: the per-role lists below are already curated to match
   * the backend's `@Roles` reality, so leaving existing items ungated preserves
   * today's behavior. Add a gate to auto-trim an item for a reduced custom role
   * once the backend returns real per-user permissions.
   */
  access?: AccessCheck;
}

/**
 * Single source of truth for role-based navigation. The sidebar, the header
 * title, and the mobile bottom nav all read from here — adding a new screen
 * for a role means adding one entry to that role's list, nothing else.
 *
 * Ordering matters: the primary/home item must come FIRST in each list — the
 * bottom nav relies on plain DOM order so `dir="rtl"` puts it at the far
 * right in Arabic automatically (design rule: no hardcoded sides).
 */
export const NAV_CONFIG: Record<UserRole, NavItem[]> = {
  [UserRole.ADMIN_SUPER]: [
    {
      titleKey: "dashboard.title",
      href: ROUTES.ADMIN.DASHBOARD,
      icon: LayoutDashboardIcon,
      inBottomNav: true,
    },
    {
      titleKey: "providers.title",
      href: ROUTES.ADMIN.PROVIDERS,
      icon: Building2Icon,
      inBottomNav: true,
    },
    {
      titleKey: "catalog.title",
      href: ROUTES.ADMIN.CATALOG,
      icon: PackageIcon,
      inBottomNav: true,
    },
    {
      titleKey: "customers.title",
      href: ROUTES.ADMIN.CUSTOMERS,
      icon: UsersIcon,
      inBottomNav: true,
    },
  ],
  [UserRole.ADMIN_SUPPORT]: [
    {
      titleKey: "dashboard.title",
      href: ROUTES.ADMIN.DASHBOARD,
      icon: LayoutDashboardIcon,
      inBottomNav: true,
    },
    {
      titleKey: "providers.title",
      href: ROUTES.ADMIN.PROVIDERS,
      icon: Building2Icon,
      inBottomNav: true,
    },
    {
      titleKey: "catalog.title",
      href: ROUTES.ADMIN.CATALOG,
      icon: PackageIcon,
      inBottomNav: true,
    },
  ],
  [UserRole.PROVIDER_OWNER]: [
    {
      titleKey: "dashboard.title",
      href: ROUTES.SUPPLIER.DASHBOARD,
      icon: LayoutDashboardIcon,
      inBottomNav: true,
    },
    {
      titleKey: "schedule.title",
      href: ROUTES.SUPPLIER.SCHEDULE,
      icon: CalendarDaysIcon,
      inBottomNav: true,
    },
    {
      titleKey: "catalog.myServices.title",
      href: ROUTES.SUPPLIER.SERVICES,
      icon: SparklesIcon,
      inBottomNav: true,
    },
    {
      titleKey: "providers.packages.title",
      href: ROUTES.SUPPLIER.PACKAGES,
      icon: PackageIcon,
      inBottomNav: true,
    },
  ],
  [UserRole.PROVIDER_MANAGER]: [
    {
      titleKey: "dashboard.title",
      href: ROUTES.SUPPLIER.DASHBOARD,
      icon: LayoutDashboardIcon,
      inBottomNav: true,
    },
    {
      titleKey: "schedule.title",
      href: ROUTES.SUPPLIER.SCHEDULE,
      icon: CalendarDaysIcon,
      inBottomNav: true,
    },
    {
      titleKey: "catalog.myServices.title",
      href: ROUTES.SUPPLIER.SERVICES,
      icon: SparklesIcon,
      inBottomNav: true,
    },
  ],
  // No services entry: `/catalog/provider/*` is @Roles(PROVIDER_OWNER,
  // PROVIDER_MANAGER) backend-side, so a technician would only get a 403.
  [UserRole.PROVIDER_TECHNICIAN]: [
    {
      titleKey: "dashboard.title",
      href: ROUTES.SUPPLIER.DASHBOARD,
      icon: LayoutDashboardIcon,
      inBottomNav: true,
    },
    {
      titleKey: "schedule.title",
      href: ROUTES.SUPPLIER.SCHEDULE,
      icon: CalendarDaysIcon,
      inBottomNav: true,
    },
  ],
  // Intentionally empty forever: the web panel serves provider + admin roles
  // only. Customers use the separate mobile app — never add routes here.
  [UserRole.CUSTOMER]: [],
};

export function getNavForRole(role: UserRole): NavItem[] {
  return NAV_CONFIG[role] ?? [];
}

/**
 * The role's landing/dashboard route — its first nav item (the home item is
 * always first per the ordering rule), or the login route if it has none.
 * Used as the default redirect target by `<RouteGuard>`.
 */
export function getDashboardPath(role: UserRole): string {
  return getNavForRole(role)[0]?.href ?? ROUTES.AUTH.LOGIN;
}

/**
 * Drop nav items the user can't access. Each item's gate is its explicit
 * `access` override, else the shared route gate from `ROUTE_ACCESS` (so the
 * sidebar and `proxy.ts` enforce the exact same rule). Ungated items always
 * pass. Pass the `check` fn from `usePermissions`.
 */
export function filterNavByAccess(
  items: NavItem[],
  check: (access: AccessCheck) => boolean,
): NavItem[] {
  return items.filter((item) => {
    const access = item.access ?? resolveRouteAccess(item.href);
    return !access || check(access);
  });
}

/**
 * Longest-prefix match of the current pathname against the role's nav items.
 * Used by the header for the route title, and to decide whether the mobile
 * back button shows (sub-routes of an item get one, top-level items don't).
 */
export function findActiveNavItem(
  role: UserRole,
  pathname: string,
): NavItem | null {
  let best: NavItem | null = null;
  for (const item of getNavForRole(role)) {
    if (pathname === item.href || pathname.startsWith(item.href + "/")) {
      if (!best || item.href.length > best.href.length) best = item;
    }
  }
  return best;
}
