/**
 * Sidebar React wrapper — Lane A imperative wrap over src/sidebar/component.ts
 *
 * Import from the dedicated subpath:
 *   import { Sidebar } from '@countermeasure-platform/web-components/react/sidebar'
 *
 * The wrapper renders a host div then mounts `SidebarComponent` into it on
 * mount. Prop changes to `activeItemId`, `pathname`, and controlled `open`
 * are synced via the class's public API.
 */

import * as React from 'react'
import { cn } from './primitives/utils'
import { SidebarComponent } from '../sidebar/component'
import type {
  SidebarComponentConfig,
  SidebarBadgeConfig,
  SidebarBadgeTone,
  SidebarNavItem,
  SidebarScopeConfig,
  SidebarScopeOption,
  SidebarSection,
  SidebarUser,
  SidebarFooterAction,
} from '../sidebar/types'

export interface SidebarProps extends Omit<
  SidebarComponentConfig,
  'container' | 'onNavigate' | 'onCollapse'
> {
  /** Currently active nav item ID. Synced via `setActive` on changes. */
  activeItemId?: string
  /** Called when the user clicks a nav item. */
  onNavigate?: (item: SidebarNavItem) => void
  /** Called when the sidebar is collapsed/expanded. */
  onCollapse?: (collapsed: boolean) => void
  className?: string
}

export type {
  SidebarBadgeConfig,
  SidebarBadgeTone,
  SidebarFooterAction,
  SidebarNavItem,
  SidebarScopeConfig,
  SidebarScopeOption,
  SidebarSection,
  SidebarUser,
}

export interface SidebarCollapseButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  collapsed?: boolean
  edge?: boolean
  visible?: boolean
  label?: string
}

const Sidebar = (props: SidebarProps) => {
  const { activeItemId, pathname, onNavigate, onCollapse, className, open, ...config } = props
  const containerRef = React.useRef<HTMLDivElement>(null)
  const sidebarRef = React.useRef<SidebarComponent | null>(null)
  const onNavigateRef = React.useRef(onNavigate)
  const onCollapseRef = React.useRef(onCollapse)
  onNavigateRef.current = onNavigate
  onCollapseRef.current = onCollapse

  // Construct once on mount — SSR-safe
  React.useEffect(() => {
    if (typeof document === 'undefined' || !containerRef.current) return
    const sidebarConfig: SidebarComponentConfig = {
      ...config,
      container: containerRef.current,
      onNavigate: (item: SidebarNavItem) => {
        onNavigateRef.current?.(item)
      },
      onCollapse: (collapsed: boolean) => {
        onCollapseRef.current?.(collapsed)
      },
    }
    if (open !== undefined) {
      sidebarConfig.open = open
    }
    if (pathname !== undefined) {
      sidebarConfig.pathname = pathname
    }
    sidebarRef.current = new SidebarComponent(sidebarConfig)
    return () => {
      sidebarRef.current?.destroy()
      sidebarRef.current = null
    }
  }, [])

  // Sync mobile open state to the component default when the prop is removed.
  React.useEffect(() => {
    if (!sidebarRef.current) return
    sidebarRef.current.setOpen(open === true)
  }, [open])

  // Sync active item when prop changes
  React.useEffect(() => {
    if (!sidebarRef.current || activeItemId === undefined) return
    sidebarRef.current.setActive(activeItemId)
  }, [activeItemId])

  // Sync route-derived active state when no explicit active item controls it.
  React.useEffect(() => {
    if (!sidebarRef.current || activeItemId !== undefined) return
    sidebarRef.current.setPathname(pathname)
  }, [activeItemId, pathname])

  return <div ref={containerRef} data-slot="sidebar" className={cn(className)} />
}

Sidebar.displayName = 'Sidebar'

const collapseDefaultLabel = (collapsed: boolean): string =>
  collapsed ? 'Expand sidebar' : 'Collapse sidebar'

const collapseIconPath = (collapsed: boolean): string =>
  collapsed ? 'm9 18 6-6-6-6' : 'm15 18-6-6 6-6'

const CollapseChevron = ({ collapsed }: { collapsed: boolean }) => (
  <svg
    aria-hidden="true"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    strokeWidth="2"
    strokeLinecap="round"
    strokeLinejoin="round"
  >
    <path d={collapseIconPath(collapsed)} />
  </svg>
)

const SidebarCollapseButton = (componentProps: SidebarCollapseButtonProps) => {
  const {
    collapsed = false,
    edge = false,
    visible = false,
    label,
    className,
    type = 'button',
    children,
    ...props
  } = componentProps
  const resolvedLabel = label ?? collapseDefaultLabel(collapsed)

  return (
    <button
      type={type}
      className={cn('sidebar__collapse-btn', edge && 'sidebar__collapse-btn--edge', className)}
      aria-label={resolvedLabel}
      aria-expanded={!collapsed}
      title={resolvedLabel}
      data-collapsed={collapsed ? 'true' : 'false'}
      data-visible={visible ? 'true' : undefined}
      {...props}
    >
      {children ?? <CollapseChevron collapsed={collapsed} />}
    </button>
  )
}

SidebarCollapseButton.displayName = 'SidebarCollapseButton'

export { Sidebar, SidebarCollapseButton }
