"use client"

import Link from "next/link"
import { usePathname } from "next/navigation"
import { useTranslation } from "react-i18next"
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible"
import { ScrollArea } from "@/components/ui/scroll-area"
import {
  Sidebar,
  SidebarContent,
  SidebarFooter,
  SidebarGroup,
  SidebarGroupContent,
  SidebarHeader,
  SidebarMenu,
  SidebarMenuButton,
  SidebarMenuItem,
  SidebarMenuSub,
  SidebarMenuSubButton,
  SidebarMenuSubItem,
  SidebarRail,
  SidebarSeparator,
  useSidebar,
} from "@/components/ui/sidebar"
import { RiArrowRightSLine, RiExternalLinkLine } from "@remixicon/react"
import { getIconComponent } from "@/lib/icon-map"
import navs from "@/config/navs"
import type { NavItem } from "@/types/app-config"
import { usePermissions } from "@/hooks/use-permissions"
import { useFirstAccessibleDashboardRoute } from "@/hooks/use-first-accessible-dashboard-route"
import { canAccessDashboardRoute } from "@/lib/dashboard-route-meta"
import { SidebarVersion } from "@/components/sidebars/version"
import { useDirection } from "@/components/ui/direction"
import { getThemeManifest } from "@/lib/theme/manifest"
import { withUtm } from "@/lib/utm"
import { ThemeLogo } from "@/components/theme/logo"

const theme = getThemeManifest()
const APP_NAME = theme.brand.name

function NavIcon({ name }: { name?: string }) {
  const Icon = getIconComponent(name)
  if (!Icon) return null
  // Icon from static map lookup; rule flags dynamic lookup as "component during render"
  return (
    // eslint-disable-next-line react-hooks/static-components -- icon from static map
    <Icon className="size-4 shrink-0" aria-hidden />
  )
}

function hasChildren(item: NavItem) {
  return Array.isArray(item.children) && item.children.length > 0
}

function isExternal(item: NavItem) {
  return Boolean(item.target) || /^https?:/i.test(item.to ?? "")
}

function normalizedTo(item: NavItem) {
  return item.to ?? "/"
}

