/**
 * SidebarComponent type definitions
 * @countermeasure/web-components/sidebar/component
 */

import { type BrandSize } from '../components/brand'
import { type IconSet } from '../icons/index'

export type SidebarBadgeTone =
  | 'default'
  | 'primary'
  | 'amber'
  | 'cyan'
  | 'rose'
  | 'warning'
  | 'error'

export type SidebarActiveMatcher =
  | 'exact'
  | 'prefix'
  | string
  | RegExp
  | ((pathname: string, item: SidebarNavItem) => boolean)

export interface SidebarBadgeConfig {
  /** Visible badge text. Use short labels such as "9", "99+", or "Soon". */
  label: string
  /** Optional accessible title used in collapsed tooltips and native titles. */
  title?: string
  /**
   * Visual tone for the badge.
   * @default 'primary'
   */
  tone?: SidebarBadgeTone
  /**
   * Keep the collapsed rail dot visible even when label is empty.
   * @default false
   */
  dot?: boolean
}

export interface SidebarNavItem {
  /** Stable identifier used for selection and badge updates. */
  id: string
  /** Visible label rendered alongside the icon. */
  label: string
  /** Optional navigation target. When omitted, the item renders as a button. */
  href?: string
  /** Optional target for link navigation. */
  target?: string
  /** Optional rel for external links. */
  rel?: string
  /** Accessible label override. */
  ariaLabel?: string
  /** Icon name resolved through the active icon set. */
  icon?: string
  /** Numeric or rich badge displayed at the trailing edge of the row. */
  badge?: number | SidebarBadgeConfig
  /**
   * Visual tone for the badge.
   * @default 'primary'
   */
  badgeTone?: SidebarBadgeTone
  /** Static pill label such as "Admin" or "Soon". */
  tag?: string
  /** Tooltip/title shown when the sidebar is collapsed. */
  tooltip?: string
  /**
   * Whether this item is the current page. If omitted, active state can be
   * derived from `activeItemId`, `href`, or `activeMatch`.
   */
  active?: boolean
  /** Route matching rule used against the current configured/browser pathname. */
  activeMatch?: SidebarActiveMatcher
  /**
   * Treat href matching as exact instead of prefix matching.
   * @default false
   */
  end?: boolean
  /**
   * Render the item as unavailable while preserving its position.
   * @default false
   */
  disabled?: boolean
  /** Called when the item is activated. */
  onClick?: (event: MouseEvent) => void
}

export interface SidebarSection {
  /** Stable section identifier. */
  id: string
  /** Optional section heading. */
  label?: string
  /** Nav items rendered within this section. */
  items: SidebarNavItem[]
  /**
   * Render the section as a collapsible accordion group with a clickable
   * header instead of a flat label. When set, `label` is rendered as the
   * toggle and items collapse/expand on click.
   * @default false
   */
  collapsible?: boolean
  /**
   * Initial expanded state when `collapsible` is true.
   * @default true
   */
  defaultExpanded?: boolean
  /** Optional icon for the collapsible group header. */
  icon?: string
}

export interface SidebarUser {
  /** Display name shown in the footer. */
  name: string
  /** Secondary user metadata such as email or role. */
  detail?: string
  /** Avatar image URL. */
  avatarUrl?: string
  /** Initials fallback when no avatar URL is provided. */
  initials?: string
  /** Presence dot tone shown on the avatar. */
  presence?: 'online' | 'away' | 'busy' | 'dnd' | 'offline'
  /** Accessible label for the user trigger. */
  label?: string
  /** Called when the user surface is activated. */
  onClick?: () => void
}

export interface SidebarFooterAction {
  /** Stable identifier for the action. */
  id: string
  /** Icon name resolved through the active icon set. */
  icon: string
  /** Accessible label / tooltip for the action. */
  label: string
  /**
   * Render the action with destructive styling.
   * @default false
   */
  danger?: boolean
  /** Called when the action is activated. */
  onClick?: () => void
}

