import { useNavigate, useParams } from "react-router-dom";
import styles from "./styles.module.css";
import { useEffect, useRef, useState } from "react";
import { IAnswer, IQuestion } from "@/data";
import Title from "@/components/Title";
import routes from "@/routes";
import { useDispatch, useSelector } from "react-redux";
import { actions, selectors } from "@/store";
import { IQuestionnaire, selectQuestionnaire } from "@/store/questionnaire";
import { useDynamicSize } from "@/hooks/useDynamicSize";
import BackgroundTopBlob from "../../ui/BackgroundTopBlob";
import Header from "../Header";
import { stepsQuestionary } from "../../data/stepsQuestionary";
import Answer from "../../ui/Answer";
import Stepper from "../Stepper";
import { useLottie } from "@/hooks/lottie/useLottie";
import { useMetricABFlags } from "@/services/metric/metricService.ts";
import { preloadImages } from "@/hooks/preload/images";
import { useTouchAction } from "@/hooks/touchAction/useTouchAction";
import { useTranslations } from "@/hooks/translations";
import { ELocalesPlacement } from "@/locales";

function QuestionnairePage(): JSX.Element {
  const { question, stepId } = useParams();
  const navigate = useNavigate();
  const dispatch = useDispatch();
  const { translate } = useTranslations(ELocalesPlacement.V1);
  const [currentStep, setCurrentStep] = useState<number>();
  const [currentQuestion, setCurrentQuestion] = useState<IQuestion>();
  const [selectedAnswer, setSelectedAnswer] = useState<IAnswer | null>(null);
  const steps = stepsQuestionary.filter((item) => !!item.questions.length);
  const questionsAnswers = useSelector(selectQuestionnaire);
  const { width: pageWidth, elementRef } = useDynamicSize({
    defaultWidth: 393,
  });
  const { gender } = useSelector(selectors.selectQuestionnaire);
  const clickAnswerTimeOutRef = useRef<NodeJS.Timeout>();
  const { flags } = useMetricABFlags();
  const aboutUsAnswersKey = flags?.aboutUsAnswers?.[0];
  useLottie({
    preloadKey: currentQuestion?.lottie?.preloadKey,
  });
  useTouchAction(
    currentQuestion?.answers?.length && currentQuestion?.answers?.length < 3
      ? "none"
      : currentQuestion?.touchAction
  );

  useEffect(() => {
    if (currentQuestion?.preloadImages?.length) {
      preloadImages(currentQuestion.preloadImages);
    }
  }, [currentQuestion]);

  useEffect(() => {
    const currentStepIndex = steps.findIndex((item) => item.id === stepId);
    if (currentStepIndex === -1) return navigate(routes.client.notFound());
    setCurrentStep(currentStepIndex || 0);
    const _currentQuestion = steps[currentStepIndex].questions.find(
      (item) => item.id === question
    );
    if (!_currentQuestion) return navigate(routes.client.genderV1());
    setCurrentQuestion(_currentQuestion);
  }, [navigate, question, stepId, steps]);

  useEffect(() => {
    return clearTimeout(clickAnswerTimeOutRef.current);
  }, []);

  const answerClickHandler = async (answer: IAnswer) => {
    if (!stepId || !question) return;
    const questionIndex = getIndexOfQuestion(question);
    if (questionIndex === -1) return;

    setSelectedAnswer(answer);
    await new Promise(
      (resolve) => (clickAnswerTimeOutRef.current = setTimeout(resolve, 400))
    );

    const currentStepIndex = steps.findIndex((item) => item.id === stepId);

    const questionsLength = steps[currentStepIndex].questions.length;

    const currentQuestion = steps[currentStepIndex].questions[questionIndex];

    dispatch(
      actions.questionnaire.update({
        [currentQuestion.id]: answer.id,
      })
    );
    setSelectedAnswer(null);

    if (answer.navigateToUrl?.length) {
      return navigate(answer.navigateToUrl);
    }

    if (currentQuestion.navigateToUrl?.length) {
      return navigate(currentQuestion.navigateToUrl);
    }

    if (
      currentStepIndex >= steps.length - 1 &&
      questionIndex >= questionsLength - 1
    ) {
      return navigate(routes.client.aboutUsV1(aboutUsAnswersKey));
    }

    if (questionIndex < questionsLength - 1) {
      return navigate(
        `${routes.client.questionnaireV1()}/${steps[currentStepIndex].id}/${
          steps[currentStepIndex].questions[questionIndex + 1].id
        }`
      );
    }

    if (
      currentStepIndex < steps.length - 1 &&
      questionIndex >= questionsLength - 1
    ) {
      return navigate(
        `${routes.client.questionnaireV1()}/${steps[currentStepIndex + 1].id}/${
          steps[currentStepIndex + 1].questions[0].id
        }`
      );
    }
  };

  const getIndexOfQuestion = (questionId: string) => {
    const currentStepIndex = steps.findIndex((item) => item.id === stepId);
    if (currentStepIndex === -1) return -1;
    return steps[currentStepIndex].questions.findIndex(
      (item) => item.id === questionId
    );
  };

  const getPreviousQuestion = () => {
    if (!currentQuestion) return null;
    const currentQuestionIndex = getIndexOfQuestion(currentQuestion.id);
    const currentStepIndex = steps.findIndex((item) => item.id === stepId);
    if (currentQuestionIndex === -1 || currentStepIndex === -1) return null;
    if (currentStepIndex === 0 && currentQuestionIndex === 0) return null;
    if (currentStepIndex > 0 && currentQuestionIndex === 0)
      return steps[currentStepIndex - 1].questions[
        steps[currentStepIndex - 1].questions.length - 1
      ];
    return steps[currentStepIndex].questions[currentQuestionIndex - 1];
  };

  const isShowAnswer = (answer: IAnswer) => {
    const previousQuestion = getPreviousQuestion();
    if (!previousQuestion) return true;
    const previousAnswer =
      questionsAnswers[previousQuestion.id as keyof IQuestionnaire];
    if (!previousAnswer) return true;
    if (!answer.conditionalValues) return true;
    return answer.conditionalValues?.includes(previousAnswer);
  };

  const getBackgroundColor = () => {
    if (currentQuestion?.backgroundColor?.length) {
      return currentQuestion.backgroundColor;
    }
    return gender === "male" ? "#C1E5FF" : "#f7ebff";
  };

  return (
    <section
      className={`${styles.page} page`}
      style={{
        backgroundImage: `url(${currentQuestion?.backgroundImage || ""})`,
        backgroundColor: getBackgroundColor(),
        backgroundBlendMode:
          currentQuestion?.backgroundColor?.length &&
          currentQuestion?.backgroundImage?.length
            ? "multiply"
            : "normal",
      }}
      ref={elementRef}
    >
      <BackgroundTopBlob
        className={styles["background-top-blob"]}
        width={pageWidth}
        height={145}
        cLeftStartX={65}
        cLeft={`C 32 108 11 95 0 87`}
        cRight={`C ${pageWidth - 23} 123 ${pageWidth - 36} 115 ${
          pageWidth - 69
        } 112`}
      />
      <Header className={styles.header} />
      {currentQuestion && (!!currentStep || currentStep === 0) && (
        <>
          <div className={styles["stepper-container"]}>
            <Stepper
              steps={steps}
              currentStep={currentStep}
              currentQuestion={getIndexOfQuestion(currentQuestion.id)}
            />
          </div>
          <span
            className={styles["current-step"]}
            style={{ color: steps[currentStep].color }}
          >
            {translate(steps[currentStep].label)}
          </span>
          <Title
            className={styles.title}
            style={{ color: currentQuestion?.textColor?.title || "#2c2c2c" }}
            variant="h1"
          >
            {translate(currentQuestion.question)}
          </Title>
          {!!currentQuestion.description && (
            <p
              className={styles.description}
              style={{
                color: currentQuestion?.textColor?.description || "#2c2c2c",
              }}
            >
              {translate(currentQuestion.description)}
            </p>
          )}
          <div className={styles["answers-container"]}>
            {!currentQuestion.answersElement &&
              currentQuestion.answers &&
              currentQuestion.answers.map((answer) => {
                if (!isShowAnswer(answer)) return null;
                return (
                  <Answer
                    key={answer.id}
                    answer={answer}
                    classNameContainer={`${
                      selectedAnswer?.id === answer.id
                        ? styles["answer-active"]
                        : ""
                    } ${currentQuestion.answerClassName || ""}`}
                    onClick={() => {
                      answerClickHandler(answer);
                    }}
                  />
                );
              })}
            {!!currentQuestion.answersElement && currentQuestion.answersElement}
          </div>
        </>
      )}
    </section>
  );
}

export default QuestionnairePage;
