import { useSelector } from "react-redux";
import styles from "./styles.module.scss";
import { selectors } from "@/store";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { IPalmistryLine } from "@/api/resources/Palmistry";
import Title from "@/components/Title";
import { ICompatibilityV2FingerLocal } from "@/store/compatibilityV2";
import { useNavigate, useSearchParams } from "react-router-dom";
import routes from "@/routes";
import ScannedPhotoElement from "@/components/palmistry/scanned-photo/scanned-photo";
import { useTranslations } from "@/hooks/translations";
import { ELocalesPlacement } from "@/locales";
import ProgressBarLine from "@/components/ui/ProgressBarLine";
import Modal from "@/components/Modal";
import { useAuthentication } from "@/hooks/authentication/use-authentication";
import { ESourceAuthorization } from "@/api/resources/User";
import { getRandomArbitrary } from "@/services/random-value";
import { usePreloadImages } from "@/hooks/preload/images";
import metricService, { EGoals, EMetrics } from "@/services/metric/metricService";
import {EUnleashFlags, useUnleash} from "@/hooks/ab/unleash/useUnleash.ts";
import Loader, {LoaderColor} from "@/components/Loader";

const drawElementChangeDelay = 1500;
const startDelay = 500;

interface IPoint {
  title1: string;
  title2: string;
  modal: {
    title: string;
    description: string;
    answerLeft: string;
    answerRight: string;
  }
}

