import { Box, Typography, useTheme } from "@mui/material";
import { useEffect, useState } from "react";
import { useDebouncedCallback } from "use-debounce";

import { CustomSlider } from "@ui_kit/CustomSlider";
import CustomTextField from "@ui_kit/CustomTextField";

import { updateAnswer, useQuizViewStore } from "@stores/quizView/store";

import { sendAnswer } from "@api/quizRelase";
import { enqueueSnackbar } from "notistack";
import type { QuizQuestionNumber } from "../../../model/questionTypes/number";

import { useQuizData } from "@utils/hooks/useQuizData";
import { quizThemes } from "@utils/themes/Publication/themePublication";
import { useQuizId } from "../../../contexts/QuizIdContext";
import { useRootContainerSize } from "../../../contexts/RootContainerWidthContext";

type NumberProps = {
    currentQuestion: QuizQuestionNumber;
};

export const Number = ({ currentQuestion }: NumberProps) => {
    const qid = useQuizId();
    const { settings } = useQuizData();
    const [inputValue, setInputValue] = useState<string>("0");
    const [minRange, setMinRange] = useState<string>("0");
    const [maxRange, setMaxRange] = useState<string>("100000000000");
    const theme = useTheme();
    const { answers } = useQuizViewStore();

    const isMobile = useRootContainerSize() < 650;
    const min = window.Number(currentQuestion.content.range.split("—")[0]);
    const max = window.Number(currentQuestion.content.range.split("—")[1]);

    const sendAnswerToBackend = async (value: string) => {
        try {
            await sendAnswer({
                questionId: currentQuestion.id,
                body: value,
                qid,
            });

            updateAnswer(currentQuestion.id, value, 0);
        } catch (e) {
            enqueueSnackbar("ответ не был засчитан");
        }
    };

    const updateValueDebounced = useDebouncedCallback(async (value: string) => {
        const newValue =
            window.Number(value) < window.Number(minRange)
                ? minRange
                : window.Number(value) > window.Number(maxRange)
                    ? maxRange
                    : value;

        setInputValue(newValue);
        await sendAnswerToBackend(newValue);
    }, 1000);
    const updateMinRangeDebounced = useDebouncedCallback(
        async (value: string, crowded = false) => {
            const newMinValue = crowded
                ? maxRange
                : window.Number(value.split("—")[0]) < min
                    ? String(min)
                    : value.split("—")[0];

            setMinRange(newMinValue);
            await sendAnswerToBackend(`${newMinValue}—${value.split("—")[1]}`);
        },
        1000
    );
    const updateMaxRangeDebounced = useDebouncedCallback(
        async (value: string, crowded = false) => {
            const newMaxValue = crowded
                ? minRange
                : window.Number(value.split("—")[1]) > max
                    ? String(max)
                    : value.split("—")[1];

            setMaxRange(newMaxValue);
            await sendAnswerToBackend(`${value.split("—")[0]}—${newMaxValue}`);
        },
        1000
    );
    const answer = answers.find(
        ({ questionId }) => questionId === currentQuestion.id
    )?.answer as string;

    const sliderValue = answer || currentQuestion.content.start + "—" + max;

    useEffect(() => {
        if (answer) {
            if (answer.includes("—")) {
                setMinRange(answer.split("—")[0]);
                setMaxRange(answer.split("—")[1]);
            } else {
                setInputValue(answer);
            }
        }

        if (!answer) {
            setMinRange(String(currentQuestion.content.start));
            setMaxRange(String(max));
            setInputValue(String(currentQuestion.content.start));
        }
    }, []);

    return (
        <Box>
            <Typography variant="h5" color={theme.palette.text.primary}>
                {currentQuestion.title}
            </Typography>
            <Box
                sx={{
                    display: "flex",
                    flexDirection: "column",
                    width: "100%",
                    marginTop: "20px",
                    gap: "30px",
                    paddingRight: isMobile ? "10px" : undefined,
                }}
            >
                <CustomSlider
                    value={
                        currentQuestion.content.chooseRange
                            ? sliderValue.split("—").length || 0 > 1
                                ? sliderValue.split("—").map((item) => window.Number(item))
                                : [min, min + 1]
                            : window.Number(sliderValue.split("—")[0])
                    }
                    min={min}
                    max={max}
                    step={currentQuestion.content.step || 1}
                    onChange={(_, value) => {
                        const range = Array.isArray(value)
                            ? `${value[0]}—${value[1]}`
                            : String(value);

                        updateAnswer(currentQuestion.id, range, 0);
                    }}
                    onChangeCommitted={async (_, value) => {
                        if (currentQuestion.content.chooseRange && Array.isArray(value)) {
                            setMinRange(String(value[0]));
                            setMaxRange(String(value[1]));
                            await sendAnswerToBackend(`${value[0]}—${value[1]}`);

                            return;
                        }

                        setInputValue(String(value));
                        await sendAnswerToBackend(String(value));
                    }}
                    //@ts-ignore
                    sx={{
                        color: theme.palette.primary.main,
                        "& .MuiSlider-valueLabel": {
                            background: theme.palette.primary.main,
                        },
                    }}
                />

                {!currentQuestion.content.chooseRange && (
                    <CustomTextField
                        placeholder="0"
                        value={inputValue}
                        onChange={({ target }) => {
                            const value = target.value.replace(/\D/g, "");
                            setInputValue(value);
                            updateValueDebounced(value);
                        }}
                        sx={{
                            maxWidth: "80px",
                            borderColor: theme.palette.text.primary,
                            "& .MuiInputBase-input": {
                                textAlign: "center",
                                backgroundColor: quizThemes[settings.cfg.theme].isLight
                                    ? "white"
                                    : theme.palette.background.default,
                            },
                        }}
                    />
                )}

                {currentQuestion.content.chooseRange && (
                    <Box
                        sx={{
                            display: "flex",
                            gap: "15px",
                            alignItems: "center",
                            "& .MuiFormControl-root": { width: "auto" },
                        }}
                    >
                        <CustomTextField
                            placeholder="0"
                            value={minRange}
                            onChange={({ target }) => {
                                const newValue = target.value.replace(/\D/g, "");
                                setMinRange(newValue);

                                if (window.Number(newValue) >= window.Number(maxRange)) {
                                    updateMinRangeDebounced(`${maxRange}—${maxRange}`, true);

                                    return;
                                }

                                updateMinRangeDebounced(`${newValue}—${maxRange}`);
                            }}
                            sx={{
                                maxWidth: "80px",
                                borderColor: theme.palette.text.primary,
                                "& .MuiInputBase-input": {
                                    textAlign: "center",
                                    backgroundColor: quizThemes[settings.cfg.theme].isLight
                                        ? "white"
                                        : theme.palette.background.default,
                                },
                            }}
                        />
                        <Typography color={theme.palette.text.primary}>до</Typography>
                        <CustomTextField
                            placeholder="0"
                            value={maxRange}
                            onChange={({ target }) => {
                                const newValue = target.value.replace(/\D/g, "");
                                setMaxRange(newValue);

                                if (window.Number(newValue) <= window.Number(minRange)) {
                                    updateMaxRangeDebounced(`${minRange}—${minRange}`, true);

                                    return;
                                }

                                updateMaxRangeDebounced(`${minRange}—${newValue}`);
                            }}
                            sx={{
                                maxWidth: "80px",
                                borderColor: theme.palette.text.primary,
                                "& .MuiInputBase-input": {
                                    textAlign: "center",
                                    backgroundColor: quizThemes[settings.cfg.theme].isLight
                                        ? "white"
                                        : theme.palette.background.default,
                                },
                            }}
                        />
                    </Box>
                )}
            </Box>
        </Box>
    );
};
