import { Box, FormControl, IconButton, InputAdornment, InputBase, SxProps, Theme, Typography, useMediaQuery, useTheme } from "@mui/material";
import { createTicket, getTicketMessages, getUnauthTicket, getUnauthTicketMessages, sendTicketMessage, subscribeToUnauthTicketMessages } from "@root/api/tickets";
import { GetMessagesRequest, TicketMessage } from "@root/model/ticket";
import { useMessageStore } from "@root/stores/messages";
import { addOrUpdateUnauthMessages, setUnauthTicket, setUnauthTicketFetchState, setUnauthTicketSessionId, useUnauthTicketStore } from "@root/stores/unauthTicket";
import { enqueueSnackbar } from "notistack";
import { useEffect, useRef, useState } from "react";
import ChatMessage from "../ChatMessage";
import SendIcon from "../icons/SendIcon";
import UserCircleIcon from "./UserCircleIcon";


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 sessionId = useUnauthTicketStore(state => state.sessionId);
    const messages = useUnauthTicketStore(state => state.messages);
    const messageApiPage = useUnauthTicketStore(state => state.apiPage);
    const messagesPerPage = useUnauthTicketStore(state => state.messagesPerPage);
    const messagesFetchStateRef = useRef(useMessageStore.getState().fetchState);
    const chatBoxRef = useRef<HTMLDivElement>();

    useEffect(function fetchTicketMessages() {
        if (!sessionId) return;

        const getTicketsBody: GetMessagesRequest = {
            amt: messagesPerPage,
            page: messageApiPage,
            ticket: sessionId,
        };
        const controller = new AbortController();

        setUnauthTicketFetchState("fetching");
        getUnauthTicketMessages({
            body: getTicketsBody,
            signal: controller.signal,
        }).then(result => {
            console.log("GetMessagesResponse", result);
            if (result?.length > 0) {
                addOrUpdateUnauthMessages(result);
                setUnauthTicketFetchState("idle");
            } else setUnauthTicketFetchState("all fetched");
        }).catch(error => {
            console.log("Error fetching messages", error);
            enqueueSnackbar(error.message);
        });

        return () => {
            controller.abort();
        };
    }, [messageApiPage, messagesPerPage, sessionId]);

    useEffect(function subscribeToMessages() {
        if (!sessionId) return;

        const unsubscribe = subscribeToUnauthTicketMessages({
            sessionId,
            onMessage(event) {
                try {
                    const newMessage = JSON.parse(event.data) as TicketMessage;
                    // console.log("SSE: parsed newMessage:", newMessage);
                    addOrUpdateUnauthMessages([newMessage]);
                } catch (error) {
                    // console.log("SSE: couldn't parse:", event.data);
                    // console.log("Error parsing message SSE", error);
                }
            },
            onError(event) {
                // console.log("SSE Error:", event);
            },
        });

        return () => {
            unsubscribe();
            // clearUnauthTicketState();
        };
    }, [sessionId]);

    useEffect(() => useMessageStore.subscribe(state => (messagesFetchStateRef.current = state.fetchState)), []);

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

        if (!sessionId) {
            const response = await createTicket({
                Title: "Unauth title",
                Message: messageField,
            }, false);

            setUnauthTicketSessionId(response.sess);
        } else {
            sendTicketMessage({
                ticket: sessionId,
                message: messageField,
                lang: "ru",
                files: [],
            }, true);
        }

        setMessageField("");
    }

    return (
        <Box sx={{
            display: "flex",
            flexDirection: "column",
            width: "400px",
            height: "600px",
            backgroundColor: "#944FEE",
            borderRadius: "8px",
            ...sx,
        }}>
            <Box sx={{
                display: "flex",
                gap: "9px",
                pl: "22px",
                pt: "12px",
                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={{
                height: "520px",
                backgroundColor: "white",
                mt: "auto",
                borderRadius: "8px",
                display: "flex",
                flexDirection: "column",

            }}>
                <Box
                    ref={chatBoxRef}
                    sx={{
                        display: "flex",
                        width: "100%",
                        flexDirection: "column",
                        gap: upMd ? "20px" : "16px",
                        px: upMd ? "20px" : "5px",
                        py: upMd ? "20px" : "13px",
                        overflowY: "auto",
                        flexGrow: 1,
                    }}
                >
                    {messages.map((message) => (
                        <ChatMessage
                            unAuthenticated
                            key={message.id}
                            text={message.message}
                            time={new Date(message.created_at).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })}
                            isSelf={sessionId === message.user_id}
                        />
                    ))}
                </Box>
                <FormControl fullWidth sx={{ borderTop: "1px solid black" }}>
                    <InputBase
                        value={messageField}
                        fullWidth
                        placeholder="Введите сообщение..."
                        id="message"
                        multiline
                        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
                                    onClick={handleSendMessage}
                                    sx={{
                                        height: "53px",
                                        width: "53px",
                                        mr: "13px",
                                        p: 0,
                                    }}
                                >
                                    <SendIcon style={{
                                        width: "100%",
                                        height: "100%",
                                    }} />
                                </IconButton>
                            </InputAdornment>
                        }
                    />
                </FormControl>
            </Box>
        </Box>
    );
}