import { CheckIcon, XIcon } from 'lucide-react'
import * as React from 'react'

import { cn } from './utils'

type StepStatus = 'pending' | 'active' | 'complete' | 'error' | 'disabled'

interface StepperContextValue {
  orientation: 'horizontal' | 'vertical'
}

const StepperContext = React.createContext<StepperContextValue>({
  orientation: 'horizontal',
})

function Stepper({
  className,
  orientation = 'horizontal',
  children,
  ...props
}: React.ComponentProps<'nav'> & {
  orientation?: 'horizontal' | 'vertical'
}) {
  const contextValue = React.useMemo(() => ({ orientation }), [orientation])

  return (
    <StepperContext.Provider value={contextValue}>
      <nav data-slot="stepper" aria-label="Progress" className={cn(className)} {...props}>
        <ol className={cn('flex gap-2', orientation === 'vertical' ? 'flex-col' : 'items-center')}>
          {children}
        </ol>
      </nav>
    </StepperContext.Provider>
  )
}

function StepperItem({
  className,
  step,
  label,
  description,
  status = 'pending',
  isLast = false,
  icon,
  onClick,
  ...props
}: React.ComponentProps<'li'> & {
  step: number
  label: string
  description?: string
  status?: StepStatus
  isLast?: boolean
  icon?: React.ReactNode
}) {
  const { orientation } = React.useContext(StepperContext)
  const isClickable = status !== 'disabled' && onClick !== undefined

  return (
    <li
      data-slot="stepper-item"
      data-status={status}
      className={cn(
        'flex gap-3',
        orientation === 'horizontal' && 'flex-1 items-center',
        orientation === 'vertical' && 'relative pb-8 last:pb-0',
        className
      )}
      {...props}
    >
      <div
        className={cn(
          'flex items-center gap-3',
          orientation === 'horizontal' && 'flex-col sm:flex-row',
          orientation === 'vertical' && 'items-start'
        )}
      >
        {/* Step indicator */}
        <button
          type="button"
          disabled={!isClickable}
          onClick={
            isClickable
              ? (onClick as unknown as React.MouseEventHandler<HTMLButtonElement>)
              : undefined
          }
          aria-current={status === 'active' ? 'step' : undefined}
          className={cn(
            'relative z-10 flex size-8 shrink-0 items-center justify-center rounded-full border-2 text-sm font-medium transition-all',
            status === 'pending' &&
              'border-border-glass bg-surface-secondary text-foreground-secondary',
            status === 'active' && 'border-primary bg-primary text-primary-foreground shadow-glow',
            status === 'complete' && 'border-primary bg-primary text-primary-foreground',
            status === 'error' && 'border-destructive bg-destructive text-destructive-foreground',
            status === 'disabled' &&
              'border-border-glass bg-surface-secondary text-foreground-secondary/50 cursor-not-allowed opacity-50',
            isClickable && 'cursor-pointer hover:shadow-glow'
          )}
        >
          {icon ? (
            icon
          ) : status === 'complete' ? (
            <CheckIcon className="size-4" />
          ) : status === 'error' ? (
            <XIcon className="size-4" />
          ) : (
            step
          )}
        </button>

        {/* Step text */}
        <div className="flex flex-col">
          <span
            className={cn(
              'text-sm font-medium',
              status === 'active' && 'text-foreground',
              status === 'complete' && 'text-foreground',
              status === 'pending' && 'text-foreground-secondary',
              status === 'error' && 'text-destructive',
              status === 'disabled' && 'text-foreground-secondary/50'
            )}
          >
            {label}
          </span>
          {description && (
            <span
              className={cn(
                'text-xs',
                status === 'disabled' ? 'text-foreground-secondary/40' : 'text-foreground-secondary'
              )}
            >
              {description}
            </span>
          )}
        </div>
      </div>

      {/* Connector line */}
      {!isLast && orientation === 'horizontal' && (
        <div
          data-slot="stepper-connector"
          aria-hidden="true"
          className={cn(
            'mx-2 h-0.5 flex-1 rounded-full transition-colors',
            status === 'complete' ? 'bg-primary' : 'bg-border-glass'
          )}
        />
      )}
      {!isLast && orientation === 'vertical' && (
        <div
          data-slot="stepper-connector"
          aria-hidden="true"
          className={cn(
            'absolute left-[15px] top-10 h-[calc(100%-2.5rem)] w-0.5 rounded-full transition-colors',
            status === 'complete' ? 'bg-primary' : 'bg-border-glass'
          )}
        />
      )}
    </li>
  )
}

export { Stepper, StepperItem, type StepStatus }
