import classNames from 'clsx';
import React from 'react';
import { useDispatch } from 'react-redux';
import ReactSwipeableViews from 'react-swipeable-views';

import { endOnboarding } from 'soapbox/actions/onboarding';
import LandingGradient from 'soapbox/components/landing-gradient';
import { HStack } from 'soapbox/components/ui';
import { useFeatures } from 'soapbox/hooks';

import AvatarSelectionStep from './steps/avatar-selection-step';
import BioStep from './steps/bio-step';
import CompletedStep from './steps/completed-step';
import CoverPhotoSelectionStep from './steps/cover-photo-selection-step';
import DisplayNameStep from './steps/display-name-step';
import FediverseStep from './steps/fediverse-step';
import SuggestedAccountsStep from './steps/suggested-accounts-step';

const OnboardingWizard = () => {
  const dispatch = useDispatch();
  const features = useFeatures();

  const [currentStep, setCurrentStep] = React.useState<number>(0);

  const handleSwipe = (nextStep: number) => {
    setCurrentStep(nextStep);
  };

  const handlePreviousStep = () => {
    setCurrentStep((prevStep) => Math.max(0, prevStep - 1));
  };

  const handleNextStep = () => {
    setCurrentStep((prevStep) => Math.min(prevStep + 1, steps.length - 1));
  };

  const handleComplete = () => {
    dispatch(endOnboarding());
  };

  const steps = [
    <AvatarSelectionStep onNext={handleNextStep} />,
    <DisplayNameStep onNext={handleNextStep} />,
    <BioStep onNext={handleNextStep} />,
    <CoverPhotoSelectionStep onNext={handleNextStep} />,
    <SuggestedAccountsStep onNext={handleNextStep} />,
  ];

  if (features.federating){
    steps.push(<FediverseStep onNext={handleNextStep} />);
  }

  steps.push(<CompletedStep onComplete={handleComplete} />);

  const handleKeyUp = ({ key }: KeyboardEvent): void => {
    switch (key) {
      case 'ArrowLeft':
        handlePreviousStep();
        break;
      case 'ArrowRight':
        handleNextStep();
        break;
    }
  };

  const handleDotClick = (nextStep: number) => {
    setCurrentStep(nextStep);
  };

  React.useEffect(() => {
    document.addEventListener('keyup', handleKeyUp);

    return () => {
      document.removeEventListener('keyup', handleKeyUp);
    };
  }, []);

  return (
    <div data-testid='onboarding-wizard'>
      <LandingGradient />

      <main className='h-screen flex flex-col overflow-x-hidden'>
        <div className='flex flex-col justify-center items-center h-full'>
          <ReactSwipeableViews animateHeight index={currentStep} onChangeIndex={handleSwipe}>
            {steps.map((step, i) => (
              <div key={i} className='py-6 sm:mx-auto w-full max-w-[100vw] sm:max-w-lg md:max-w-2xl'>
                <div
                  className={classNames({
                    'transition-opacity ease-linear': true,
                    'opacity-0 duration-500': currentStep !== i,
                    'opacity-100 duration-75': currentStep === i,
                  })}
                >
                  {step}
                </div>
              </div>
            ))}
          </ReactSwipeableViews>

          <HStack space={3} alignItems='center' justifyContent='center' className='relative'>
            {steps.map((_, i) => (
              <button
                key={i}
                tabIndex={0}
                onClick={() => handleDotClick(i)}
                className={classNames({
                  'w-5 h-5 rounded-full focus:ring-primary-600 focus:ring-2 focus:ring-offset-2': true,
                  'bg-gray-300 dark:bg-gray-700 dark:hover:bg-gray-700/75 hover:bg-gray-400': i !== currentStep,
                  'bg-primary-600': i === currentStep,
                })}
              />
            ))}
          </HStack>
        </div>
      </main>
    </div>
  );
};

export default OnboardingWizard;