import { Check } from 'lucide-react';
import type { LucideIcon } from 'lucide-react';

import type { ReactNode } from 'react';
import { useEffect, useRef } from 'react';

import { Button } from '@/Components/ui/button';
import { cn } from '@/lib/utils';

export interface StepDefinition {
  id: string;
  label: string;
  description?: string;
  icon?: LucideIcon;
  optional?: boolean;
  /** Estimated time for this step, e.g. "~2 minutes" */
  timeEstimate?: string;
}

interface StepperProps {
  steps: StepDefinition[];
  currentStep: number;
  onStepChange: (step: number) => void;
  children: ReactNode;
  className?: string;
}

export function Stepper({ steps, currentStep, onStepChange, children, className }: StepperProps) {
  const stepRefs = useRef<(HTMLButtonElement | null)[]>([]);

  // Handle keyboard navigation
  useEffect(() => {
    const handleKeyDown = (event: KeyboardEvent) => {
      switch (event.key) {
        case 'ArrowRight':
        case 'ArrowDown':
          event.preventDefault();
          if (currentStep < steps.length - 1) {
            onStepChange(currentStep + 1);
          }
          break;
        case 'ArrowLeft':
        case 'ArrowUp':
          event.preventDefault();
          if (currentStep > 0) {
            onStepChange(currentStep - 1);
          }
          break;
        case 'Home':
          event.preventDefault();
          onStepChange(0);
          break;
        case 'End':
          event.preventDefault();
          onStepChange(steps.length - 1);
          break;
        default:
          break;
      }
    };

    // Focus current step button for keyboard navigation
    const currentButton = stepRefs.current[currentStep];
    if (currentButton) {
      currentButton.focus();
    }

    // Add event listener to a container element
    const stepIndicatorContainer = document.querySelector<HTMLElement>('[role="tablist"]');
    if (stepIndicatorContainer) {
      stepIndicatorContainer.addEventListener('keydown', handleKeyDown);
      return () => {
        stepIndicatorContainer.removeEventListener('keydown', handleKeyDown);
      };
    }
  }, [currentStep, steps.length, onStepChange]);

  return (
    <div className={cn('w-full', className)}>
      {/* Progress bar + Step counter */}
      <div className="mb-6">
        <div className="flex items-center justify-between text-xs text-muted-foreground mb-2">
          <span className="font-medium">
            Step {currentStep + 1} of {steps.length}
          </span>
          {steps[currentStep]?.timeEstimate && (
            <span className="flex items-center gap-1">
              <span aria-hidden="true">⏱</span>
              {steps[currentStep].timeEstimate}
            </span>
          )}
        </div>
        <div
          className="h-1.5 w-full rounded-full bg-muted overflow-hidden"
          role="progressbar"
          aria-valuenow={currentStep + 1}
          aria-valuemin={1}
          aria-valuemax={steps.length}
          aria-label={`Onboarding progress: step ${currentStep + 1} of ${steps.length}`}
        >
          <div
            className="h-full rounded-full bg-primary transition-all duration-500"
            style={{ width: `${((currentStep + 1) / steps.length) * 100}%` }}
          />
        </div>
      </div>

      {/* Step Indicator */}
      <div className="mb-8">
        <div className="flex items-center justify-center" role="tablist">
          {steps.map((step, index) => {
            const isCompleted = index < currentStep;
            const isCurrent = index === currentStep;
            const StepIcon = step.icon;

            return (
              <div key={step.id} className="flex items-center">
                {/* Step Circle - Button for keyboard and mouse interaction */}
                <button
                  ref={(el) => {
                    stepRefs.current[index] = el;
                  }}
                  onClick={() => onStepChange(index)}
                  role="tab"
                  aria-selected={isCurrent}
                  aria-controls={`step-content-${index}`}
                  tabIndex={isCurrent ? 0 : -1}
                  className={cn(
                    'flex h-10 w-10 items-center justify-center rounded-full border-2 text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 cursor-pointer',
                    isCompleted && 'border-primary bg-primary text-primary-foreground',
                    isCurrent && 'border-primary bg-background text-primary',
                    !isCompleted &&
                      !isCurrent &&
                      'border-muted-foreground/30 text-muted-foreground/50',
                  )}
                >
                  {isCompleted ? (
                    <Check className="h-5 w-5 animate-checkmark" />
                  ) : StepIcon ? (
                    <StepIcon className="h-5 w-5" />
                  ) : (
                    index + 1
                  )}
                </button>
                <span
                  className={cn(
                    'mt-2 text-xs font-medium',
                    isCurrent ? 'text-foreground' : 'text-muted-foreground',
                  )}
                >
                  {step.label}
                </span>

                {/* Connecting Line */}
                {index < steps.length - 1 && (
                  <div
                    className={cn(
                      'mx-2 h-0.5 w-12 sm:w-20 transition-colors',
                      index < currentStep ? 'bg-primary' : 'bg-muted-foreground/20',
                    )}
                    aria-hidden="true"
                  />
                )}
              </div>
            );
          })}
        </div>
      </div>

      {/* Step Content */}
      <div
        key={currentStep}
        className="animate-fade-in"
        role="tabpanel"
        id={`step-content-${currentStep}`}
        aria-labelledby={`step-${currentStep}`}
      >
        {children}
      </div>
    </div>
  );
}

interface StepContentProps {
  step: number;
  currentStep: number;
  children: ReactNode;
  className?: string;
}

export function StepContent({ step, currentStep, children, className }: StepContentProps) {
  if (step !== currentStep) return null;
  return (
    <div key={step} className={cn('animate-fade-in', className)}>
      {children}
    </div>
  );
}

interface StepperNavigationProps {
  currentStep: number;
  totalSteps: number;
  onBack: () => void;
  onNext: () => void;
  onSkip?: () => void;
  nextLabel?: string;
  backLabel?: string;
  finishLabel?: string;
  skipLabel?: string;
  isNextDisabled?: boolean;
  nextDisabledHint?: string;
  className?: string;
}

export function StepperNavigation({
  currentStep,
  totalSteps,
  onBack,
  onNext,
  onSkip,
  nextLabel,
  backLabel = 'Back',
  finishLabel = 'Finish',
  skipLabel = 'Skip',
  isNextDisabled = false,
  nextDisabledHint,
  className,
}: StepperNavigationProps) {
  const isFirst = currentStep === 0;
  const isLast = currentStep === totalSteps - 1;

  return (
    <div className={cn('flex flex-col gap-2 pt-6', className)}>
      <div className="flex items-center justify-between">
        <div>
          {!isFirst && (
            <Button variant="outline" onClick={onBack}>
              {backLabel}
            </Button>
          )}
        </div>
        <div className="flex items-center gap-3">
          {onSkip && (
            <Button variant="ghost" onClick={onSkip} className="text-muted-foreground">
              {skipLabel}
            </Button>
          )}
          <Button onClick={onNext} disabled={isNextDisabled}>
            {isLast ? finishLabel : nextLabel || 'Next'}
          </Button>
        </div>
      </div>
      {isNextDisabled && nextDisabledHint && (
        <p className="text-xs text-muted-foreground text-right">{nextDisabledHint}</p>
      )}
    </div>
  );
}
