'use client'

import { Slot } from '@radix-ui/react-slot'
import { cva, type VariantProps } from 'class-variance-authority'
import * as React from 'react'
import {
  SvgHamburgerMenu1,
  SvgTaillessLineArrowDown1,
} from '@chainlink/blocks-icons'
import { useIsMobile } from '../../../hooks'
import { SvgArrowExpandWindow, type SvgIcon } from '../../../icons'
import { cn } from '../../../utils'
import { Button } from '../../Button'
import { Drawer, DrawerContent, DrawerHandle } from '../../Drawer'
import { Input } from '../../Input'
import { Separator } from '../../Separator'
import { typographyVariants } from '../../Typography'
import { ChainlinkIcon, ChainlinkLogoText } from './ChainlinkLogo'
import { defaultNavItems } from './config'
import {
  collectAllPaths,
  isPathActive,
  normalizeNavItems,
  normalizePathForMatching,
} from './utils'

const SIDEBAR_COOKIE_NAME = 'sidebar_state'
const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7
const SIDEBAR_WIDTH = '224px'
export const SIDEBAR_WIDTH_ICON = '73px'
const SIDEBAR_KEYBOARD_SHORTCUT = 'b'

type SidebarLinkProps = {
  href: string
  children: React.ReactNode
  onClick?: (event: React.MouseEvent<HTMLElement>) => void
  className?: string
  tabIndex?: number
  onKeyDown?: (event: React.KeyboardEvent<HTMLElement>) => void
  'data-sidebar'?: string
  'data-active'?: boolean | string
  style?: React.CSSProperties | undefined
}

type SidebarContextProps = {
  state: 'expanded' | 'collapsed'
  open: boolean
  setOpen: (open: boolean) => void
  openMobile: boolean
  setOpenMobile: (open: boolean) => void
  isMobile: boolean
  toggleSidebar: () => void
  openSubmenu: string | null
  setOpenSubmenu: (id: string | null) => void
  activeItem: string | null
  setActiveItem: (item: string | null) => void
  activeParentTitle?: string
  renderLink: (props: SidebarLinkProps) => React.ReactNode
  navItems?: SidebarNavItem[][]
  allPaths: Set<string>
}

const SidebarContext = React.createContext<SidebarContextProps | null>(null)

function useSidebar() {
  const context = React.useContext(SidebarContext)
  if (!context) {
    throw new Error('useSidebar must be used within a SidebarProvider.')
  }

  return context
}

function useSidebarContext() {
  return React.useContext(SidebarContext)
}

type SidebarNavItem = {
  title: string
  icon?: React.ComponentType<{ color?: SvgIcon['color'] }>
  href?: string
  items?: { title: string; href: string; external?: boolean }[]
  onClick?: () => void
  external?: boolean
}

type SidebarProviderProps = React.ComponentProps<'div'> & {
  defaultOpen?: boolean
  open?: boolean
  onOpenChange?: (open: boolean) => void
  currentPath?: string | null
  baseUrl?: string
  navItems?: SidebarNavItem[][]
  renderLink: (props: SidebarLinkProps) => React.ReactNode
  ref?: React.Ref<HTMLDivElement>
}

