import { useCallback, useEffect, useMemo, useState } from "react";
import {
  TicketMessage,
  createTicket,
  shownMessage,
  useSSESubscription,
  useTicketMessages,
  useTicketsFetcher,
  sendFile as sf
} from "@frontend/kitui";
import FloatingSupportChat from "./FloatingSupportChat";
import { useUserStore } from "@root/user";
import { useSSETab } from "../../utils/hooks/useSSETab";
import {
  addOrUpdateUnauthMessages,
  cleanAuthTicketData,
  cleanUnauthTicketData,
  setIsMessageSending,
  setTicketData,
  setUnauthIsPreventAutoscroll,
  setUnauthTicketMessageFetchState,
  useTicketStore,
} from "@root/ticket";
import { enqueueSnackbar } from "notistack";
import { parseAxiosError } from "@utils/parse-error";
import { selectSendingMethod } from "./utils";

type ModalWarningType =
  | "errorType"
  | "errorSize"
  | "picture"
  | "video"
  | "audio"
  | "document"
  | null;
const MAX_FILE_SIZE = 419430400;
const ACCEPT_SEND_FILE_TYPES_MAP = [
  ".jpeg",
  ".jpg",
  ".png",
  ".mp4",
  ".doc",
  ".docx",
  ".pdf",
  ".txt",
  ".xlsx",
  ".csv",
] as const;

export default () => {
  const user = useUserStore((state) => state.user?._id);
  const ticket = useTicketStore(state => state[user ? "authData" : "unauthData"]);

  //Запись SEE в учётник
  const { isActiveSSETab, updateSSEValue } = useSSETab<TicketMessage[]>(
    "ticket",
    addOrUpdateUnauthMessages,
  );

  const [modalWarningType, setModalWarningType] =
    useState<ModalWarningType>(null);
  const [isChatOpened, setIsChatOpened] = useState<boolean>(false);
  const [sseEnabled, setSseEnabled] = useState(true);

  const handleChatClickOpen = () => {
    setIsChatOpened(true);
  };
  const handleChatClickClose = () => {
    setIsChatOpened(false);
  };
  const handleChatClickSwitch = () => {
    setIsChatOpened((state) => !state);
  };


  useTicketMessages({
    url: `${process.env.REACT_APP_DOMAIN}/heruvym/v1.0.0/getMessages`,
    isUnauth: true,
    ticketId: ticket.sessionData?.ticketId,
    messagesPerPage: ticket.messagesPerPage,
    messageApiPage: ticket.apiPage,
    onSuccess: useCallback((messages) => {
      addOrUpdateUnauthMessages(messages);
    }, []),
    onError: useCallback((error: Error) => {
      if (error.name === "CanceledError") {
        return;
      }

      const [message] = parseAxiosError(error);
      if (message) enqueueSnackbar(message);
    }, []),
    onFetchStateChange: setUnauthTicketMessageFetchState,
  });

  useSSESubscription<TicketMessage>({
    enabled:
      sseEnabled && isActiveSSETab && Boolean(ticket.sessionData?.sessionId),
    url: `${process.env.REACT_APP_DOMAIN}/heruvym/v1.0.0/ticket?ticket=${ticket.sessionData?.ticketId}&s=${ticket.sessionData?.sessionId}`,
    onNewData: (ticketMessages) => {
      const isTicketClosed = ticketMessages.some(
        (message) => message.session_id === "close",
      );
      if (isTicketClosed) {
        cleanAuthTicketData();
        if (!user) {
          cleanUnauthTicketData();
          localStorage.removeItem("unauth-ticket");
        }
        return;
      }
      updateSSEValue(ticketMessages);
      addOrUpdateUnauthMessages(ticketMessages);
    },
    onDisconnect: useCallback(() => {
      setUnauthIsPreventAutoscroll(false);
      setSseEnabled(false);
    }, []),
    marker: "ticket",
  });

  useEffect(() => {
    cleanAuthTicketData();
    setSseEnabled(true);
  }, [user]);

  useEffect(() => {
    if (isChatOpened) {
      const newMessages = ticket.messages.filter(
        ({ shown }) => shown?.me !== 1,
      );

      // Находим последнее сообщение, которое не от пользователя
      const lastNonUserMessage = newMessages
        .filter(({ user_id }) => (ticket.sessionData?.sessionId || user) !== user_id)
        .pop();

      // Отправляем shown только на последнее сообщение, которое не от пользователя
      if (lastNonUserMessage) {
        shownMessage(lastNonUserMessage.id);
      }
    }
  }, [isChatOpened, ticket.messages]);

  const sendMessage = async (messageField: string) => {
    if (!messageField || ticket.isMessageSending) return false;

    setSseEnabled(true);
    setIsMessageSending(true);

    let successful = await selectSendingMethod({ messageField });

    setIsMessageSending(false);
    return successful;
  };
  const sendFile = async (file: File | undefined): Promise<void> => {
    if (file === undefined) return;

    let ticketId = ticket.sessionData?.ticketId;
    if (!ticket.sessionData?.ticketId) {
      const [data, createError] = await createTicket({
        message: "",
        useToken: Boolean(user),
        systemError: false
      });
      ticketId = data?.Ticket;

      if (createError || !data) {
        enqueueSnackbar(`Не удалось создать диалог ${parseAxiosError(createError)}`);
        return;
      } else {
        setTicketData({ ticketId: data.Ticket, sessionId: data.sess });
      }

      setIsMessageSending(false);
    }

    if (ticketId !== undefined) {
      if (file.size > MAX_FILE_SIZE) {
        setModalWarningType("errorSize");
        return;
      }

      const [_, sendFileError] = await sf({ticketId, file});

      if (sendFileError) {
        enqueueSnackbar(`Не удалось отправить файл ${parseAxiosError(sendFileError)}`);
      }
    }
  };

  return (
    <FloatingSupportChat
      isChatOpened={isChatOpened}
      handleChatClickOpen={handleChatClickOpen}
      handleChatClickClose={handleChatClickClose}
      handleChatClickSwitch={handleChatClickSwitch}
      sendMessage={sendMessage}
      sendFile={sendFile}
      modalWarningType={modalWarningType}
      setModalWarningType={setModalWarningType}
    />
  );
};
