import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import styles from "./styles.module.scss"
import Title from "@/components/Title";
import ProgressBarLine from "@/components/ui/ProgressBarLine";
import { useTranslations } from "@/hooks/translations";
import { ELocalesPlacement } from "@/locales";
import { getRandomArbitrary } from "@/services/random-value";
import { useNavigate } from "react-router-dom";
import routes from "@/routes";
import { useSelector } from "react-redux";
import { selectors } from "@/store";
import { ELottieKeys, useLottie } from "@/hooks/lottie/useLottie";
import { DotLottieReact } from "@lottiefiles/dotlottie-react";
import Modal from "@/components/Modal";
import { ESourceAuthorization } from "@/api/resources/User";
import { useAuthentication } from "@/hooks/authentication/use-authentication";
import { usePreloadImages } from "@/hooks/preload/images";
import { getZodiacSignByDate } from "@/services/zodiac-sign";

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

function Loading() {
    const { translate } = useTranslations(ELocalesPlacement.CompatibilityV4);
    const navigate = useNavigate();
    const { animationData } = useLottie({
        loadKey: ELottieKeys.scannedPhoto,
    });
    const { authorization } = useAuthentication();

    const [isPause, setIsPause] = useState(false);
    const [progress, setProgress] = useState(0);
    const interval = useRef<NodeJS.Timeout>();
    const { whatAddToAnalysis, relationshipStatus } = useSelector(selectors.selectCompatibilityV4Answers);
    const feature = useSelector(selectors.selectFeature);
    const isIOSPath = useMemo(() => feature?.toLowerCase()?.includes("black") || feature?.toLowerCase()?.includes("ios"), [feature]);
    const authCode = useSelector(selectors.selectAuthCode);

    const { gender, partnerGender, birthdate, partnerBirthdate } = useSelector(selectors.selectQuestionnaire);
    const zodiacSign = getZodiacSignByDate(birthdate);
    const partnerZodiacSign = getZodiacSignByDate(partnerBirthdate);
    const isSingle = relationshipStatus === "single";

    const preloadImages = useMemo(() => {
        return [
            "/v4/compatibility/trial-payment/book.png",
            `/zodiac-signs/${gender?.toLowerCase()}/${zodiacSign?.toLowerCase()}.svg`,
            `/zodiac-signs/${partnerGender?.toLowerCase()}/${partnerZodiacSign?.toLowerCase()}.svg`
        ]
    }, [gender, partnerGender, birthdate, partnerBirthdate])

    usePreloadImages(preloadImages)

    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 loadingProfilePoints: IPoint[] = useMemo(() => {
        const titles: IPoint[] = [
            {
                title1: `/loading.loaders${isSingle ? ".single" : ""}.title-1-1`,
                title2: `/loading.loaders${isSingle ? ".single" : ""}.title-1-2`,
                modal: {
                    title: `/loading.modals.title-1`,
                    description: `/loading.modals.description-1`,
                    answerLeft: `/loading.modals.answer-1-left`,
                    answerRight: `/loading.modals.answer-1-right`,
                }
            },
            {
                title1: `/loading.loaders${isSingle ? ".single" : ""}.title-2-1`,
                title2: `/loading.loaders${isSingle ? ".single" : ""}.title-2-2`,
                modal: {
                    title: `/loading.modals.title-2`,
                    description: `/loading.modals.description-2`,
                    answerLeft: `/loading.modals.answer-2-left`,
                    answerRight: `/loading.modals.answer-2-right`,
                }
            },
            {
                title1: `/loading.loaders${isSingle ? ".single" : ""}.title-3-1`,
                title2: `/loading.loaders${isSingle ? ".single" : ""}.title-3-2`,
                modal: {
                    title: `/loading.modals.title-3`,
                    description: `/loading.modals.description-3`,
                    answerLeft: `/loading.modals.answer-3-left`,
                    answerRight: `/loading.modals.answer-3-right`,
                }
            },
        ]
        const whatAddToAnalysisAnswers = whatAddToAnalysis.split(",").slice(0, 3);
        whatAddToAnalysisAnswers.forEach((answer, index) => {
            if (!!answer?.length) {
                titles[index].title3 = `/what-add-to-analysis${isSingle ? ".single" : ""}.${answer}`
            }
        })
        return titles;
    }, [whatAddToAnalysis, isSingle]);

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

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

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

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

    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)]);

    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 getTitle = useCallback((index: number): string => {
        const progressValue = getProgressValue(index);
        if (!!loadingProfilePoints[index].title3) {
            if (progressValue < 34) {
                return loadingProfilePoints[index].title1;
            }
            if (progressValue < 67) {
                return loadingProfilePoints[index].title2;
            }
            return loadingProfilePoints[index].title3 || "";
        }
        return progressValue > 50 ? loadingProfilePoints[index].title2 : loadingProfilePoints[index].title1;
    }, [loadingProfilePoints, getProgressValue]);

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

    return (
        <div className={styles.container}>
            {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>
            )}
            <div className={styles["lottie-animation-container"]}>
                {animationData &&
                    <DotLottieReact
                        className={`${styles["lottie-animation"]} ym-hide-content`}
                        data={animationData}
                        autoplay
                        loop={true}
                        width={323}
                    />}
            </div>
            <div className={styles["points-container"]}>
                {loadingProfilePoints.map((_, 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(getTitle(index))}
                            </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>
        </div>
    )
}

export default Loading