const SidebarProvider = ({
  defaultOpen = false,
  open: openProp,
  onOpenChange: setOpenProp,
  className,
  currentPath,
  baseUrl,
  navItems = defaultNavItems,
  style,
  children,
  ref,
  renderLink,
  ...props
}: SidebarProviderProps) => {
  const isMobile = useIsMobile() ?? false
  const [openMobile, setOpenMobile] = React.useState(false)

  // Normalize navItems based on baseUrl
  const normalizedNavItems = React.useMemo(
    () => normalizeNavItems(navItems, baseUrl),
    [navItems, baseUrl],
  )

  // Collect all defined paths for specificity checking
  const allPaths = React.useMemo(
    () => collectAllPaths(normalizedNavItems),
    [normalizedNavItems],
  )

  const [activeItem, setActiveItem] = React.useState<string | null>(
    currentPath ? normalizePathForMatching(currentPath) : null,
  )

  // Sync activeItem with currentPath prop when it changes
  React.useEffect(() => {
    if (currentPath !== undefined) {
      setActiveItem(normalizePathForMatching(currentPath))
    }
  }, [currentPath])

  // Calculate activeParentTitle and openSubmenu based on activeItem and specific matching rules
  const activeParentTitle = React.useMemo(() => {
    if (!activeItem) return undefined

    for (const group of normalizedNavItems) {
      for (const item of group) {
        // Check if any child matches the active item
        if (item.items) {
          for (const subItem of item.items) {
            if (
              subItem.href &&
              isPathActive(activeItem, subItem.href, allPaths)
            ) {
              return item.title
            }
          }

          // If no child matched, check if the parent itself matches
          // This handles cases where we are at a path that matches the parent's href (e.g. /)
          // but doesn't match any specific child path
          if (item.href && isPathActive(activeItem, item.href, allPaths)) {
            return item.title
          }
        }
      }
    }

    return undefined
  }, [activeItem, normalizedNavItems, allPaths])

  const [openSubmenu, setOpenSubmenu] = React.useState<string | null>(
    activeParentTitle ?? null,
  )

  // Sync openSubmenu when activeParentTitle changes
  React.useEffect(() => {
    if (activeParentTitle !== undefined) {
      setOpenSubmenu(activeParentTitle)
    }
  }, [activeParentTitle])

  // This is the internal state of the sidebar.
  // We use openProp and setOpenProp for control from outside the component.
  const [_open, _setOpen] = React.useState(defaultOpen)
  const open = openProp ?? _open
  const setOpen = React.useCallback(
    (value: boolean | ((value: boolean) => boolean)) => {
      const openState = typeof value === 'function' ? value(open) : value
      if (setOpenProp) {
        setOpenProp(openState)
      } else {
        _setOpen(openState)
      }

      // This sets the cookie to keep the sidebar state.
      document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`
    },
    [setOpenProp, open],
  )

  // Helper to toggle the sidebar.
  const toggleSidebar = React.useCallback(() => {
    return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open)
  }, [isMobile, setOpen, setOpenMobile])

  // Adds a keyboard shortcut to toggle the sidebar.
  React.useEffect(() => {
    const handleKeyDown = (event: KeyboardEvent) => {
      if (
        event.key === SIDEBAR_KEYBOARD_SHORTCUT &&
        (event.metaKey || event.ctrlKey)
      ) {
        event.preventDefault()
        toggleSidebar()
      }
    }

    window.addEventListener('keydown', handleKeyDown)
    return () => window.removeEventListener('keydown', handleKeyDown)
  }, [toggleSidebar])

  // We add a state so that we can do data-state="expanded" or "collapsed".
  // This makes it easier to style the sidebar with Tailwind classes.
  const state = open ? 'expanded' : 'collapsed'

  // Update activeItem when active prop changes
  React.useEffect(() => {
    if (currentPath !== undefined) {
      setActiveItem(currentPath)
    }
  }, [currentPath])

  const contextValue = React.useMemo<SidebarContextProps>(
    () => ({
      state,
      open,
      setOpen,
      isMobile,
      openMobile,
      setOpenMobile,
      toggleSidebar,
      openSubmenu,
      setOpenSubmenu,
      activeItem,
      setActiveItem,
      activeParentTitle,
      renderLink,
      navItems: normalizedNavItems,
      allPaths,
    }),
    [
      state,
      open,
      setOpen,
      isMobile,
      openMobile,
      setOpenMobile,
      toggleSidebar,
      openSubmenu,
      setOpenSubmenu,
      activeItem,
      setActiveItem,
      activeParentTitle,
      renderLink,
      normalizedNavItems,
      allPaths,
    ],
  )

  return (
    <SidebarContext.Provider value={contextValue}>
      <div
        data-slot="sidebar-wrapper"
        style={
          {
            '--sidebar-width': SIDEBAR_WIDTH,
            '--sidebar-width-icon': SIDEBAR_WIDTH_ICON,
            ...style,
          } as React.CSSProperties
        }
        className={cn(
          'group/sidebar-wrapper flex min-h-svh w-full overflow-x-hidden has-[[data-variant=inset]]:bg-background',
          className,
        )}
        ref={ref}
        {...props}
      >
        {children}
      </div>
    </SidebarContext.Provider>
  )
}
SidebarProvider.displayName = 'SidebarProvider'

type SidebarProps = React.ComponentProps<'div'> & {
  side?: 'left' | 'right'
  variant?: 'sidebar' | 'floating' | 'inset'
  collapsible?: 'offcanvas' | 'icon' | 'none'
  ref?: React.Ref<HTMLDivElement>
}

const Sidebar = ({
  side = 'left',
  variant = 'sidebar',
  collapsible = 'icon',
  className,
  children,
  ref,
  ...props
}: SidebarProps) => {
  const { isMobile, state, openMobile, setOpenMobile, setOpen } = useSidebar()

  const sidebarRef = React.useRef<HTMLDivElement>(null)
  const isCollapsed = state === 'collapsed'

  // Combine refs
  React.useImperativeHandle(ref, () => sidebarRef.current as HTMLDivElement)

  // Handle focus events for keyboard navigation on the entire sidebar
  React.useEffect(() => {
    const element = sidebarRef.current
    if (!element || isMobile) return

    const handleFocusIn = () => {
      // If sidebar is collapsed and focus enters, expand it
      if (isCollapsed) {
        setOpen(true)
      }
    }

    const handleFocusOut = (event: FocusEvent) => {
      // Check if focus is moving outside of the sidebar
      const relatedTarget = event.relatedTarget as Node | null
      // If relatedTarget is null, focus is leaving the document/window
      // If relatedTarget exists but is not contained in the sidebar, focus is leaving
      if (!relatedTarget || !element.contains(relatedTarget)) {
        // Use a small timeout to allow focus to settle, in case focus is moving
        // to another element within the sidebar
        setTimeout(() => {
          // Double-check: if the active element is not within the sidebar, collapse
          const activeElement = document.activeElement
          if (activeElement && !element.contains(activeElement)) {
            // Focus has left the sidebar, collapse it
            // But only if it's not already collapsed
            if (!isCollapsed) {
              setOpen(false)
            }
          }
        }, 0)
      }
    }

    element.addEventListener('focusin', handleFocusIn)
    element.addEventListener('focusout', handleFocusOut)

    return () => {
      element.removeEventListener('focusin', handleFocusIn)
      element.removeEventListener('focusout', handleFocusOut)
    }
  }, [isCollapsed, setOpen, isMobile])

  // Conditional returns after all hooks
  if (collapsible === 'none') {
    return (
      <div
        className={cn(
          'flex h-svh w-[--sidebar-width] flex-col',
          side === 'left' ? 'border-r' : 'border-l',
          className,
        )}
        ref={ref}
        {...props}
      >
        <div
          data-sidebar="sidebar"
          className="flex h-full flex-col bg-background text-foreground"
        >
          {children}
        </div>
      </div>
    )
  }

  if (isMobile) {
    return (
      <Drawer open={openMobile} onOpenChange={setOpenMobile}>
        <DrawerContent
          data-sidebar="sidebar"
          data-mobile="true"
          className="h-full max-h-[85%] w-full p-0 [&>button]:hidden"
        >
          <div className="flex h-full w-full flex-col">
            <DrawerHandle />
            {children}
          </div>
        </DrawerContent>
      </Drawer>
    )
  }

  const handleMouseEnter = () => {
    if (!isMobile && state === 'collapsed') {
      setOpen(true)
    }
  }

  const handleMouseLeave = () => {
    if (!isMobile && state === 'expanded') {
      // Check if OrgSwitcher is open by looking for open select content with org-switcher attribute
      const openOrgSwitcher = document.querySelector(
        '[data-slot="select-content"][data-state="open"][data-org-switcher="true"]',
      )
      if (openOrgSwitcher) {
        return
      }

      setOpen(false)
    }
  }

  return (
    <div
      ref={sidebarRef}
      className="group peer hidden text-foreground md:block"
      data-state={state}
      data-collapsible={state === 'collapsed' ? collapsible : ''}
      data-variant={variant}
      data-side={side}
      data-icon-mode={collapsible === 'icon' ? 'true' : 'false'}
      onMouseEnter={handleMouseEnter}
      onMouseLeave={handleMouseLeave}
    >
      <div
        className={cn(
          'absolute inset-y-0 z-[15] hidden h-svh w-[--sidebar-width] transition-[left,right,width] duration-100 ease-out md:flex',
          side === 'left'
            ? 'left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]'
            : 'right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]',
          // Adjust the padding for floating and inset variants.
          variant === 'floating' || variant === 'inset'
            ? 'p-3 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4)_+2px)]'
            : 'border-0 border-r border-solid border-border group-data-[collapsible=icon]:w-[--sidebar-width-icon]',
          variant === 'floating' && 'p-2',
          className,
        )}
        {...props}
      >
        <div
          data-sidebar="sidebar"
          className="flex h-full w-full flex-col bg-background group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:border-border group-data-[variant=floating]:shadow"
        >
          {children}
        </div>
      </div>
    </div>
  )
}
Sidebar.displayName = 'Sidebar'

type SidebarTriggerProps = React.ComponentProps<typeof Button> & {
  ref?: React.Ref<React.ElementRef<typeof Button>>
}

const SidebarTrigger = ({
  className,
  onClick,
  ref,
  ...props
}: SidebarTriggerProps) => {
  const { toggleSidebar } = useSidebar()

  return (
    <Button
      ref={ref}
      data-sidebar="trigger"
      variant="ghost"
      size="xs"
      className={cn('h-7 w-7', className)}
      onClick={(event) => {
        onClick?.(event)
        toggleSidebar()
      }}
      {...props}
    >
      <SvgHamburgerMenu1 width={16} height={16} />
      <span className="sr-only">Toggle Sidebar</span>
    </Button>
  )
}
SidebarTrigger.displayName = 'SidebarTrigger'

type SidebarRailProps = React.ComponentProps<'button'> & {
  ref?: React.Ref<HTMLButtonElement>
}

const SidebarRail = ({ className, ref, ...props }: SidebarRailProps) => {
  const { toggleSidebar } = useSidebar()

  return (
    <button
      ref={ref}
      data-sidebar="rail"
      aria-label="Toggle Sidebar"
      tabIndex={-1}
      onClick={toggleSidebar}
      title="Toggle Sidebar"
      className={cn(
        'absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] hover:after:bg-border group-data-[side=left]:-right-4 group-data-[side=right]:left-0 sm:flex',
        '[[data-side=left]_&]:cursor-w-resize [[data-side=right]_&]:cursor-e-resize',
        '[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize',
        'group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full group-data-[collapsible=offcanvas]:hover:bg-background',
        '[[data-side=left][data-collapsible=offcanvas]_&]:-right-2',
        '[[data-side=right][data-collapsible=offcanvas]_&]:-left-2',
        className,
      )}
      {...props}
    />
  )
}
SidebarRail.displayName = 'SidebarRail'

type SidebarInsetProps = React.ComponentProps<'div'> & {
  ref?: React.Ref<HTMLDivElement>
}

const SidebarInset = ({ className, ref, ...props }: SidebarInsetProps) => {
  return (
    <div
      ref={ref}
      className={cn(
        'relative z-[14] max-h-svh min-h-screen w-full overflow-y-scroll bg-background',
        'md:peer-data-[variant=inset]:m-2 md:peer-data-[state=collapsed]:peer-data-[variant=inset]:ml-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow',
        // Apply margin when sidebar is in icon mode based on side
        'md:peer-data-[icon-mode=true]:peer-data-[side=left]:ml-[--sidebar-width-icon]',
        'md:peer-data-[icon-mode=true]:peer-data-[side=right]:mr-[--sidebar-width-icon]',
        // Ensure content takes full width when sidebar is closed in offcanvas mode
        'md:peer-data-[state=collapsed]:peer-data-[collapsible=offcanvas]:peer-data-[side=right]:mr-0',
        className,
      )}
      {...props}
    />
  )
}
SidebarInset.displayName = 'SidebarInset'

type SidebarInputProps = React.ComponentProps<typeof Input> & {
  ref?: React.Ref<React.ElementRef<typeof Input>>
}

const SidebarInput = ({ className, ref, ...props }: SidebarInputProps) => {
  return (
    <Input
      ref={ref}
      data-sidebar="input"
      className={cn(
        'h-8 w-full bg-background shadow-none focus-visible:ring-2 focus-visible:ring-ring',
        className,
      )}
      {...props}
    />
  )
}
SidebarInput.displayName = 'SidebarInput'

type SidebarHeaderProps = React.ComponentProps<'div'> & {
  ref?: React.Ref<HTMLDivElement>
}

const SidebarHeader = ({ className, ref, ...props }: SidebarHeaderProps) => {
  return (
    <div
      ref={ref}
      data-sidebar="header"
      className={cn('flex-col gap-2 p-3 pb-0 pr-3.5', className)}
      {...props}
    />
  )
}
SidebarHeader.displayName = 'SidebarHeader'

type SidebarFooterProps = React.ComponentProps<'div'> & {
  ref?: React.Ref<HTMLDivElement>
}

const SidebarFooter = ({ className, ref, ...props }: SidebarFooterProps) => {
  return (
    <div
      ref={ref}
      data-sidebar="footer"
      className={cn('flex flex-col gap-2 p-3 pr-3.5', className)}
      {...props}
    />
  )
}
SidebarFooter.displayName = 'SidebarFooter'

type SidebarSeparatorProps = React.ComponentProps<typeof Separator> & {
  ref?: React.Ref<React.ElementRef<typeof Separator>>
}

const SidebarSeparator = ({
  className,
  ref,
  ...props
}: SidebarSeparatorProps) => {
  return (
    <div className="px-3">
      <Separator
        ref={ref}
        data-sidebar="separator"
        className={cn('w-full bg-border', className)}
        {...props}
      />
    </div>
  )
}
SidebarSeparator.displayName = 'SidebarSeparator'

type SidebarContentProps = React.ComponentProps<'div'> & {
  ref?: React.Ref<HTMLDivElement>
}

const SidebarContent = ({ className, ref, ...props }: SidebarContentProps) => {
  return (
    <div
      ref={ref}
      data-sidebar="content"
      className={cn(
        'relative flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden',
        className,
      )}
      {...props}
    >
      {props.children}
    </div>
  )
}
SidebarContent.displayName = 'SidebarContent'

type SidebarGroupProps = React.ComponentProps<'div'> & {
  ref?: React.Ref<HTMLDivElement>
}

const SidebarGroup = ({
  className,
  children,
  ref,
  ...props
}: SidebarGroupProps) => {
  return (
    <div
      ref={ref}
      data-sidebar="group"
      className={cn(
        'relative flex w-full min-w-0 flex-col p-4 pt-3 md:p-3',
        className,
      )}
      {...props}
    >
      {children}
    </div>
  )
}
SidebarGroup.displayName = 'SidebarGroup'

type SidebarGroupLabelProps = React.ComponentProps<'div'> & {
  asChild?: boolean
  ref?: React.Ref<HTMLDivElement>
}

const SidebarGroupLabel = ({
  className,
  asChild = false,
  ref,
  ...props
}: SidebarGroupLabelProps) => {
  const Comp = asChild ? Slot : 'div'

  return (
    <Comp
      ref={ref}
      data-sidebar="group-label"
      className={cn(
        'flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium text-muted-foreground outline-none ring-ring transition-[margin,opacity] duration-200 ease-linear focus-visible:bg-platform-navigation-hover focus-visible:outline-none [&>svg]:size-4 [&>svg]:shrink-0',
        'group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0',
        className,
      )}
      {...props}
    />
  )
}
SidebarGroupLabel.displayName = 'SidebarGroupLabel'

type SidebarGroupActionProps = React.ComponentProps<'button'> & {
  asChild?: boolean
  ref?: React.Ref<HTMLButtonElement>
}

const SidebarGroupAction = ({
  className,
  asChild = false,
  ref,
  ...props
}: SidebarGroupActionProps) => {
  const Comp = asChild ? Slot : 'button'

  return (
    <Comp
      ref={ref}
      data-sidebar="group-action"
      className={cn(
        'absolute right-3 top-3.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-foreground outline-none ring-ring transition-transform hover:bg-platform-navigation-hover hover:text-platform-navigation-hover-foreground focus-visible:bg-platform-navigation-hover focus-visible:text-platform-navigation-hover-foreground focus-visible:outline-none [&>svg]:size-4 [&>svg]:shrink-0',
        // Increases the hit area of the button on mobile.
        'after:absolute after:-inset-2 after:md:hidden',
        'group-data-[collapsible=icon]:hidden',
        className,
      )}
      {...props}
    />
  )
}
SidebarGroupAction.displayName = 'SidebarGroupAction'

type SidebarGroupContentProps = React.ComponentProps<'div'> & {
  ref?: React.Ref<HTMLDivElement>
}

const SidebarGroupContent = ({
  className,
  ref,
  ...props
}: SidebarGroupContentProps) => (
  <div
    ref={ref}
    data-sidebar="group-content"
    className={cn(
      'w-full text-sm [&_[data-sidebar="menu-button"]_span]:font-semibold [&_[data-sidebar="menu-button"]_span]:text-platform-navigation-foreground',
      '![data-sidebar="menu-button"]_svg]:text-platform-navigation-muted-foreground',
      '[&_[data-sidebar="menu-button"][data-active="true"]>span]:text-platform-navigation-active-foreground',
      className,
    )}
    {...props}
  />
)
SidebarGroupContent.displayName = 'SidebarGroupContent'

type SidebarMenuProps = React.ComponentProps<'ul'> & {
  ref?: React.Ref<HTMLUListElement>
}

const SidebarMenu = ({ className, ref, ...props }: SidebarMenuProps) => (
  <ul
    ref={ref}
    data-sidebar="menu"
    className={cn('flex w-full min-w-0 flex-col gap-4', className)}
    {...props}
  />
)
SidebarMenu.displayName = 'SidebarMenu'

type SidebarMenuSubItemProps = React.ComponentProps<'li'> & {
  ref?: React.Ref<HTMLLIElement>
}

const SidebarMenuSubItem = ({ ref, ...props }: SidebarMenuSubItemProps) => (
  <li
    className='[&_[data-sidebar="menu-sub-button"]]:text-platform-navigation-muted-foreground'
    ref={ref}
    {...props}
  />
)
SidebarMenuSubItem.displayName = 'SidebarMenuSubItem'

type SidebarMenuSubButtonProps = React.ComponentProps<'a'> & {
  href?: string
  title?: string
  parentTitle?: string
  external?: boolean
  ref?: React.Ref<HTMLAnchorElement>
}

const SidebarMenuSubButton = ({
  href,
  title,
  className,
  onClick,
  parentTitle,
  external = false,
  ref,
  ...props
}: SidebarMenuSubButtonProps) => {
  const {
    activeItem,
    setActiveItem,
    setOpenMobile,
    isMobile,
    renderLink,
    state,
    openSubmenu,
    allPaths,
  } = useSidebar()

  // Prevent focus when sidebar is collapsed OR when parent submenu is not open
  const isCollapsed = state === 'collapsed'
  const isParentSubmenuOpen = parentTitle ? openSubmenu === parentTitle : false
  const shouldBeFocusable = !isCollapsed && isParentSubmenuOpen

  const isActive = href ? isPathActive(activeItem || '', href, allPaths) : false

  const handleClick = () => {
    if (href) {
      // Handle navigation - set active optimistically only for internal links
      if (href.startsWith('/')) {
        setActiveItem(normalizePathForMatching(href))
      }

      // Close mobile sidebar for any navigation
      if (isMobile) {
        setOpenMobile(false)
      }
    }
  }

  const buttonClasses = cn(
    'text-platform-navigation-foreground',
    'flex h-12 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sm text-muted-foreground !outline-none ring-ring hover:text-platform-navigation-active-foreground focus-visible:bg-platform-navigation-hover focus-visible:shadow-none focus-visible:outline-none active:text-platform-navigation-active-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0',
    className,
  )

  // No href - render button (for onClick handlers)
  if (!href) {
    return (
      <button
        data-sidebar="menu-sub-button"
        data-active={isActive}
        className={buttonClasses}
        tabIndex={shouldBeFocusable ? undefined : -1}
        onClick={(e) => {
          handleClick()
          onClick?.(e as any)
        }}
      >
        <span
          style={{
            color: isActive
              ? 'var(--platform-navigation-active-foreground)'
              : 'var(--platform-navigation-foreground)',
          }}
        >
          {title}
        </span>
      </button>
    )
  }

  // Internal link - use renderLink
  if (href.startsWith('/')) {
    return renderLink({
      href,
      tabIndex: shouldBeFocusable ? undefined : -1,
      onClick: handleClick,
      'data-sidebar': 'menu-sub-button',
      'data-active': isActive,
      className: cn(
        '!outline-none focus-visible:bg-platform-navigation-hover focus-visible:outline-none',
        buttonClasses,
        isActive
          ? 'text-platform-navigation-active-foreground'
          : 'text-platform-navigation-foreground',
      ),
      style: {
        color: isActive
          ? 'var(--platform-navigation-active-foreground)'
          : 'var(--platform-navigation-foreground)',
      },
      children: title,
    })
  }

  // External link
  return (
    <a
      ref={ref}
      href={href}
      target={external ? '_blank' : undefined}
      rel="noopener noreferrer"
      data-sidebar="menu-sub-button"
      data-active={isActive}
      className={cn(buttonClasses, external && 'group/link w-full')}
      tabIndex={shouldBeFocusable ? undefined : -1}
      onClick={handleClick}
      {...props}
    >
      <span
        style={{
          color: isActive
            ? 'var(--platform-navigation-active-foreground)'
            : 'var(--platform-navigation-foreground)',
        }}
      >
        {title}
      </span>
      {external && (
        <SvgArrowExpandWindow
          width="16"
          height="16"
          color="platform-navigation-muted"
          className="ml-auto h-4 max-h-4 w-4 max-w-4 opacity-0 transition-opacity duration-150 group-hover/link:opacity-100"
          data-sidebar="external-link-icon"
        />
      )}
    </a>
  )
}
SidebarMenuSubButton.displayName = 'SidebarMenuSubButton'

type SidebarMenuSubProps = React.ComponentProps<'ul'> & {
  parentTitle?: string
  ref?: React.Ref<HTMLUListElement>
}

const SidebarMenuSub = ({
  className,
  parentTitle,
  ref,
  ...props
}: SidebarMenuSubProps) => {
  const [hoveredIndex, setHoveredIndex] = React.useState<number | null>(null)
  const { activeItem, openSubmenu, allPaths } = useSidebar()

  // Find the active index by looking at children's href prop
  const activeIndex = React.useMemo(() => {
    return React.Children.toArray(props.children).findIndex((child) => {
      if (React.isValidElement(child)) {
        // Look for SidebarMenuSubButton with matching href
        const subButton = React.Children.toArray(
          (child.props as any).children,
        ).find(
          (subChild) =>
            React.isValidElement(subChild) &&
            (subChild.props as any).href &&
            isPathActive(
              activeItem || '',
              (subChild.props as any).href,
              allPaths,
            ),
        )
        return !!subButton
      }
      return false
    })
  }, [props.children, activeItem, allPaths])

  const currentIndex = hoveredIndex ?? activeIndex

  // Determine if this submenu should be open based on parent title
  const isOpen = parentTitle ? openSubmenu === parentTitle : false

  // The content of the submenu is wrapped in a div to prevent margin collapse
  // and ensure the grid animation works correctly.
  return (
    <ul
      ref={ref}
      data-sidebar="menu-sub"
      data-state={isOpen ? 'open' : 'closed'}
      className={cn(
        'group grid list-none transition-[grid-template-rows] duration-200 ease-in-out data-[state=closed]:grid-rows-[0fr] data-[state=open]:grid-rows-[1fr]',
        className,
      )}
      {...props}
    >
      {/* Vertical line indicator - positioned outside overflow container */}
      {currentIndex >= 0 && (
        <div
          className="pointer-events-none absolute left-[23px] z-10 h-5 w-[3px] bg-brand duration-150 ease-in-out"
          style={{
            transform: `translateY(${currentIndex * 48 + 14}px)`,
          }}
        />
      )}
      <div
        className={cn(
          'ml-[23px] mr-[6px] flex min-w-0 translate-x-px flex-col overflow-hidden whitespace-nowrap border-b-0 border-l border-r-0 border-t-0 border-solid border-border pl-4 pr-0',
        )}
      >
        {React.Children.map(props.children, (child, index) => {
          if (React.isValidElement(child)) {
            return React.cloneElement(child, {
              onMouseEnter: () => setHoveredIndex(index),
              onMouseLeave: () => setHoveredIndex(null),
            } as any)
          }
          return child
        })}
      </div>
    </ul>
  )
}
SidebarMenuSub.displayName = 'SidebarMenuSub'

const sidebarMenuButtonVariants = cva(
  'peer/menu-button flex w-full items-center gap-3.5 overflow-hidden rounded-md p-3 text-left text-sm text-platform-navigation-foreground outline-none ring-ring transition-[width,height,padding] hover:bg-platform-navigation-hover focus-visible:bg-platform-navigation-hover focus-visible:outline-none active:bg-platform-navigation-hover disabled:pointer-events-none disabled:opacity-50 group-has-[[data-sidebar=menu-action]]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-platform-navigation-active !font-semibold data-[state=open]:hover:bg-platform-navigation-hover data-[state=open]:hover:text-platform-navigation-hover-foreground group-data-[collapsible=icon]:!size-12 py-3 px-3.5 [&>span:last-child]:truncate [&_svg]:size-5 [&_svg]:shrink-0 whitespace-nowrap h-12',
)

type SidebarMenuButtonProps = React.ComponentProps<'button'> &
  SidebarNavItem & {
    ref?: React.Ref<HTMLButtonElement>
  }

const SidebarMenuButton = ({
  title,
  href,
  icon,
  className,
  onClick,
  items,
  external = false,
  ref,
}: SidebarMenuButtonProps) => {
  const {
    openSubmenu,
    setOpenSubmenu,
    activeItem,
    setActiveItem,
    activeParentTitle,
    renderLink,
    setOpenMobile,
    state,
    setOpen,
    allPaths,
  } = useSidebar()

  const isCollapsed = state === 'collapsed'

  // Check if this item is active
  const hasSubmenu = !!items
  const isActive =
    (hasSubmenu && activeParentTitle === title) || // Parent is active if it contains the active child
    (!hasSubmenu && href && isPathActive(activeItem || '', href, allPaths)) // Item is active if it matches path logic

  const Icon = icon

  const handleClick = (event: React.MouseEvent<HTMLElement>) => {
    // If item has submenu, toggle it (don't navigate)
    if (hasSubmenu) {
      event.preventDefault()
      // If sidebar is collapsed, expand it first
      if (isCollapsed) {
        setOpen(true)
      }
      setOpenSubmenu(openSubmenu === title ? null : title)
      return
    }

    // If item has href, handle navigation
    if (title && href) {
      // Handle navigation - set active optimistically only for internal links
      if (href.startsWith('/')) {
        setActiveItem(normalizePathForMatching(href))
      }
      // Close any open submenu when clicking on an item
      setOpenSubmenu(null)
    }
    setOpenMobile(false)
    // Call the original onClick if provided (no event parameter)
    onClick?.()
  }

  const handleKeyDown = (event: React.KeyboardEvent<HTMLElement>) => {
    // If Enter or Space is pressed on a collapsed item with submenu, expand sidebar and open submenu
    if (
      (event.key === 'Enter' || event.key === ' ') &&
      hasSubmenu &&
      isCollapsed
    ) {
      event.preventDefault()
      setOpen(true)
      setOpenSubmenu(openSubmenu === title ? null : title)
    }
  }

  // No href - render NonNavigatingItem (or parent with submenu)
  if (hasSubmenu || !href) {
    const isOpen = openSubmenu === title
    return (
      <>
        <button
          ref={ref}
          data-sidebar="menu-button"
          data-active={isActive}
          data-state={isOpen ? 'open' : 'closed'}
          className={cn(
            sidebarMenuButtonVariants(),
            isActive && '[&_svg]:text-brand',
            'text-foreground !outline-none focus-visible:shadow-none',
            className,
          )}
          onClick={handleClick}
          onKeyDown={handleKeyDown}
        >
          <>
            {Icon && <Icon color="platform-navigation-muted" />}
            <span>{title}</span>
            {hasSubmenu && (
              <SvgTaillessLineArrowDown1
                width={16}
                height={16}
                style={{
                  color: 'var(--platform-navigation-muted-foreground)',
                }}
                className={cn(
                  'ml-auto !size-4 transition-transform duration-200',
                  isOpen && '-rotate-180',
                )}
              />
            )}
          </>
        </button>
        {hasSubmenu && (
          <SidebarMenuSub parentTitle={title}>
            {items.map((subItem) => (
              <SidebarMenuSubItem key={subItem.title}>
                <SidebarMenuSubButton
                  title={subItem.title}
                  href={subItem.href}
                  parentTitle={title}
                  external={subItem.external}
                />
              </SidebarMenuSubItem>
            ))}
          </SidebarMenuSub>
        )}
      </>
    )
  }

  // Internal link - use renderLink with InternalLink structure
  if (href.startsWith('/')) {
    return renderLink({
      href,
      onKeyDown: handleKeyDown,
      onClick: handleClick,
      'data-sidebar': 'menu-button',
      'data-active': isActive,
      className: cn(
        '!outline-none focus-visible:bg-platform-navigation-hover focus-visible:outline-none',
        sidebarMenuButtonVariants(),
        isActive && '[&>svg:not([data-sidebar=external-link-icon])]:text-brand',
        className,
      ),
      children: (
        <>
          {Icon && <Icon color="platform-navigation-muted" />}
          <span>{title}</span>
        </>
      ),
    })
  }

  // External link - render with external icon
  return (
    <a
      href={href}
      target="_blank"
      rel="noopener noreferrer"
      data-sidebar="menu-button"
      data-active={isActive}
      className={cn(
        sidebarMenuButtonVariants(),
        isActive && '[&>svg:not([data-sidebar=external-link-icon])]:text-brand',
        external && 'group/link',
        className,
      )}
      onClick={handleClick}
      onKeyDown={handleKeyDown}
    >
      {Icon && <Icon color="platform-navigation-muted" />}
      <span>{title}</span>
      {external && (
        <SvgArrowExpandWindow
          width="16"
          height="16"
          color="platform-navigation-muted"
          className="ml-auto h-4 max-h-4 w-4 max-w-4 opacity-0 transition-opacity duration-150 group-hover/link:opacity-100"
          data-sidebar="external-link-icon"
        />
      )}
    </a>
  )
}
SidebarMenuButton.displayName = 'SidebarMenuButton'

type SidebarMenuItemProps = React.ComponentProps<'li'> & {
  ref?: React.Ref<HTMLLIElement>
}

const SidebarMenuItem = ({
  className,
  ref,
  ...props
}: SidebarMenuItemProps) => (
  <li
    ref={ref}
    data-sidebar="menu-item"
    className={cn('group/menu-item relative overflow-hidden', className)}
    {...props}
  />
)
SidebarMenuItem.displayName = 'SidebarMenuItem'

type SidebarMenuActionProps = React.ComponentProps<'button'> & {
  asChild?: boolean
  showOnHover?: boolean
  ref?: React.Ref<HTMLButtonElement>
}

const SidebarMenuAction = ({
  className,
  asChild = false,
  showOnHover = false,
  ref,
  ...props
}: SidebarMenuActionProps) => {
  const Comp = asChild ? Slot : 'button'

  return (
    <Comp
      ref={ref}
      data-sidebar="menu-action"
      className={cn(
        'absolute right-1 top-1.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-foreground outline-none ring-ring transition-transform hover:bg-platform-navigation-hover hover:text-platform-navigation-hover-foreground focus-visible:bg-platform-navigation-hover focus-visible:text-platform-navigation-hover-foreground focus-visible:outline-none peer-hover/menu-button:text-platform-navigation-hover-foreground [&>svg]:size-4 [&>svg]:shrink-0',
        // Increases the hit area of the button on mobile.
        'after:absolute after:-inset-2 after:md:hidden',
        'top-2.5',
        'group-data-[collapsible=icon]:hidden',
        showOnHover &&
          'group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 peer-data-[active=true]/menu-button:text-platform-navigation-active-foreground md:opacity-0',
        className,
      )}
      {...props}
    />
  )
}
SidebarMenuAction.displayName = 'SidebarMenuAction'

type SidebarMenuBadgeProps = React.ComponentProps<'div'> & {
  ref?: React.Ref<HTMLDivElement>
}

const SidebarMenuBadge = ({
  className,
  ref,
  ...props
}: SidebarMenuBadgeProps) => (
  <div
    ref={ref}
    data-sidebar="menu-badge"
    className={cn(
      'pointer-events-none absolute right-1 flex h-5 min-w-5 select-none items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums text-foreground',
      'peer-hover/menu-button:text-platform-navigation-hover-foreground peer-data-[active=true]/menu-button:text-platform-navigation-active-foreground',
      'top-2.5',
      'group-data-[collapsible=icon]:hidden',
      className,
    )}
    {...props}
  />
)
SidebarMenuBadge.displayName = 'SidebarMenuBadge'

type SidebarMenuSkeletonProps = React.ComponentProps<'div'> & {
  showIcon?: boolean
  ref?: React.Ref<HTMLDivElement>
}

const SidebarMenuSkeleton = ({
  className,
  showIcon = false,
  ref,
  ...props
}: SidebarMenuSkeletonProps) => {
  // Random width between 50 to 90%.
  const width = React.useMemo(() => {
    return `${Math.floor(Math.random() * 40) + 50}%`
  }, [])

  return (
    <div
      ref={ref}
      data-sidebar="menu-skeleton"
      className={cn('flex h-8 items-center gap-2 rounded-md px-2', className)}
      {...props}
    >
      {showIcon && (
        <div
          className="size-4 rounded-md bg-muted"
          data-sidebar="menu-skeleton-icon"
        />
      )}
      <div
        className="h-4 max-w-[--skeleton-width] flex-1 rounded-md bg-muted"
        data-sidebar="menu-skeleton-text"
        style={
          {
            '--skeleton-width': width,
          } as React.CSSProperties
        }
      />
    </div>
  )
}
SidebarMenuSkeleton.displayName = 'SidebarMenuSkeleton'

type SidebarLogoIconProps = React.ComponentProps<'div'> & {
  ref?: React.Ref<HTMLDivElement>
}

const SidebarLogoIcon = ({
  className,
  children,
  ref,
  ...props
}: SidebarLogoIconProps) => {
  return (
    <div
      ref={ref}
      className={cn(
        'flex size-12 shrink-0 items-center justify-center',
        className,
      )}
      {...props}
    >
      {children}
    </div>
  )
}
SidebarLogoIcon.displayName = 'SidebarLogoIcon'

type SidebarLogoTextProps = React.ComponentProps<'div'> &
  Pick<VariantProps<typeof typographyVariants>, 'variant' | 'color'> & {
    ref?: React.Ref<HTMLDivElement>
  }

const SidebarLogoText = ({
  className,
  children,
  variant = 'body-semi-xl',
  color = 'brand',
  ref,
  ...props
}: SidebarLogoTextProps) => {
  return (
    <div
      ref={ref}
      className={cn(
        'flex items-center group-data-[collapsible=icon]:hidden',
        typographyVariants({ variant, color }),
        className,
      )}
      {...props}
    >
      {children}
    </div>
  )
}
SidebarLogoText.displayName = 'SidebarLogoText'

type SidebarLogoProps = React.ComponentProps<'div'> & {
  href?: string
  ref?: React.Ref<HTMLDivElement>
}

const SidebarLogo = ({
  children,
  className,
  href = '/',
  ref,
}: SidebarLogoProps) => {
  const { renderLink, setActiveItem, setOpenSubmenu } = useSidebar()

  const handleClick = () => {
    // Set active item optimistically for internal links
    setActiveItem(href)
    // Close any open submenus
    setOpenSubmenu(null)
  }

  return (
    <SidebarHeader ref={ref} className={cn('hidden md:flex', className)}>
      <SidebarMenu>
        <SidebarMenuItem>
          {renderLink({
            href,
            onClick: handleClick,
            tabIndex: 0,
            'data-sidebar': 'menu-button',
            className:
              'flex cursor-pointer !outline-none focus-visible:!bg-platform-navigation-hover focus-visible:outline-none',
            children,
          })}
        </SidebarMenuItem>
      </SidebarMenu>
    </SidebarHeader>
  )
}
SidebarLogo.displayName = 'SidebarLogo'

type SidebarLinksProps = {
  navItems?: SidebarNavItem[][]
}

const SidebarLinks = ({ navItems: propNavItems }: SidebarLinksProps) => {
  const { navItems: defaultNavItems } = useSidebar()
  const navItems = propNavItems ?? defaultNavItems
  if (!navItems) return null
  return (
    <>
      {navItems.map((group, groupIndex) => (
        <React.Fragment key={groupIndex}>
          {groupIndex > 0 && <SidebarSeparator />}
          <SidebarGroup>
            <SidebarGroupContent>
              <SidebarMenu>
                {group.map((item) => (
                  <SidebarMenuItem key={item.title}>
                    <SidebarMenuButton {...item} />
                  </SidebarMenuItem>
                ))}
              </SidebarMenu>
            </SidebarGroupContent>
          </SidebarGroup>
        </React.Fragment>
      ))}
    </>
  )
}
SidebarLinks.displayName = 'SidebarLinks'

type SidebarChainlinkLogoProps = React.ComponentProps<'div'> & {
  href?: string
  ref?: React.Ref<HTMLDivElement>
}

const SidebarChainlinkLogo = ({
  href = '/',
  className,
  ref,
  ...props
}: SidebarChainlinkLogoProps) => {
  return (
    <SidebarLogo href={href} className={className} ref={ref} {...props}>
      <SidebarLogoIcon>
        <ChainlinkIcon />
      </SidebarLogoIcon>
      <SidebarLogoText>
        <ChainlinkLogoText />
      </SidebarLogoText>
    </SidebarLogo>
  )
}
SidebarChainlinkLogo.displayName = 'SidebarChainlinkLogo'

export {
  Sidebar,
  SidebarContent,
  SidebarFooter,
  SidebarGroup,
  SidebarGroupAction,
  SidebarGroupContent,
  SidebarGroupLabel,
  SidebarHeader,
  SidebarInput,
  SidebarInset,
  SidebarLogo,
  SidebarLogoIcon,
  SidebarLogoText,
  SidebarChainlinkLogo,
  SidebarLinks,
  SidebarMenu,
  SidebarMenuAction,
  SidebarMenuBadge,
  SidebarMenuButton,
  SidebarMenuItem,
  SidebarMenuSkeleton,
  SidebarMenuSub,
  SidebarMenuSubButton,
  SidebarMenuSubItem,
  SidebarProvider,
  SidebarRail,
  SidebarSeparator,
  SidebarTrigger,
  SidebarContext,
  useSidebar,
  useSidebarContext,
  type SidebarNavItem,
  type SidebarLinkProps,
}
