import { Box, FormControl, IconButton, InputAdornment, InputBase, SxProps, Theme, Typography, useMediaQuery, useTheme } from "@mui/material";
import { TicketMessage } from "@frontend/kitui";
import { addOrUpdateUnauthMessages, useUnauthTicketStore, incrementUnauthMessageApiPage, setUnauthIsPreventAutoscroll, setUnauthSessionData, setIsMessageSending } from "@root/stores/unauthTicket";
import { enqueueSnackbar } from "notistack";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import ChatMessage from "../ChatMessage";
import SendIcon from "../icons/SendIcon";
import UserCircleIcon from "./UserCircleIcon";
import { throttle } from "@frontend/kitui";
import { makeRequest } from "@frontend/kitui";
import { useTicketMessages, getMessageFromFetchError, useSSESubscription, useEventListener, createTicket } from "@frontend/kitui";


interface Props {
    sx?: SxProps<Theme>;
}

export default function Chat({ sx }: Props) {
    const theme = useTheme();
    const upMd = useMediaQuery(theme.breakpoints.up("md"));
    const [messageField, setMessageField] = useState<string>("");
    const sessionData = useUnauthTicketStore(state => state.sessionData);
    const messages = useUnauthTicketStore(state => state.messages);
    const messageApiPage = useUnauthTicketStore(state => state.apiPage);
    const messagesPerPage = useUnauthTicketStore(state => state.messagesPerPage);
    const isMessageSending = useUnauthTicketStore(state => state.isMessageSending);
    const isPreventAutoscroll = useUnauthTicketStore(state => state.isPreventAutoscroll);
    const lastMessageId = useUnauthTicketStore(state => state.lastMessageId);
    const chatBoxRef = useRef<HTMLDivElement>(null);

    const fetchState = useTicketMessages({
        url: "https://admin.pena.digital/heruvym/getMessages",
        isUnauth: true,
        ticketId: sessionData?.ticketId,
        messagesPerPage,
        messageApiPage,
        onNewMessages: useCallback(messages => {
            if (chatBoxRef.current && chatBoxRef.current.scrollTop < 1) chatBoxRef.current.scrollTop = 1;
            addOrUpdateUnauthMessages(messages);
        }, []),
        onError: useCallback((error: Error) => {
            const message = getMessageFromFetchError(error);
            if (message) enqueueSnackbar(message);
        }, []),
    });

    useSSESubscription<TicketMessage>({
        enabled: Boolean(sessionData),
        url: `https://hub.pena.digital/heruvym/ticket?ticket=${sessionData?.ticketId}&s=${sessionData?.sessionId}`,
        onNewData: addOrUpdateUnauthMessages,
        onDisconnect: useCallback(() => {
            setUnauthIsPreventAutoscroll(false);
        }, []),
        marker: "ticket"
    });

    const throttledScrollHandler = useMemo(() => throttle(() => {
        const chatBox = chatBoxRef.current;
        if (!chatBox) return;

        const scrollBottom = chatBox.scrollHeight - chatBox.scrollTop - chatBox.clientHeight;
        const isPreventAutoscroll = scrollBottom > chatBox.clientHeight;
        setUnauthIsPreventAutoscroll(isPreventAutoscroll);

        if (fetchState !== "idle") return;

        if (chatBox.scrollTop < chatBox.clientHeight) {
            incrementUnauthMessageApiPage();
        }
    }, 200), [fetchState]);

    useEventListener("scroll", throttledScrollHandler, chatBoxRef);

    useEffect(function scrollOnNewMessage() {
        if (!chatBoxRef.current) return;

        if (!isPreventAutoscroll) {
            setTimeout(() => {
                scrollToBottom();
            }, 50);
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [lastMessageId]);

    async function handleSendMessage() {
        if (!messageField || isMessageSending) return;

        if (!sessionData) {
            setIsMessageSending(true);
            createTicket({
                url: "https://hub.pena.digital/heruvym/create",
                body: {
                    Title: "Unauth title",
                    Message: messageField,
                },
                useToken: false,
            }).then(response => {
                setUnauthSessionData({
                    ticketId: response.Ticket,
                    sessionId: response.sess,
                });
            }).catch(error => {
                const errorMessage = getMessageFromFetchError(error);
                if (errorMessage) enqueueSnackbar(errorMessage);
            }).finally(() => {
                setMessageField("");
                setIsMessageSending(false);
            });
        } else {
            setIsMessageSending(true);
            makeRequest({
                url: "https://hub.pena.digital/heruvym/send",
                method: "POST",
                useToken: false,
                body: {
                    ticket: sessionData.ticketId,
                    message: messageField,
                    lang: "ru",
                    files: [],
                },
                withCredentials: true,
            }).catch(error => {
                const errorMessage = getMessageFromFetchError(error);
                if (errorMessage) enqueueSnackbar(errorMessage);
            }).finally(() => {
                setMessageField("");
                setIsMessageSending(false);
            });
        }

    }

    function scrollToBottom(behavior?: ScrollBehavior) {
        if (!chatBoxRef.current) return;

        const chatBox = chatBoxRef.current;
        chatBox.scroll({
            left: 0,
            top: chatBox.scrollHeight,
            behavior,
        });
    }

    const handleTextfieldKeyPress: React.KeyboardEventHandler<HTMLInputElement | HTMLTextAreaElement> = (e) => {
        if (e.key === "Enter" && !e.shiftKey) {
            e.preventDefault();
            handleSendMessage();
        }
    };

    return (
        <Box sx={{
            display: "flex",
            flexDirection: "column",
            height: "clamp(250px, calc(100vh - 90px), 600px)",
            backgroundColor: "#944FEE",
            borderRadius: "8px",
            ...sx,
        }}>
            <Box sx={{
                display: "flex",
                gap: "9px",
                pl: "22px",
                pt: "12px",
                pb: "20px",
                filter: "drop-shadow(0px 3px 12px rgba(37, 39, 52, 0.3))",
            }}>
                <UserCircleIcon />
                <Box sx={{
                    mt: "5px",
                    display: "flex",
                    flexDirection: "column",
                    gap: "3px",
                }}>
                    <Typography>Мария</Typography>
                    <Typography sx={{
                        fontSize: "16px",
                        lineHeight: "19px",
                    }}>онлайн-консультант</Typography>
                </Box>
            </Box>
            <Box sx={{
                flexGrow: 1,
                backgroundColor: "white",
                borderRadius: "8px",
                display: "flex",
                flexDirection: "column",
            }}>
                <Box
                    ref={chatBoxRef}
                    sx={{
                        display: "flex",
                        width: "100%",
                        flexBasis: 0,
                        flexDirection: "column",
                        gap: upMd ? "20px" : "16px",
                        px: upMd ? "20px" : "5px",
                        py: upMd ? "20px" : "13px",
                        overflowY: "auto",
                        flexGrow: 1,
                    }}
                >
                    {sessionData && messages.map((message) => (
                        <ChatMessage
                            unAuthenticated
                            key={message.id}
                            text={message.message}
                            createdAt={message.created_at}
                            isSelf={sessionData.sessionId === message.user_id}
                        />
                    ))}
                </Box>
                <FormControl fullWidth sx={{ borderTop: "1px solid black" }}>
                    <InputBase
                        value={messageField}
                        fullWidth
                        placeholder="Введите сообщение..."
                        id="message"
                        multiline
                        onKeyDown={handleTextfieldKeyPress}
                        sx={{
                            width: "100%",
                            p: 0,
                        }}
                        inputProps={{
                            sx: {
                                fontWeight: 400,
                                fontSize: "16px",
                                lineHeight: "19px",
                                pt: upMd ? "30px" : "28px",
                                pb: upMd ? "30px" : "24px",
                                px: "19px",
                                maxHeight: "calc(19px * 5)",
                                color: "black",
                            },
                        }}
                        onChange={(e) => setMessageField(e.target.value)}
                        endAdornment={
                            <InputAdornment position="end">
                                <IconButton
                                    disabled={isMessageSending}
                                    onClick={handleSendMessage}
                                    sx={{
                                        height: "53px",
                                        width: "53px",
                                        mr: "13px",
                                        p: 0,
                                        opacity: isMessageSending ? 0.3 : 1,
                                    }}
                                >
                                    <SendIcon style={{
                                        width: "100%",
                                        height: "100%",
                                    }} />
                                </IconButton>
                            </InputAdornment>
                        }
                    />
                </FormControl>
            </Box>
        </Box>
    );
}