function ScannedPhoto() {
  const { translate } = useTranslations(ELocalesPlacement.CompatibilityV2);
  const navigate = useNavigate();
  const photo = useSelector(selectors.selectCompatibilityV2Photo);
  const fingers = useSelector(selectors.selectCompatibilityV2Fingers);
  const lines = useSelector(selectors.selectCompatibilityV2Lines);

  const { isReady, variant: v2CompatibilityScanResultNumbers } = useUnleash({
    flag: EUnleashFlags.v2CompatibilityScanResultNumbers
  });

  const changeTitleTimeOut = useRef<NodeJS.Timeout>();

  const [currentElementIndex, setCurrentElementIndex] = useState(0);
  const [title, setTitle] = useState("");
  const [shouldDisplayPalmLines, setShouldDisplayPalmLines] = useState(false);
  const [smallPhotoState, setSmallPhotoState] = useState(false);
  const [isDecorationShown, setIsDecorationShown] = useState(true);
  const [searchParams] = useSearchParams();
  const isFromScanHand = searchParams.get("fromScanHand") === "true";

  const [classNameScannedPhoto, setClassNameScannedPhoto] = useState(isFromScanHand ? styles.scannedPhotoFromScanHand : "");

  const feature = useSelector(selectors.selectFeature);
  const isIOSPath = useMemo(() => feature?.toLowerCase()?.includes("black") || feature?.toLowerCase()?.includes("ios"), [feature]);
  const authCode = useSelector(selectors.selectAuthCode);

  const { authorization } = useAuthentication();

  usePreloadImages([
    "/v2/compatibility/download-app.png",
    "/v2/compatibility/love-line.svg",
    "/v2/compatibility/head-line.svg",
    "/v2/compatibility/life-line.svg",
    "/v2/compatibility/fate-line.svg",
    "/v2/compatibility/hand-little-finger.svg",
    "/v2/compatibility/partners.png"
  ])

  const drawElements = useMemo(() => [...fingers, ...lines], [fingers, lines]);

  const { relationshipStatus } = useSelector(selectors.selectCompatibilityV2Answers)

  const loadingProfilePoints: IPoint[] = useMemo(() => {
    const prefix = relationshipStatus === "single" ? "without-partner" : "with-partner";
    return [
      {
        title1: `/scanned-photo.${prefix}.loaders.title-1-1`,
        title2: `/scanned-photo.${prefix}.loaders.title-1-2`,
        modal: {
          title: `/scanned-photo.${prefix}.modals.title-1`,
          description: `/scanned-photo.${prefix}.modals.description-1`,
          answerLeft: `/scanned-photo.${prefix}.modals.answer-1-left`,
          answerRight: `/scanned-photo.${prefix}.modals.answer-1-right`,
        }
      },
      {
        title1: `/scanned-photo.${prefix}.loaders.title-2-1`,
        title2: `/scanned-photo.${prefix}.loaders.title-2-2`,
        modal: {
          title: `/scanned-photo.${prefix}.modals.title-2`,
          description: `/scanned-photo.${prefix}.modals.description-2`,
          answerLeft: `/scanned-photo.${prefix}.modals.answer-2-left`,
          answerRight: `/scanned-photo.${prefix}.modals.answer-2-right`,
        }
      },
      {
        title1: `/scanned-photo.${prefix}.loaders.title-3-1`,
        title2: `/scanned-photo.${prefix}.loaders.title-3-2`,
        modal: {
          title: `/scanned-photo.${prefix}.modals.title-3`,
          description: `/scanned-photo.${prefix}.modals.description-3`,
          answerLeft: `/scanned-photo.${prefix}.modals.answer-3-left`,
          answerRight: `/scanned-photo.${prefix}.modals.answer-3-right`,
        }
      },
    ]
  }, []);

  useEffect(() => {
    metricService.reachGoal(EGoals.CAMERA_HAND, [EMetrics.YANDEX, EMetrics.KLAVIYO]);
  }, [])

  useEffect(() => {
    if (isIOSPath) {
      (async () => {
        await authorization("", ESourceAuthorization["aura.compatibility.v2"], true);
      })();
    }
  }, [isIOSPath, authorization])

  useEffect(() => {
    if (!drawElements[currentElementIndex]) return;
    changeTitleTimeOut.current = setTimeout(() => {
      const title =
        (drawElements[currentElementIndex] as ICompatibilityV2FingerLocal)
          .fingerName || drawElements[currentElementIndex].name;
      setTitle(title);
      if (currentElementIndex < drawElements.length - 1) {
        setCurrentElementIndex((prevState) => prevState + 1);
      }
    }, drawElementChangeDelay);

    return () => {
      if (changeTitleTimeOut.current) {
        clearTimeout(changeTitleTimeOut.current);
      }
    };
  }, [currentElementIndex, drawElements]);

  useEffect(() => {
    if (currentElementIndex < drawElements.length - 1) return;

    const timer = setTimeout(() => {
      setTitle("");
    }, drawElementChangeDelay * 2)

    return () => {
      if (timer) {
        clearTimeout(timer);
      }
    }
  }, [currentElementIndex, drawElements])

  useEffect(() => {
    setShouldDisplayPalmLines(
      lines.includes(drawElements[currentElementIndex] as IPalmistryLine)
    );
  }, [currentElementIndex, drawElements, lines]);

  useEffect(() => {
    if (currentElementIndex < drawElements.length - 1) return;
    const timer = setTimeout(() => {
      setSmallPhotoState(true);
    }, drawElementChangeDelay * 2);
    const goNextTimer = setTimeout(
      () => {
        // navigate(routes.client.compatibilityV2Email())
        setIsDecorationShown(false);
        setClassNameScannedPhoto(styles.scannedPhotoSmall);
      },
      drawElementChangeDelay * drawElements.length + 8000
    );

    return () => {
      if (timer) {
        clearTimeout(timer);
      }
      if (goNextTimer) {
        clearTimeout(goNextTimer);
      }
    };
  }, [currentElementIndex, drawElements.length, navigate]);

  // useEffect(() => {
  //   if (currentElementIndex < drawElements.length) return;
  //   const timer = setTimeout(() => {
  //     // navigate(routes.client.compatibilityV2Email());
  //   }, drawElementChangeDelay + 1000);
  //   return () => clearTimeout(timer);
  // }, [currentElementIndex, drawElements.length, navigate]);


  const [progress, setProgress] = useState(0);
  const [isPause, setIsPause] = useState(false);
  const interval = useRef<NodeJS.Timeout>();

  const loadingPointSettings = useMemo(() => {
    const currentPointIndex = Math.floor(progress / 100);
    const endFastLoading = getRandomArbitrary(15, 30);
    const startFastLoading = getRandomArbitrary(70, 85);
    const pauseLoading = getRandomArbitrary(40, 60);

    return { endFastLoading, pauseLoading, startFastLoading, currentPointIndex };
  }, [Math.floor(progress / 100)])

  const getProgressValue = useCallback(
    (index: number) => {
      const integerDivision = Math.floor(progress / 100);
      if (integerDivision > index) {
        return 100;
      }
      if (integerDivision === index) {
        return progress % 100;
      }
      return 0;
    },
    [progress]
  );

  const onEndLoading = useCallback(() => {
    const isIOS = /iPhone|iPad|iPod/i.test(navigator.userAgent);
    if (isIOSPath && !!authCode && isIOS) {
      return navigate(routes.client.compatibilityV2TryApp());
    }
    navigate(routes.client.compatibilityV2Email());
  }, [isIOSPath, authCode, navigate]);

  useEffect(() => {
    if (progress === 75) {
      setIsPause(true);
    }
    if (progress !== 0 && (progress / 50) % 2 === 1 && progress > 100) {
      return setIsPause(true);
    }
  }, [progress]);


  const getLoadingTime = useCallback((progress: number) => {
    const progressOfCurrentPoint = progress % 100;

    if (progressOfCurrentPoint < loadingPointSettings.endFastLoading) {
      return 40;
    }
    if (progressOfCurrentPoint > loadingPointSettings.startFastLoading) {
      return 40;
    }
    if (progressOfCurrentPoint === loadingPointSettings.pauseLoading) {
      return 3000;
    }
    return 100
  }, [Math.floor(progress / 100)]);

  useEffect(() => {
    const loadingTime = getLoadingTime(progress);
    if (progress >= loadingProfilePoints.length * 100) {
      return onEndLoading();
    }
    interval.current = setTimeout(() => {
      setProgress((prevProgress) => {
        if (!isPause && !isDecorationShown) return prevProgress + 1;
        return prevProgress;
      });
    }, loadingTime);
    return () => {
      clearTimeout(interval.current);
    };
  }, [progress, onEndLoading, isPause, isDecorationShown]);

  const getCurrentIndex = () => {
    return Math.floor(progress / 100);
  };

  if (!isReady) return <Loader color={LoaderColor.Black} />;

  const isShowLineScale = isReady && v2CompatibilityScanResultNumbers === "on";

  return (
    <section className={`${styles.page} palmistry-container_type_scan-photo`}>
      <Title variant="h2" className={styles.title}>
        {title}
      </Title>
      <ScannedPhotoElement
        photo={photo}
        small={smallPhotoState}
        drawElementChangeDelay={drawElementChangeDelay}
        startDelay={startDelay}
        displayLines={shouldDisplayPalmLines}
        lines={lines}
        fingers={fingers}
        drawElements={drawElements}
        className={classNameScannedPhoto}
        isDecorationShown={isDecorationShown}
        isShowLineScale={isShowLineScale}
      />
      <h2
        className={`palmistry-container__waiting-title ${styles.waitingTitle} ${!isDecorationShown ? styles.hidden : ""}`}
        style={{
          animationDelay: `${drawElementChangeDelay * drawElements.length + 2500
            }ms`,
        }}
      >
        {translate("/scanned-photo.title")}
      </h2>

      <h3
        className={`palmistry-container__waiting-description ${styles.waitingDescription} ${!isDecorationShown ? styles.hidden : ""}`}
        style={{
          animationDelay: `${drawElementChangeDelay * drawElements.length + 3000
            }ms`,
        }}
      >
        {translate("/scanned-photo.text")}
      </h3>


      {isPause && (
        <Modal
          isCloseButtonVisible={false}
          open={!!isPause}
          onClose={() => setIsPause(false)}
          className={styles.modal}
          containerClassName={styles["modal-container"]}
        >
          <Title variant="h4" className={styles["modal-title"]}>
            {translate(loadingProfilePoints[getCurrentIndex()].modal.title)}
          </Title>
          <p className={styles["modal-description"]}>
            {translate(loadingProfilePoints[getCurrentIndex()].modal.description)}
          </p>
          <div className={styles["modal-answers"]}>
            <div className={styles["modal-answer"]} onClick={() => setIsPause(false)}>
              <p className={styles["modal-answer-text"]}>
                {translate(loadingProfilePoints[getCurrentIndex()].modal.answerLeft)}
              </p>
            </div>
            <div className={styles["modal-answer"]} onClick={() => setIsPause(false)}>
              <p className={styles["modal-answer-text"]}>
                {translate(loadingProfilePoints[getCurrentIndex()].modal.answerRight)}
              </p>
            </div>
          </div>
        </Modal>
      )}
      {!isDecorationShown && <div className={styles["points-container"]}>
        {loadingProfilePoints.map(({ title1, title2 }, index) => (
          <div
            className={`${styles["point"]} ${getCurrentIndex() === index && styles["active"]
              }`}
            // ref={(el) => (pointsRef.current[index] = el as HTMLDivElement)}
            key={`point-${index}`}
          >
            <div className={styles["point__text-container"]}>
              <Title variant="h2" className={styles["point__title"]}>
                {translate(getProgressValue(index) > 50 ? title2 : title1)}
              </Title>
              <ProgressBarLine
                containerClassName={styles["progress-bar__container"]}
                lineClassName={styles["progress-bar__line"]}
                lineColor={"#275DA7"}
                value={getProgressValue(index)}
                delay={50}
              />
            </div>
            <p
              className={styles["point__percentage"]}
            >
              {getProgressValue(index)}%
            </p>
          </div>
        ))}
      </div>}
    </section >
  );
}

export default ScannedPhoto;
