import {
    Box,
    ButtonBase,
    IconButton,
    Modal,
    Skeleton,
    Typography,
    useTheme
} from "@mui/material";
import { useQuizViewStore } from "@stores/quizView";

import CloseBold from "@icons/CloseBold";
import UploadIcon from "@icons/UploadIcon";

import { sendAnswer, sendFile } from "@api/quizRelase";
import { useQuizData } from "@contexts/QuizDataContext";
import Info from "@icons/Info";
import { enqueueSnackbar } from "notistack";
import { useState } from "react";
import { useRootContainerSize } from "../../../contexts/RootContainerWidthContext";
import type { QuizQuestionFile } from "../../../model/questionTypes/file";
import { ACCEPT_SEND_FILE_TYPES_MAP, MAX_FILE_SIZE, UPLOAD_FILE_DESCRIPTIONS_MAP } from "../tools/fileUpload";

type ModalWarningType = "errorType" | "errorSize" | "picture" | "video" | "audio" | "document" | null;

type FileProps = {
    currentQuestion: QuizQuestionFile;
};

export const File = ({ currentQuestion }: FileProps) => {
    const theme = useTheme();
    const answers = useQuizViewStore(state => state.answers);
    const updateAnswer = useQuizViewStore(state => state.updateAnswer);
    const { quizId, preview } = useQuizData();
    const [modalWarningType, setModalWarningType] = useState<ModalWarningType>(null);
    const [isSending, setIsSending] = useState<boolean>(false);
    const [isDropzoneHighlighted, setIsDropzoneHighlighted] = useState<boolean>(false);
    const isMobile = useRootContainerSize() < 500;

    const answer = answers.find(
        ({ questionId }) => questionId === currentQuestion.id
    )?.answer as string;

    const uploadFile = async (file: File | undefined) => {
        if (isSending) return;
        if (!file) return;
        console.log(file.size);
        console.log(MAX_FILE_SIZE);
        if (file.size > MAX_FILE_SIZE) return setModalWarningType("errorSize");

        const isFileTypeAccepted = ACCEPT_SEND_FILE_TYPES_MAP[currentQuestion.content.type].some(
            fileType => file.name.toLowerCase().endsWith(fileType)
        );

        if (!isFileTypeAccepted) return setModalWarningType("errorType");

        setIsSending(true);
        try {
            const data = await sendFile({
                questionId: currentQuestion.id,
                body: {
                    file: file,
                    name: file.name,
                    preview
                },
                qid: quizId,
            });
            console.log(data);

            await sendAnswer({
                questionId: currentQuestion.id,
                body: `https://storage.yandexcloud.net/squizanswer/${quizId}/${currentQuestion.id}/${data!.data.fileIDMap[currentQuestion.id]}`,
                qid: quizId,
                preview
            });

            updateAnswer(currentQuestion.id, `${file.name}|${URL.createObjectURL(file)}`, 0);
        } catch (e) {
            console.log(e);
            enqueueSnackbar("ответ не был засчитан");
        }

        setIsSending(false);
    };

    const onDrop = (event: React.DragEvent<HTMLDivElement>) => {
        event.preventDefault();
        setIsDropzoneHighlighted(false);

        const file = event.dataTransfer.files[0];

        uploadFile(file);
    };

    return (
        <Box>
            <Typography
                variant="h5"
                color={theme.palette.text.primary}
                sx={{ wordBreak: "break-word" }}
            >{currentQuestion.title}</Typography>
            <Box
                sx={{
                    display: "flex",
                    flexDirection: "column",
                    width: "100%",
                    marginTop: "20px",
                    maxWidth: answer?.split("|")[0] ? "640px" : "600px",
                }}
            >
                {answer?.split("|")[0] ? (
                    <Box sx={{ display: "flex", alignItems: "center", gap: "15px" }}>
                        <Typography color={theme.palette.text.primary}>Вы загрузили:</Typography>
                        <Box
                            sx={{
                                padding: "5px 5px 5px 16px",
                                backgroundColor: theme.palette.primary.main,
                                borderRadius: "8px",
                                color: "#FFFFFF",
                                display: "flex",
                                alignItems: "center",
                                overflow: "hidden",
                                gap: "15px",
                            }}
                        >
                            <Typography
                                sx={{
                                    whiteSpace: "nowrap",
                                    textOverflow: "ellipsis",
                                    overflow: "hidden",
                                }}
                            >
                                {answer?.split("|")[0]}</Typography>
                            <IconButton
                                sx={{ p: 0 }}
                                onClick={async () => {
                                    if (answer.length > 0) {
                                        setIsSending(true);
                                        await sendAnswer({
                                            questionId: currentQuestion.id,
                                            body: "",
                                            qid: quizId,
                                            preview
                                        });
                                    }
                                    console.log(answer);
                                    updateAnswer(currentQuestion.id, "", 0);
                                    setIsSending(false);
                                }}
                            >
                                <CloseBold />
                            </IconButton>
                        </Box>
                    </Box>
                ) : (
                    <Box
                        sx={{
                            display: "flex",
                            alignItems: "center"
                        }}
                    >
                        {isSending ?
                            <Skeleton
                                variant="rounded"
                                sx={{
                                    width: "100%",
                                    height: "120px",
                                    maxWidth: "560px",
                                }}
                            />
                            :
                            <ButtonBase
                                component="label"
                                sx={{ justifyContent: "flex-start", width: "100%" }}
                            >
                                <input
                                    onChange={e => uploadFile(e.target.files?.[0])}
                                    hidden
                                    accept={ACCEPT_SEND_FILE_TYPES_MAP[currentQuestion.content.type].join(",")}
                                    multiple
                                    type="file"
                                />
                                <Box
                                    onDragEnter={() => !answer?.split("|")[0] && setIsDropzoneHighlighted(true)}
                                    onDragLeave={() => setIsDropzoneHighlighted(false)}
                                    onDragOver={(e) => e.preventDefault()}
                                    onDrop={onDrop}
                                    sx={{
                                        width: "100%",
                                        height: isMobile ? undefined : "120px",
                                        display: "flex",
                                        gap: "50px",
                                        justifyContent: "flex-start",
                                        alignItems: "center",
                                        padding: "33px 44px 33px 55px",
                                        backgroundColor: "#F2F3F7",
                                        border: `1px solid ${isDropzoneHighlighted ? "red" : "#9A9AAF"}`,
                                        borderRadius: "8px",
                                    }}
                                >
                                    <UploadIcon />
                                    <Box>
                                        <Typography
                                            sx={{
                                                color: "#9A9AAF",
                                                // color: theme.palette.grey2.main,
                                                fontWeight: 500,
                                            }}
                                        >
                                            {UPLOAD_FILE_DESCRIPTIONS_MAP[currentQuestion.content.type].title}
                                        </Typography>
                                        <Typography
                                            sx={{
                                                color: "#9A9AAF",
                                                // color: theme.palette.grey2.main,
                                                fontSize: "16px",
                                                lineHeight: "19px",
                                            }}
                                        >
                                            {UPLOAD_FILE_DESCRIPTIONS_MAP[currentQuestion.content.type].description}
                                        </Typography>
                                    </Box>
                                </Box>
                            </ButtonBase>
                        }
                        <Info
                            sx={{ width: "40px", height: "40px" }}
                            color={theme.palette.primary.main}
                            onClick={() => setModalWarningType(currentQuestion.content.type)}
                        />
                    </Box>
                )}
                {answer && currentQuestion.content.type === "picture" && (
                    <img
                        src={answer.split("|")[1]}
                        alt=""
                        style={{
                            marginTop: "15px",
                            maxWidth: "300px",
                            maxHeight: "300px",
                        }}
                    />
                )}
                {answer && currentQuestion.content.type === "video" && (
                    <video
                        src={answer.split("|")[1]}
                        style={{
                            marginTop: "15px",
                            maxWidth: "300px",
                            maxHeight: "300px",
                            objectFit: "cover",
                        }}
                    />
                )}
            </Box>
            <Modal
                open={modalWarningType !== null}
                onClose={() => setModalWarningType(null)}
            >
                <Box sx={{
                    position: 'absolute',
                    top: '50%',
                    left: '50%',
                    transform: 'translate(-50%, -50%)',
                    width: isMobile ? 300 : 400,
                    bgcolor: 'background.paper',
                    borderRadius: 3,
                    boxShadow: 24,
                    p: 4,
                }}>
                    <CurrentModal status={modalWarningType} />
                </Box>
            </Modal>
        </Box>
    );
};

const CurrentModal = ({ status }: { status: ModalWarningType; }) => {

    switch (status) {
        case null: return null;
        case 'errorType': return <Typography>Выбран некорректный тип файла</Typography>;
        case 'errorSize': return <Typography>Файл слишком большой. Максимальный размер 50 МБ</Typography>;
        default: return (
            <>
                <Typography>Допустимые расширения файлов:</Typography>
                <Typography>{
                    ACCEPT_SEND_FILE_TYPES_MAP[status].join(" ")}</Typography>
            </>
        );
    }
};
