import type { CSSProperties, MouseEvent, ReactNode } from 'react';

function classNames(...values: Array<string | false | null | undefined>): string {
  return values.filter(Boolean).join(' ');
}

export interface NavItemProps {
  icon?: ReactNode;
  label: string;
  active?: boolean;
  badge?: ReactNode;
  badgeTone?: 'warn' | 'error' | 'accent';
  href?: string;
  onClick?: (e: MouseEvent) => void;
  style?: CSSProperties;
  // Native tooltip; used by the collapsed sidebar rail to surface the label that is visually
  // hidden there (the label stays in the a11y tree for the accessible name — #396).
  title?: string;
}

export function NavItem({
  icon,
  label,
  active = false,
  badge = null,
  badgeTone = 'warn',
  href,
  onClick,
  style,
  title
}: NavItemProps) {
  const content = (
    <>
      {active && <span className="ctv-nav-rail" />}
      {icon && <span className="ctv-nav-icon">{icon}</span>}
      <span className="ctv-nav-label">{label}</span>
      {badge != null && (
        <span className={classNames('ctv-nav-badge', `ctv-nav-badge-${badgeTone}`)}>{badge}</span>
      )}
    </>
  );

  if (href) {
    return (
      <a
        href={href}
        aria-current={active ? 'page' : undefined}
        onClick={onClick}
        className={classNames('ctv-nav-item', active && 'ctv-nav-item-active')}
        style={style}
        title={title}
      >
        {content}
      </a>
    );
  }

  return (
    <button
      type="button"
      aria-current={active ? 'page' : undefined}
      onClick={onClick}
      className={classNames('ctv-nav-item', active && 'ctv-nav-item-active')}
      style={style}
      title={title}
    >
      {content}
    </button>
  );
}

export interface NavSectionProps {
  children?: ReactNode;
  style?: CSSProperties;
}

export function NavSection({ children, style }: NavSectionProps) {
  return (
    <div className="ctv-nav-section" style={style}>
      {children}
    </div>
  );
}

export interface TabItem {
  value: string;
  label: string;
  icon?: ReactNode;
  count?: number;
}

export interface TabsProps {
  tabs: Array<string | TabItem>;
  value?: string;
  onChange?: (value: string) => void;
  style?: CSSProperties;
}

function normalizeTab(tab: string | TabItem): TabItem {
  return typeof tab === 'string' ? { value: tab, label: tab } : tab;
}

export function Tabs({ tabs, value, onChange, style }: TabsProps) {
  const items = tabs.map(normalizeTab);
  const activeValue = value ?? items[0]?.value;

  return (
    <div className="ctv-tabs" role="tablist" style={style}>
      {items.map((tab) => {
        const selected = tab.value === activeValue;

        return (
          <button
            key={tab.value}
            type="button"
            role="tab"
            aria-selected={selected}
            className="ctv-tab"
            onClick={() => onChange?.(tab.value)}
          >
            {tab.icon && <span className="ctv-tab-icon">{tab.icon}</span>}
            <span>{tab.label}</span>
            {tab.count != null && <span className="ctv-tab-count">{tab.count}</span>}
          </button>
        );
      })}
    </div>
  );
}