export interface SidebarBrandConfig {
  /** Accessible brand label. */
  label?: string
  /** Brand mark size. */
  markSize?: BrandSize | number
  /**
   * Show the COUNTERMEASURE wordmark next to the diamond.
   * @default true
   */
  showWordmark?: boolean
  /** Optional link target for the brand surface. */
  href?: string
  /** Called when the brand surface is activated. */
  onClick?: () => void
  /**
   * Render the brand as decorative.
   * @default false
   */
  decorative?: boolean
}

export interface SidebarScopeOption {
  id: string
  label: string
  status?: 'active' | 'suspended' | 'archived' | 'warning' | 'error' | 'neutral'
  disabled?: boolean
}

export interface SidebarScopeConfig {
  /** Label shown above/inside the selector. */
  label?: string
  /** Icon name resolved through the active icon set. */
  icon?: string
  /** Current selected option id. */
  value?: string
  /** Fallback label when `value` does not match an option. */
  placeholder?: string
  /** Options rendered in the selector menu. */
  options: SidebarScopeOption[]
  /** Called when the selected option changes. */
  onChange?: (option: SidebarScopeOption) => void
}

export interface SidebarComponentConfig {
  /** Container element (or selector) the sidebar is mounted into. */
  container: HTMLElement | string
  /** Visual variant key — passed through as `data-variant` for theming. */
  variant?: string
  /** Sections rendered top-to-bottom. */
  sections: SidebarSection[]
  /** Optional brand header rendered above the navigation. */
  brand?: SidebarBrandConfig
  /** Optional scope/tenant selector rendered below the brand. */
  scope?: SidebarScopeConfig
  /** Optional element inserted between the header/scope area and navigation. */
  beforeNav?: HTMLElement | HTMLElement[]
  /** Optional element inserted after navigation and before footer. */
  afterNav?: HTMLElement | HTMLElement[]
  /**
   * Render the shared edge-docked collapse control.
   * @default false
   */
  collapsible?: boolean
  /**
   * Keep the collapse control visible instead of hover/focus-only.
   * Useful for docs and constrained previews.
   * @default false
   */
  collapseButtonVisible?: boolean
  /** Optional user surface rendered in the footer. */
  user?: SidebarUser
  /** Footer action buttons rendered next to the user surface. */
  footerActions?: SidebarFooterAction[]
  /**
   * Icon set used to resolve `icon` names.
   * @default 'lucide'
   */
  iconSet?: IconSet
  /**
   * Initial collapsed state. When `collapsible` is true the collapse button
   * starts pointing the matching direction.
   * @default false
   */
  collapsed?: boolean
  /**
   * Current active nav item ID. Applied during initial render and when React
   * wrappers call `setActive`.
   */
  activeItemId?: string
  /**
   * Current route path used to derive active link state. When omitted, browser
   * consumers fall back to `window.location.pathname`.
   */
  pathname?: string
  /**
   * Persist collapsed state under this localStorage key.
   * When omitted, collapsed state remains in memory only.
   */
  storageKey?: string
  /**
   * Persist collapsed state when `storageKey` is supplied.
   * @default true
   */
  persistCollapsed?: boolean
  /**
   * Viewport width below which the sidebar behaves as a mobile drawer.
   * @default 900
   */
  mobileBreakpoint?: number
  /**
   * Render and control a mobile backdrop alongside the sidebar.
   * @default false
   */
  mobileBackdrop?: boolean
  /**
   * Close the mobile drawer after a nav item activates.
   * @default true
   */
  closeOnNavigate?: boolean
  /**
   * Controlled mobile open state. Reflected to `data-open` for the mobile
   * sidebar visibility contract.
   * @default false
   */
  open?: boolean
  /** Called when a nav item is activated. */
  onNavigate?: (item: SidebarNavItem) => void
  /** Called when the sidebar's collapsed state changes. */
  onCollapse?: (collapsed: boolean) => void
  /** Called when the mobile open state changes. */
  onOpenChange?: (open: boolean) => void
}
