import React from 'react';

import { useLocation, useNavigate } from 'react-router-dom';

import routes from '@/routes';

export enum Step {
  Welcome = 'welcome',
  Gender = 'gender',
  Birthdate = 'birthdate',
  PalmsHold = 'palms-hold',
  Wish = 'wish',
  RelationshipStatus = 'relationship-status',
  ResonatedElement = 'resonated-element',
  ColorYouLike = 'color-you-like',
  Decisions = 'decisions',
  GuidancePlan = 'guidance-plan',
  PersonalStatement = 'personal-statement',
  ScanInfo = 'scan-info',
  Upload = 'upload',
  ScanPhoto = 'scan-photo',
  Email = 'email',
  SubscriptionPlan = 'subscription-plan',
  Paywall = 'paywall',
  Payment = 'payment',
  Discount = 'discount',
  PremiumBundle = 'premium-bundle',
}

export const sortedList = [
  Step.Welcome,
  Step.Gender,
  Step.Birthdate,
  Step.PalmsHold,
  Step.Wish,
  Step.RelationshipStatus,
  Step.ResonatedElement,
  Step.ColorYouLike,
  Step.Decisions,
  Step.GuidancePlan,
  // Step.PersonalStatement,
  Step.ScanInfo,
  Step.Upload,
  Step.ScanPhoto,
  Step.Email,
  Step.SubscriptionPlan,
  Step.Paywall,
  Step.Payment,
  Step.Discount,
  Step.PremiumBundle,
];

export enum GenderChoice {
  Male = 'male',
  Female = 'female',
}

export enum WishChoice {
  Love = 'Love & Relationship',
  Health = 'Health & Vitality',
  Career = 'Career & Destiny',
}

export enum RelationshipStatusChoice {
  Single = 'single',
  InRelationship = 'relationship',
}

export enum ResonatedElementChoice {
  Earth = 'Earth',
  Water = 'Water',
  Fire = 'Fire',
  Air = 'Air',
}

export enum ColorYouLikeChoice {
  Red = 'Red',
  Yellow = 'Yellow',
  Blue = 'Blue',
  Orange = 'Orange',
  Green = 'Green',
  Violet = 'Violet',
}

export enum DecisionsChoice {
  Heart = 'Heart',
  Head = 'Head',
  Both = 'Both',
}

export type Choice = GenderChoice | WishChoice | RelationshipStatusChoice | ResonatedElementChoice | ColorYouLikeChoice | DecisionsChoice;

const buildStoredValues = (value: string | ((s: Step) => string)) => {
  return sortedList.reduce((acc, step) => ({
    ...acc,
    [step]: typeof value === 'function' ? value(step) : value,
  }), {} as Record<Step, string>);
};

export default function useSteps() {
  const { pathname } = useLocation();
  const navigate = useNavigate();
  const pathnameTail = pathname.split('/').pop();
  const current = pathnameTail === 'palmistry' ? Step.Welcome : pathnameTail;
  const list = Object.values(Step);
  const count = list.length - 1;
  const progressBarRange = [1, 10];
  const isWelcome = current === Step.Welcome;
  const defaultStep = Step.Welcome;
  const currentNumber = React.useMemo(() => sortedList.findIndex((s) => s === current), [current]);
  const isInvalid = currentNumber === -1;

  const [isInited, setIsInited] = React.useState(false);
  const [storedValues, setStoredValues] = React.useState(buildStoredValues(''));
  const [firstUnpassedStep, setFirstUnpassedStep] = React.useState<Step | null>(null);

  const getFromStorage = (key: Step | 'firstUnpassedStep') => {
    return localStorage.getItem(`palmistry.${key}`) || '';
  };

  React.useEffect(() => {
    if (pathnameTail === 'palmistry') {
      navigate(routes.client.palmistryWelcome());
    }

    setIsInited(true);
    setStoredValues(buildStoredValues(getFromStorage));
    setFirstUnpassedStep(getFromStorage('firstUnpassedStep') as Step | null);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const getStoredValue = (key: Step) => {
    return storedValues[key] || '';
  };

  function saveToStorage(key: Step | 'firstUnpassedStep', value: string) {
    localStorage.setItem(`palmistry.${key}`, value);
  }

  function getPreviousStep() {
    if (current === Step.ResonatedElement && getStoredValue(Step.Wish) !== WishChoice.Love) {
      return sortedList[currentNumber - 2];
    } else {
      return sortedList[currentNumber - 1];
    }
  }

  function getNextStep(choice?: Choice) {
    if (current === Step.Wish && choice !== WishChoice.Love) {
      return sortedList[currentNumber + 2];
    } else {
      return sortedList[currentNumber + 1];
    }
  }

  function goBack() {
    navigate(`/palmistry/${getPreviousStep()}`);
  }

  function goNext(choice?: Choice) {
    const nextStep = getNextStep();

    setFirstUnpassedStep(nextStep as Step);

    if (sortedList.indexOf(nextStep) > sortedList.indexOf(firstUnpassedStep as Step)) {
      saveToStorage('firstUnpassedStep', nextStep as Step);
    }

    navigate(`/palmistry/${getNextStep(choice)}`);
  }

  function goFirstUnpassedStep(queryParameters = "") {
    if (!firstUnpassedStep) {
      navigate(`/palmistry/${sortedList[0]}?${queryParameters}`);
      return;
    }



    navigate(`/palmistry/${firstUnpassedStep}?${queryParameters}`, {
      state: {
        from: pathname,
      },
    });
  }

  function saveCurrent(value: string) {
    saveToStorage(current as Step, value);
  }

  return {
    isInited,
    current,
    list,
    count,
    progressBarRange,
    isWelcome,
    defaultStep,
    currentNumber,
    isInvalid,
    storedValue: storedValues[current as Step],
    firstUnpassedStep,
    goBack,
    goNext,
    saveToStorage,
    saveCurrent,
    getStoredValue,
    goFirstUnpassedStep,
    setFirstUnpassedStep,
  };
}
