import { Box, IconButton, InputAdornment, TextField, useMediaQuery, useTheme } from "@mui/material";
import { addOrUpdateMessage, setMessages, useMessageStore } from "@root/stores/messages";
import Message from "./Message";
import SendIcon from "@mui/icons-material/Send";
import AttachFileIcon from "@mui/icons-material/AttachFile";
import { KeyboardEvent, useEffect, useRef, useState } from "react";
import { useParams } from "react-router-dom";
import { GetMessagesRequest, TicketMessage } from "@root/model/ticket";
import { getTicketMessages, sendTicketMessage, subscribeToTicketMessages } from "@root/api/tickets";
import { enqueueSnackbar } from "notistack";
import { useTicketStore } from "@root/stores/tickets";


export default function Chat() {
    const theme = useTheme();
    const upMd = useMediaQuery(theme.breakpoints.up("md"));
    const tickets = useTicketStore(state => state.tickets);
    const messages = useMessageStore(state => state.messages);
    const [messageField, setMessageField] = useState<string>("");
    const ticketId = useParams().ticketId;
    const chatBoxRef = useRef<HTMLDivElement>(null);

    const ticket = tickets.find(ticket => ticket.id === ticketId);

    useEffect(function scrollOnNewMessage() {
        scrollToBottom();
    }, [messages]);

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

        const getTicketsBody: GetMessagesRequest = {
            amt: 100, // TODO use pagination
            page: 0,
            srch: "",
            ticket: ticketId,
        };
        const controller = new AbortController();

        setMessages([]);
        getTicketMessages({
            body: getTicketsBody,
            signal: controller.signal,
        }).then(result => {
            console.log("GetMessagesResponse", result);
            setMessages(result);
        }).catch(error => {
            console.log("Error fetching tickets", error);
            enqueueSnackbar(error.message);
        });

        return () => controller.abort();
    }, [ticketId]);

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

        const token = localStorage.getItem("AT");
        if (!token) return;

        const unsubscribe = subscribeToTicketMessages({
            ticketId,
            accessToken: token,
            onMessage(event) {
                console.log("SSE: message received:", event.data);
                if (event.data === "no tickets 4 user") return;

                try {
                    const newMessage = JSON.parse(event.data) as TicketMessage;
                    console.log("SSE: parsed newMessage:", newMessage);
                    addOrUpdateMessage([newMessage]);
                } catch (error) {
                    console.log("Error parsing message SSE", error);
                }
            },
            onError(event) {
                console.log("SSE Error:", event);
            },
        });

        return () => {
            unsubscribe();
        };
    }, [ticketId]);

    function scrollToBottom() {
        if (!chatBoxRef.current) return;

        chatBoxRef.current.scroll({
            left: 0,
            top: chatBoxRef.current.scrollHeight,
            behavior: "smooth",
        });
    }

    function handleSendMessage() {
        if (!ticketId || !messageField) return;

        sendTicketMessage({
            body: {
                files: [],
                lang: "ru",
                message: messageField,
                ticket: ticketId,
            }
        });
        setMessageField("");
    }

    function handleAddAttachment() {

    }

    function handleTextfieldKeyPress(e: KeyboardEvent) {
        if (e.key === "Enter" && !e.shiftKey) {
            e.preventDefault();
            handleSendMessage();
        }
    }

    const sortedMessages = messages.sort(sortMessagesByTime);

    return (
        <Box sx={{
            border: "1px solid",
            borderColor: theme.palette.grayDark.main,
            height: "600px",
            borderRadius: "3px",
            p: "8px",
            display: "flex",
            flex: upMd ? "2 0 0" : undefined,
            flexDirection: "column",
            gap: "8px",
        }}>
            <Box
                ref={chatBoxRef}
                sx={{
                    backgroundColor: "#46474a",
                    flexGrow: 1,
                    display: "flex",
                    flexDirection: "column",
                    gap: "12px",
                    p: "8px",
                    overflow: "auto",
                    colorScheme: "dark",
                }}
            >
                {ticket && sortedMessages.map(message =>
                    <Message key={message.id} message={message} isSelf={ticket.user !== message.user_id} />
                )}
            </Box>
            <TextField
                value={messageField}
                onChange={e => setMessageField(e.target.value)}
                onKeyPress={handleTextfieldKeyPress}
                id="message-input"
                placeholder="Написать сообщение"
                fullWidth
                multiline
                maxRows={8}
                InputProps={{
                    style: {
                        backgroundColor: theme.palette.content.main,
                        color: theme.palette.secondary.main,
                    },
                    endAdornment: (
                        <InputAdornment position="end">
                            <IconButton
                                onClick={handleSendMessage}
                                sx={{
                                    height: "45px",
                                    width: "45px",
                                    p: 0,
                                }}
                            >
                                <SendIcon sx={{ color: theme.palette.golden.main }} />
                            </IconButton>
                            <IconButton
                                onClick={handleAddAttachment}
                                sx={{
                                    height: "45px",
                                    width: "45px",
                                    p: 0,
                                }}
                            >
                                <AttachFileIcon sx={{ color: theme.palette.golden.main }} />
                            </IconButton>
                        </InputAdornment>
                    )
                }}
                InputLabelProps={{
                    style: {
                        color: theme.palette.secondary.main,
                    }
                }}
            />
        </Box>
    );
}

function sortMessagesByTime(message1: TicketMessage, message2: TicketMessage) {
    const date1 = new Date(message1.created_at).getTime();
    const date2 = new Date(message2.created_at).getTime();
    return date1 - date2;
}