import { ChevronDown, ChevronRight, type LucideIcon } from 'lucide-react';

import type { ReactNode } from 'react';

import { Link } from '@inertiajs/react';

import { cn } from '@/lib/utils';

export interface HubDimCta {
  /** Label shown on the inline button (e.g. "Connect GSC"). */
  label: string;
  /** Resolved href the button navigates to. */
  href: string;
}

/**
 * NAV-001 V2 — single hub row in the sidebar.
 *
 * Shape:
 *   [icon]  [label] [optional badge]            [chevron]
 *           [optional dim-reason subtext]
 *           ▼ children container (when expanded)
 *
 * Hub label is a focusable link to the hub URL. Chevron is a separate
 * focusable button so screen-reader users can tab to it independently and
 * trigger expand/collapse with Enter/Space without leaving the keyboard.
 *
 * Active states:
 *   - hub label gets a muted left-border accent when ANY child is on the
 *     current URL (drives the "you are inside this hub" cue)
 *   - dim state stacks on top: dimmed hubs are rendered at lower opacity
 *     and route to the per-hub explainer page instead of the steady-state
 *     landing
 */
export interface HubItemProps {
  hubKey: string;
  label: string;
  href: string;
  Icon: LucideIcon;
  expanded: boolean;
  isActiveHub: boolean;
  /**
   * True only when the current URL is the hub's own landing — not when active
   * via a child. Drives `aria-current="page"` on the hub link; otherwise the
   * hub uses `aria-current="location"` so screen readers don't announce two
   * "current page" elements in the same nav.
   */
  isExactHubMatch?: boolean;
  dimmed: boolean;
  dimmedReason?: string;
  /**
   * Optional inline CTA shown beneath a dimmed hub. Turns the dim subtext
   * into an actionable Connect button so the user can resolve the gate
   * without having to find the onboarding page on their own.
   */
  dimmedCta?: HubDimCta;
  badge?: number;
  onToggle: () => void;
  onNavigate?: () => void;
  children?: ReactNode;
}

export function HubItem({
  hubKey,
  label,
  href,
  Icon,
  expanded,
  isActiveHub,
  isExactHubMatch,
  dimmed,
  dimmedReason,
  dimmedCta,
  badge,
  onToggle,
  onNavigate,
  children,
}: HubItemProps) {
  const Chevron = expanded ? ChevronDown : ChevronRight;
  const showBadge = typeof badge === 'number' && badge > 0;

  return (
    <div
      data-testid={`hub-item-${hubKey}`}
      className={cn(
        'flex flex-col',
        isActiveHub && 'border-l-2 border-sidebar-accent-foreground/40',
        !isActiveHub && 'border-l-2 border-transparent',
      )}
    >
      <div className="flex items-stretch">
        <Link
          href={href}
          onClick={onNavigate}
          aria-current={
            isExactHubMatch ? 'page' : isActiveHub ? 'location' : undefined
          }
          data-testid={`hub-link-${hubKey}`}
          className={cn(
            // Fitts' law: ≥44px tap target on touch viewports (md:py-1.5 keeps the dense desktop look).
'flex flex-1 items-center gap-3 rounded-md px-2 py-3 md:py-1.5 min-h-[44px] md:min-h-0 text-sm font-medium transition-colors',
            'hover:bg-sidebar-accent hover:text-sidebar-accent-foreground',
            'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',
            isActiveHub ? 'text-foreground' : 'text-sidebar-foreground/90',
            dimmed && 'opacity-60',
          )}
        >
          <Icon className="size-4 shrink-0" aria-hidden="true" />
          <span className="flex-1 truncate">{label}</span>
          {showBadge && (
            <span
              aria-label={`${badge} new`}
              className={cn(
                'inline-flex h-4 min-w-[1rem] items-center justify-center rounded-full px-1',
                'bg-primary text-primary-foreground text-[10px] font-semibold',
              )}
            >
              {badge! > 99 ? '99+' : badge}
            </span>
          )}
        </Link>
        <button
          type="button"
          onClick={onToggle}
          aria-expanded={expanded}
          aria-controls={`hub-children-${hubKey}`}
          aria-label={expanded ? `Collapse ${label}` : `Expand ${label}`}
          data-testid={`hub-toggle-${hubKey}`}
          className={cn(
            // Fitts' law: 44×44px tap target on touch; compact 28×28 on desktop.
            'inline-flex h-11 w-11 md:h-7 md:w-7 items-center justify-center rounded-md',
            'text-sidebar-foreground/60 transition-colors',
            'hover:bg-sidebar-accent hover:text-sidebar-accent-foreground',
            'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',
          )}
        >
          <Chevron className="size-4" aria-hidden="true" />
        </button>
      </div>
      {dimmed && (dimmedReason || dimmedCta) && (
        <div data-testid={`hub-dim-reason-${hubKey}`} className="mt-0.5 px-2 pl-8 space-y-2">
          {dimmedReason && <p className="text-xs text-muted-foreground">{dimmedReason}</p>}
          {dimmedCta && (
            <Link
              href={dimmedCta.href}
              onClick={onNavigate}
              data-testid={`hub-dim-cta-${hubKey}`}
              className={cn(
                // Inline pill with 44px mobile tap target + compact desktop.
                'inline-flex items-center gap-1 rounded-md px-3 py-2 md:py-1.5 text-xs font-medium',
                'min-h-[44px] md:min-h-[28px]',
                'bg-primary/10 text-primary hover:bg-primary/15 hover:text-primary',
                'transition-colors',
                'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',
              )}
            >
              {dimmedCta.label}
              <ChevronRight className="size-3" aria-hidden="true" />
            </Link>
          )}
        </div>
      )}
      {expanded && children && (
        <div
          id={`hub-children-${hubKey}`}
          data-testid={`hub-children-${hubKey}`}
          className="mt-0.5 flex flex-col gap-0.5"
        >
          {children}
        </div>
      )}
    </div>
  );
}
