import { forwardRef } from 'react'
import type { HTMLAttributes } from 'react'
import { cva } from 'class-variance-authority'
import { cn } from '@/lib/utils'

const LIST_BASE = 'flex flex-col gap-1'

const itemVariants = cva(
  'w-full flex flex-col gap-0.5 items-start p-2 text-sm rounded text-left transition-colors outline-none focus-visible:bg-fill-tertiary focus-visible:ring-0',
  {
    variants: {
      selected: { true: '', false: '' },
      disabled: {
        true: 'opacity-50 cursor-not-allowed',
        false: 'cursor-pointer hover:bg-fill-tertiary',
      },
      dimmed: { true: 'opacity-40', false: '' },
    },
    defaultVariants: { selected: false, disabled: false, dimmed: false },
  }
)

const prefixVariants = cva(
  'flex-shrink-0 w-5 h-5 rounded-full flex items-center justify-center text-xs font-mono font-medium transition-colors',
  {
    variants: {
      selected: {
        true: 'bg-primary-active text-text-on-primary',
        false: 'bg-fill-secondary text-text-tertiary',
      },
    },
    defaultVariants: { selected: false },
  }
)

export interface OptionItem {
  id: string
  label: string
  description?: string
  disabled?: boolean
}

export interface OptionListProps extends HTMLAttributes<HTMLDivElement> {
  items: OptionItem[]
  selectedIds?: string[]
  focusedId?: string
  onItemClick?: (item: OptionItem, index: number) => void
  showPrefix?: boolean
  disabled?: boolean
}

export const OptionList = forwardRef<HTMLDivElement, OptionListProps>(
  (
    {
      items,
      selectedIds = [],
      focusedId,
      onItemClick,
      showPrefix = true,
      disabled = false,
      className,
      ...props
    },
    ref
  ) => {
    const getOptionNumber = (index: number) => String(index + 1)

    return (
      <div
        ref={ref}
        role="listbox"
        aria-multiselectable={selectedIds.length > 1}
        className={cn(LIST_BASE, className)}
        {...props}
      >
        {items.map((item, index) => {
          const isSelected = selectedIds.includes(item.id)
          const isFocused = focusedId === item.id
          const isDisabled = disabled || item.disabled
          const hasSelection = selectedIds.length > 0
          const dimmed = hasSelection && !isSelected && !isDisabled

          return (
            <button
              key={item.id}
              type="button"
              role="option"
              aria-selected={isSelected}
              aria-disabled={isDisabled}
              onClick={() => {
                if (!isDisabled) onItemClick?.(item, index)
              }}
              disabled={isDisabled}
              className={cn(
                itemVariants({
                  selected: isSelected,
                  disabled: isDisabled,
                  dimmed,
                }),
                // 键盘焦点态：仅底色，无 ring
                isFocused && 'bg-fill-tertiary'
              )}
            >
              <div className="flex items-center gap-3">
                {showPrefix && (
                  <div className={prefixVariants({ selected: isSelected })}>
                    {getOptionNumber(index)}
                  </div>
                )}
                <span className="font-medium text-text">{item.label}</span>
              </div>
              {item.description && (
                <div className="ml-8 text-xs text-text-tertiary">
                  {item.description}
                </div>
              )}
            </button>
          )
        })}
      </div>
    )
  }
)

OptionList.displayName = 'OptionList'
