
import Modal from "@/components/Modal";
import styles from "../styles.module.scss";
import Title from "@/components/Title";
import { useTranslations } from "@/hooks/translations";
import { ELocalesPlacement } from "@/locales";
import Loader, { LoaderColor } from "@/components/Loader";
import { useEffect, useState } from "react";
import CameraModal from "@/components/CompatibilityV2/components/CameraModal";
import { useNavigate } from "react-router-dom";
import routes from "@/routes";
import Toast from "@/components/pages/ABDesign/v1/components/Toast";
import { DataURIToBlob } from "@/services/data";
import { actions } from "@/store";
import { IPalmistryFinger, IPalmistryLine } from "@/api/resources/Palmistry";
import { ICompatibilityV2FingerLocal } from "@/store/compatibilityV2";
import { useApi } from "@/api";
import { useDispatch } from "react-redux";
import metricService, { EGoals, EMetrics } from "@/services/metric/metricService";
import { EUnleashFlags, useUnleash } from "@/hooks/ab/unleash/useUnleash";

enum EToastVisible {
    "try_again" = "try_again",
    "try_again_or_next" = "try_again_or_next",
    "no_access_camera" = "no_access_camera",
    "reload_page" = "reload_page",
    "turn_hand" = "turn_hand",
}

function IphoneCamera() {
    const api = useApi();
    const dispatch = useDispatch();
    const { translate } = useTranslations(ELocalesPlacement.CompatibilityV2);
    const navigate = useNavigate();

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

    const isShowCameraRequestModal = cameraRequestModalCompatibilityV2 !== "hide";

    const { variant: compatibilityV2ScanHand } = useUnleash({
        flag: EUnleashFlags.compatibilityV2ScanHand
    });

    const { variant: v2CompatibilityCameraTemplate = "v0" } = useUnleash({
        flag: EUnleashFlags.v2CompatibilityCameraTemplate
    });
    console.log("v2CompatibilityCameraTemplate: ", v2CompatibilityCameraTemplate)

    const isShowScanHand = compatibilityV2ScanHand !== "hide";

    const [isLoading, setIsLoading] = useState(false);
    const [isRequestCameraModalOpen, setIsRequestCameraModalOpen] = useState(isShowCameraRequestModal);
    const [isCameraModalOpen, setIsCameraModalOpen] = useState(false);
    const [reinitializeCameraCount, setReinitializeCameraCount] = useState(0);
    const [toastVisible, setToastVisible] = useState<EToastVisible | null>(null);
    const [isMediaPipeInit, setIsMediaPipeInit] = useState(true);

    const handleToScanHand = () => {
        metricService.reachGoal(EGoals.SCAN_ARTIFICIAL_PHOTO, [EMetrics.YANDEX, EMetrics.KLAVIYO]);
        return navigate(routes.client.compatibilityV2ScanHand())
    }

    const handleToScannedPhoto = () => {
        metricService.reachGoal(EGoals.CAMERA_SUCCESS, [EMetrics.YANDEX, EMetrics.KLAVIYO]);
        return navigate(routes.client.compatibilityV2ScannedPhoto())
    }

    const handleCameraError = (error: string | DOMException) => {
        console.log("camera error: ", error)
        if (reinitializeCameraCount < 2 && !String(error).includes("NotAllowedError")) {
            setToastVisible(EToastVisible.no_access_camera)
        } else {
            if (!isShowScanHand) {
                return setToastVisible(EToastVisible.reload_page)
            }
            return handleToScanHand()
        }
    }

    const handleCameraSuccess = (photo: string) => {
        onTakePhoto(photo)
    }


    const handleRequestCameraModalCancel = () => {
        setIsRequestCameraModalOpen(false)
        setToastVisible(EToastVisible.no_access_camera)
    }

    const handleRequestCameraModalAllow = () => {
        setIsRequestCameraModalOpen(false)
        handleRequestCamera()
    }

    const handleRequestCamera = () => {
        setToastVisible(null)
        if (!isCameraModalOpen) {
            return setIsCameraModalOpen(true)
        }
        setReinitializeCameraCount(prev => prev + 1)
    }

    const handleTryAgain = () => {
        setToastVisible(null)
        // setReinitializeCameraCount(prev => prev + 1)
    }

    useEffect(() => {
        if (!isShowCameraRequestModal) {
            setIsCameraModalOpen(true)
        }
    }, [isShowCameraRequestModal])

    // LOGIC TODO: Make hook

    const onTakePhoto = async (photo: string) => {
        try {
            const file = DataURIToBlob(photo);

            const result = await getLines(file);

            URL.revokeObjectURL(URL.createObjectURL(file));

            dispatch(
                actions.compatibilityV2.update({
                    photo,
                })
            );
            if (!checkPalmistryLines(result?.lines || [])) return;
            handleToScannedPhoto();
        } catch (error) {
            console.error('Ошибка при обработке фото:', error);
        } finally {
            // Принудительный запуск сборщика мусора (не гарантировано, но может помочь)
            if (window.gc) {
                window.gc();
            }
        }
    };

    const fingersNames = {
        thumb: translate("thumb"),
        index_finger: translate("index_finger"),
        middle_finger: translate("middle_finger"),
        ring_finger: translate("ring_finger"),
        pinky: translate("pinky"),
    };

    const setFingersNames = (
        fingers: IPalmistryFinger[]
    ): ICompatibilityV2FingerLocal[] => {
        if (!fingers) return [];
        return fingers.map((finger) => {
            return {
                ...finger,
                fingerName: fingersNames[finger.name as keyof typeof fingersNames],
            };
        });
    };

    const getLines = async (file: File | Blob) => {
        setIsLoading(true);
        const formData = new FormData();
        formData.append("file", file);
        try {
            const result = await api.getPalmistryLines({ formData });
            const fingers = setFingersNames(result?.fingers);

            dispatch(
                actions.compatibilityV2.update({
                    lines: result?.lines,
                    fingers,
                })
            );
            return result;
        } catch (error) {
            dispatch(
                actions.compatibilityV2.update({
                    lines: [],
                    fingers: [],
                })
            );
            return null;
        } finally {
            setIsLoading(false);
        }
    };

    const checkPalmistryLines = (lines: IPalmistryLine[]): boolean => {
        if (!lines.length || lines.length < 2) {
            metricService.reachGoal(EGoals.CAMERA_ERROR, [EMetrics.YANDEX, EMetrics.KLAVIYO]);
            setToastVisible(EToastVisible.try_again);
            return false;
        }
        if (lines.length === 2) {
            setToastVisible(EToastVisible.try_again_or_next);
            return false;
        }
        return true;
    };

    const onSelectFile = async (event: React.ChangeEvent<HTMLInputElement>) => {
        setToastVisible(null);
        if (!event.target.files || event.target.files.length === 0) return;

        const result = await getLines(event.target.files[0]);

        const reader = new FileReader();

        reader.onloadend = () => {
            dispatch(
                actions.compatibilityV2.update({
                    photo: reader.result as string,
                })
            );
            if (!checkPalmistryLines(result?.lines || [])) return;
            handleToScannedPhoto();
        };

        reader.readAsDataURL(event.target.files[0]);
    };

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

    return (
        <>
            {/* Модальное окно запроса камеры */}
            <Modal
                isCloseButtonVisible={false}
                open={isRequestCameraModalOpen}
                onClose={() => { }}
                className={styles.modal}
                containerClassName={styles["modal-container"]}
            >
                <Title variant="h4" className={styles["modal-title"]}>
                    {translate("/camera.modal.title")}
                </Title>
                <div className={styles["modal-answers"]}>
                    <div className={styles["modal-answer"]} onClick={handleRequestCameraModalCancel}>
                        <p className={styles["modal-answer-text"]}>
                            {translate("/camera.modal.cancel")}
                        </p>
                    </div>
                    <div className={styles["modal-answer"]} onClick={handleRequestCameraModalAllow}>
                        <p className={styles["modal-answer-text"]}>
                            {translate("/camera.modal.allow")}
                        </p>
                    </div>
                </div>
            </Modal>

            {/* Модальное окно камеры */}
            {/* {!isLoading && ( */}
            <CameraModal
                onClose={() => console.log("close")}
                onTakePhoto={handleCameraSuccess}
                onError={handleCameraError}
                isShowHand={v2CompatibilityCameraTemplate !== "v1"}
                isMediaPipe={["v2", "v3", "v4"].includes(v2CompatibilityCameraTemplate)}
                mediaPipeRenderingTemplate={v2CompatibilityCameraTemplate as "v2" | "v3" | "v4"}
                onMediaPipeInitChange={(status) => setIsMediaPipeInit(status)}
                isCameraVisible={isCameraModalOpen}
                reinitializeKey={reinitializeCameraCount}
                className={(isLoading || !isMediaPipeInit) ? styles.hideCameraModal : ""}
                onIsFacingCameraChange={(isFacingCamera) => {
                    if (!isFacingCamera) {
                        setToastVisible(EToastVisible.turn_hand)
                    } else {
                        setToastVisible(null)
                    }
                }}
            />
            {/* )} */}

            {/* Лоадер */}
            {(isLoading || !isMediaPipeInit) && (
                <Loader className={styles.loader} color={LoaderColor.Black} />
            )}

            {/* Тост если фото плохое */}
            {toastVisible === EToastVisible.try_again && (
                <Toast classNameContainer={styles["toast-container"]} variant="error">
                    <div className={styles["toast-content"]}>
                        <span>{translate("/camera.bad_photo")}</span>
                        <div className={styles["toast-buttons-container"]}>
                            <button onClick={handleTryAgain}>
                                {translate("/camera.try_again")}
                            </button>
                            <button className={styles.buttonUpload}>
                                <input
                                    id="upload-input"
                                    type="file"
                                    accept="image/*"
                                    style={{ display: 'none' }}
                                    onChange={onSelectFile}
                                />
                                <label htmlFor="upload-input" className={styles.labelUpload}>
                                    {translate("/camera.upload")}
                                </label>
                            </button>
                        </div>
                    </div>
                </Toast>
            )}

            {/* Тост если нет доступа к камере */}
            {toastVisible === EToastVisible.no_access_camera && (
                <Toast classNameContainer={styles["toast-container"]} variant="error">
                    <div className={styles["toast-content"]}>
                        <span>{translate("/camera.no_access_camera")}</span>
                        <div className={styles["toast-buttons-container"]}>
                            <button onClick={handleRequestCamera}>
                                {translate("/camera.give_access")}
                            </button>
                            <button className={styles.buttonUpload}>
                                <input
                                    id="upload-input"
                                    type="file"
                                    accept="image/*"
                                    style={{ display: 'none' }}
                                    onChange={onSelectFile}
                                />
                                <label htmlFor="upload-input" className={styles.labelUpload}>
                                    {translate("/camera.upload")}
                                </label>
                            </button>
                        </div>
                    </div>
                </Toast>
            )}

            {/* Тост если фото можно улучшить */}
            {toastVisible === EToastVisible.try_again_or_next && (
                <Toast classNameContainer={styles["toast-container"]} variant="error">
                    <div
                        className={styles["toast-content"]}
                        style={{ flexDirection: "column" }}
                    >
                        <span>{translate("/camera.do_better")}</span>
                        <div className={styles["buttons-container"]}>
                            <button onClick={handleTryAgain}>
                                {translate("/camera.try_again")}
                            </button>
                            <button onClick={handleToScannedPhoto}>
                                {translate("/camera.next")}
                            </button>
                        </div>
                    </div>
                </Toast>
            )}

            {/* Тост если нужно перезагрузить страницу */}
            {toastVisible === EToastVisible.reload_page && (
                <Toast classNameContainer={styles["toast-container"]} variant="error">
                    <div className={styles["toast-content"]}>
                        <span>{translate("/camera.reload_page")}</span>
                        <button onClick={() => {
                            setToastVisible(null)
                            window.location.reload()
                        }}>
                            {translate("/camera.reload_page_button")}
                        </button>
                    </div>
                </Toast>
            )}

            {/* Тост если нужно повернуть руку */}
            {toastVisible === EToastVisible.turn_hand && (
                <Toast classNameContainer={styles["toast-container"]} variant="error">
                    <div
                        className={styles["toast-content"]}
                        style={{ flexDirection: "column" }}
                    >
                        <span>{translate("/camera.turn_hand")}</span>
                    </div>
                </Toast>
            )}
        </>
    )
}

export default IphoneCamera;