import {
  createContext,
  type PropsWithChildren,
  useContext,
  useState,
} from 'react';
import { useFormContext } from 'react-hook-form';
import { useMatch, useParams } from 'react-router';

import { PathSteps } from 'src/pages/dashboard/Learning/Paths/constants';
import {
  type NewPathFormValues,
  type PathStepsType,
} from 'src/pages/dashboard/Learning/Paths/types';
import { useLokaliseTranslation } from 'src/utils/i18n';

import { pathsRoutes } from '../routes';

type StepAction = {
  show: boolean;
  disabled: boolean;
  buttonText: string;
  handle: () => void;
};

type NewStep = {
  id: PathStepsType;
  title: string;
};

type NewCurrentStep = {
  value: number;
  id: PathStepsType;
};

type NewStepperValue = {
  currentStep: NewCurrentStep;
  steps: NewStep[];
  back: StepAction;
  next: StepAction;
  setStep: (step: PathStepsType) => void;
  isLastStep: boolean;
  isFirstStep: boolean;
};

const ACTION_DEFAULT = {
  show: false,
  disabled: false,
  handle: () => null,
  buttonText: '',
};

const NewStepperContext = createContext({
  currentStep: {
    id: PathSteps.BASIC_INFORMATION,
    value: 0,
  },
  steps: [],
  back: ACTION_DEFAULT,
  next: ACTION_DEFAULT,
  setStep: () => null,
  isLastStep: false,
  isFirstStep: true,
} as NewStepperValue);

export const NewStepperProvider = ({ children }: PropsWithChildren) => {
  const { t } = useLokaliseTranslation('learning');
  const [currentValue, setCurrentValue] = useState(0);
  const { getValues } = useFormContext<NewPathFormValues>();
  const status = getValues('basic_information.status');
  const params = useParams();
  const pathId = params.id ? parseInt(params.id) : undefined;
  const isEditPath = pathId ? useMatch(pathsRoutes.edit(pathId)) : false;

  const steps = Object.values(PathSteps).map(step => ({
    id: step,
    title: t(`common.${step}`),
  }));

  const handleBack = () => setCurrentValue(Math.max(currentValue - 1, 0));
  const handleNext = () =>
    setCurrentValue(Math.min(currentValue + 1, steps.length - 1));

  const setStep = (step: PathStepsType) => {
    setCurrentValue(steps.findIndex(s => s.id === step));
  };

  const lastStep = steps.length - 1;

  const isLastStep = currentValue === lastStep;
  const isFirstStep = currentValue === 0;

  const nextButtonText = () => {
    if (!isLastStep) return t('general:next');
    if (isEditPath && status === 'ACTIVE') return t('general:save_changes');
    return t('path.publish.title');
  };

  return (
    <NewStepperContext.Provider
      value={{
        currentStep: {
          value: currentValue,
          id: steps[currentValue].id,
        },
        steps,
        back: {
          handle: handleBack,
          show: currentValue > 0,
          buttonText: t('general:back'),
          disabled: false,
        },
        next: {
          handle: handleNext,
          show: currentValue <= lastStep,
          buttonText: nextButtonText(),
          disabled: false,
        },
        setStep,
        isLastStep,
        isFirstStep,
      }}
    >
      {children}
    </NewStepperContext.Provider>
  );
};

export const useNewPathStepper = () => useContext(NewStepperContext);