export function AppSidebar() {
  const { t } = useTranslation()
  const pathname = usePathname()
  const { state } = useSidebar()
  const isCollapsed = state === "collapsed"
  const dir = useDirection()
  const brandInitial = APP_NAME.charAt(0).toUpperCase() ?? "R"

  const { isAdmin, canAccessPath, hasResolvedAdmin, hasFetchedPolicy, isLoading } = usePermissions()
  const { route: homeRoute } = useFirstAccessibleDashboardRoute()
  const isPermissionsReady = hasResolvedAdmin && (isAdmin || (!isLoading && hasFetchedPolicy))

  if (!isPermissionsReady) {
    return null
  }

  const visibleNavs = navs.flatMap((nav) => {
    if (nav.type === "divider") {
      return [nav]
    }

    let visibleChildren: NavItem[] = []
    if (nav.children?.length) {
      visibleChildren = nav.children.filter((child) => {
        if (!child.to || isExternal(child)) return true
        if (!canAccessDashboardRoute(child.to, { isAdmin, canAccessPath })) return false
        return true
      })
      if (visibleChildren.length === 0 && !nav.to) return []
    } else {
      if (nav.to && !isExternal(nav) && !canAccessDashboardRoute(nav.to, { isAdmin, canAccessPath })) return []
    }

    const navItem = { ...nav }
    if (visibleChildren.length > 0) {
      navItem.children = visibleChildren
    } else {
      delete navItem.children
    }

    return [navItem]
  })

  const navGroups: NavItem[][] = []
  let current: NavItem[] = []

  for (let index = 0; index < visibleNavs.length; index++) {
    const nav = visibleNavs[index]
    if (!nav) continue

    if (nav.type === "divider") {
      const hasItemsBefore = current.length > 0
      const hasItemsAfter = visibleNavs.slice(index + 1).some((item) => item.type !== "divider")
      if (hasItemsBefore && hasItemsAfter) {
        navGroups.push(current)
        current = []
      }
      continue
    }

    current.push(nav)
  }

  if (current.length > 0) {
    navGroups.push(current)
  }

  const isRouteActive = (item: NavItem): boolean => {
    if (hasChildren(item)) {
      return item.children!.some((child) => isRouteActive(child))
    }
    if (!item.to || isExternal(item)) return false
    // Root path "/" must match exactly; otherwise "/browser" etc. would match via startsWith("/")
    if (item.to === "/") {
      return pathname === "/"
    }
    return pathname.startsWith(item.to)
  }

  const getLabel = (item: NavItem) => t(item.label)

  return (
    <Sidebar
      collapsible="icon"
      side={dir === "rtl" ? "right" : "left"}
      className="**:data-[sidebar=menu-button]:text-start! **:data-[sidebar=menu-sub-button]:text-start!"
    >
      <SidebarHeader>
        <Link href={homeRoute ?? "/"} className="flex items-center gap-3">
          {isCollapsed ? (
            <div className="flex size-8 items-center justify-center rounded-none bg-primary text-sm font-semibold text-primary-foreground">
              <span>{brandInitial}</span>
            </div>
          ) : (
            <div className="flex min-w-0 items-baseline gap-2 px-3 py-4">
              <ThemeLogo width={96} height={16} className="shrink-0" alt={APP_NAME} priority />
            </div>
          )}
        </Link>
      </SidebarHeader>

      <SidebarContent>
        <ScrollArea className="flex-1 pe-1">
          <div className="flex flex-col gap-4">
            {navGroups.map((group, groupIndex) => (
              <SidebarGroup key={groupIndex} className="gap-4 py-0">
                <SidebarGroupContent>
                  <SidebarMenu>
                    {group.map((item) => (
                      <Collapsible
                        key={item.label}
                        defaultOpen={hasChildren(item) && isRouteActive(item)}
                        className="group/collapsible"
                        render={
                          hasChildren(item) ? (
                            <SidebarMenuItem>
                              <CollapsibleTrigger
                                render={
                                  <SidebarMenuButton
                                    isActive={isRouteActive(item)}
                                    tooltip={getLabel(item)}
                                    className="gap-3"
                                  >
                                    <NavIcon name={item.icon} />
                                    <span className="flex-1 truncate">{getLabel(item)}</span>
                                    <RiArrowRightSLine
                                      className="size-4 shrink-0 transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90"
                                      aria-hidden
                                    />
                                  </SidebarMenuButton>
                                }
                              />
                              <CollapsibleContent>
                                <SidebarMenuSub className="border-l-0 border-s rtl:-translate-x-px">
                                  {item.children!.map((child) => (
                                    <SidebarMenuSubItem key={child.label}>
                                      {isExternal(child) ? (
                                        <SidebarMenuSubButton
                                          size="sm"
                                          render={
                                            <a
                                              href={withUtm(normalizedTo(child), "sidebar")}
                                              target="_blank"
                                              rel="noopener noreferrer"
                                              className="flex w-full items-center gap-2"
                                            >
                                              <NavIcon name={child.icon} />
                                              <span className="truncate">{getLabel(child)}</span>
                                              <RiExternalLinkLine
                                                className="ms-auto size-3 text-muted-foreground"
                                                aria-hidden
                                              />
                                            </a>
                                          }
                                        />
                                      ) : (
                                        <SidebarMenuSubButton
                                          size="sm"
                                          isActive={isRouteActive(child)}
                                          render={
                                            <Link href={normalizedTo(child)} className="flex w-full items-center gap-2">
                                              <NavIcon name={child.icon} />
                                              <span className="truncate">{getLabel(child)}</span>
                                            </Link>
                                          }
                                        />
                                      )}
                                    </SidebarMenuSubItem>
                                  ))}
                                </SidebarMenuSub>
                              </CollapsibleContent>
                            </SidebarMenuItem>
                          ) : (
                            <SidebarMenuItem>
                              {isExternal(item) ? (
                                <SidebarMenuButton
                                  tooltip={getLabel(item)}
                                  render={
                                    <a
                                      href={withUtm(normalizedTo(item), "sidebar")}
                                      target="_blank"
                                      rel="noopener noreferrer"
                                      className="flex w-full items-center gap-3"
                                    >
                                      <NavIcon name={item.icon} />
                                      <span className="flex-1 truncate">{getLabel(item)}</span>
                                      <RiExternalLinkLine className="size-3.5 text-muted-foreground" aria-hidden />
                                    </a>
                                  }
                                />
                              ) : (
                                <SidebarMenuButton
                                  isActive={isRouteActive(item)}
                                  tooltip={getLabel(item)}
                                  render={
                                    <Link href={normalizedTo(item)} className="flex w-full items-center gap-3">
                                      <NavIcon name={item.icon} />
                                      <span className="flex-1 truncate">{getLabel(item)}</span>
                                    </Link>
                                  }
                                />
                              )}
                            </SidebarMenuItem>
                          )
                        }
                      />
                    ))}
                  </SidebarMenu>
                </SidebarGroupContent>
                {groupIndex !== navGroups.length - 1 ? <SidebarSeparator className="mx-2" /> : null}
              </SidebarGroup>
            ))}
          </div>
        </ScrollArea>
      </SidebarContent>

      <SidebarFooter className="mt-auto px-2 pb-2">
        <SidebarVersion appName={APP_NAME} />
      </SidebarFooter>

      <SidebarRail />
    </Sidebar>
  )
}
