import {
  Box,
  FormControl,
  IconButton,
  InputAdornment,
  InputBase,
  SxProps,
  Theme,
  Typography,
  useMediaQuery,
  useTheme,
} from "@mui/material";
import {
  getAuthToken,
  getMessageFromFetchError,
  throttle,
  TicketMessage,
  useSSESubscription,
  useTicketMessages,
  useTicketsFetcher,
} from "@frontend/kitui";
import { enqueueSnackbar } from "notistack";
import {
  TouchEvent,
  useCallback,
  useEffect,
  useMemo,
  useRef,
  useState,
  WheelEvent,
} from "react";
import ChatMessage from "../ChatMessage";
import SendIcon from "../icons/SendIcon";
import ArrowLeft from "@root/assets/Icons/arrowLeft";
import UserCircleIcon from "./UserCircleIcon";
import {
  sendTicketMessage,
  shownMessage,
  sendFile as sendFileRequest,
} from "@root/api/ticket";
import { useSSETab } from "@root/utils/hooks/useSSETab";
import {
  ACCEPT_SEND_MEDIA_TYPES_MAP,
  checkAcceptableMediaType,
  MAX_FILE_SIZE,
} from "@utils/checkAcceptableMediaType";
import {
  addOrUpdateUnauthMessages,
  clearTickets,
  incrementUnauthMessage,
  setIsMessageSending,
  setTicketData,
  setUnauthIsPreventAutoscroll,
  setUnauthTicketMessageFetchState,
  useTicketStore,
} from "@root/stores/tickets";
import { useUserStore } from "@root/stores/user";
import AttachFileIcon from "@mui/icons-material/AttachFile";
import ChatDocument from "./ChatDocument";
import ChatImage from "./ChatImage";
import ChatVideo from "./ChatVideo";
import { createTicket } from "@api/ticket";

type ModalWarningType =
  | "errorType"
  | "errorSize"
  | "picture"
  | "video"
  | "audio"
  | "document"
  | null;
interface Props {
  open: boolean;
  sx?: SxProps<Theme>;
  onclickArrow?: () => void;
}

export default function Chat({ open = false, onclickArrow, sx }: Props) {
  const theme = useTheme();
  const upMd = useMediaQuery(theme.breakpoints.up("md"));
  const isMobile = useMediaQuery(theme.breakpoints.down(800));
  const [messageField, setMessageField] = useState<string>("");
  const [disableFileButton, setDisableFileButton] = useState<boolean>(false);
  const [sseEnabled, setSseEnabled] = useState(true);
  const [modalWarningType, setModalWarningType] =
    useState<ModalWarningType>(null);
  const chatBoxRef = useRef<HTMLDivElement>(null);
  const fileInputRef = useRef<HTMLInputElement>(null);
  const user = useUserStore((state) => state.user?._id);
  const ticket = useTicketStore(
    (state) => state[user ? "authData" : "unauthData"]
  );
  const {
    messages,
    sessionData,
    isMessageSending,
    isPreventAutoscroll,
    lastMessageId,
    messagesPerPage,
    unauthTicketMessageFetchState: fetchState,
    apiPage: messageApiPage,
  } = ticket;
  const { isActiveSSETab, updateSSEValue } = useSSETab<TicketMessage[]>(
    "ticket",
    addOrUpdateUnauthMessages
  );

  const getGreetingMessage: TicketMessage = useMemo(() => {
    const workingHoursMessage =
      "Здравствуйте, задайте ваш вопрос и наш оператор вам ответит в течение 10 минут";
    const offHoursMessage =
      "Здравствуйте, к сожалению, сейчас операторы не работают. Задайте ваш вопрос, и вам ответят в 10:00 по московскому времени";
    const date = new Date();
    const currentHourUTC = date.getUTCHours();
    const MscTime = 3; // Москва UTC+3;
    const moscowHour = (currentHourUTC + MscTime) % 24;
    const greetingMessage =
      moscowHour >= 3 && moscowHour < 10
        ? offHoursMessage
        : workingHoursMessage;

    return {
      created_at: new Date().toISOString(),
      files: [],
      id: "111",
      message: greetingMessage,
      request_screenshot: "",
      session_id: "greetingMessage",
      shown: { me: 1 },
      ticket_id: "111",
      user_id: "greetingMessage",
    };
  }, [open]);

  useTicketMessages({
    url: process.env.REACT_APP_DOMAIN + "/heruvym/v1.0.0/getMessages",
    isUnauth: true,
    ticketId: sessionData?.ticketId,
    messagesPerPage,
    messageApiPage,
    onSuccess: 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);
    }, []),
    onFetchStateChange: setUnauthTicketMessageFetchState,
  });
  console.log("sessionData")
  console.log(sessionData)
  useSSESubscription<TicketMessage>({
    enabled: sseEnabled && isActiveSSETab && Boolean(sessionData),
    url:
      process.env.REACT_APP_DOMAIN +
      `/heruvym/v1.0.0/ticket?ticket=${sessionData?.ticketId}&s=${sessionData?.sessionId}`,
    onNewData: (ticketMessages) => {
      console.log("ticketMessages useSSESubscription " + ticketMessages)
      const isTicketClosed = ticketMessages.some(
        (message) => message.session_id === "close"
      );
      if (isTicketClosed) {
        clearTickets();
        addOrUpdateUnauthMessages([getGreetingMessage]);
        if (!user) {
          localStorage.removeItem("unauth-ticket");
        }
        return;
      }
      updateSSEValue(ticketMessages);
      addOrUpdateUnauthMessages(ticketMessages);
    },
    onDisconnect: useCallback(() => {
      setUnauthIsPreventAutoscroll(false);
      setSseEnabled(false);
    }, []),
    marker: "ticket",
  });

  useTicketsFetcher({
    url: process.env.REACT_APP_DOMAIN + "/heruvym/v1.0.0/getTickets",
    ticketsPerPage: 10,
    ticketApiPage: 0,
    onSuccess: (result) => {
      if (result.data?.length) {
        const currentTicket = result.data.find(
          ({ origin, state }) =>
            !origin.includes("/support") && state !== "close"
        );

        if (!currentTicket) {
          return;
        }

        setTicketData({
          ticketId: currentTicket.id,
          sessionId: currentTicket.sess,
        });
      }
    },
    onError: (error: Error) => {
      const message = getMessageFromFetchError(error);
      if (message) enqueueSnackbar(message);
    },
    onFetchStateChange: () => { },
    enabled: Boolean(user),
  });

  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) {
          incrementUnauthMessage();
        }
      }, 200),
    [fetchState]
  );

  useEffect(() => {
    addOrUpdateUnauthMessages([getGreetingMessage]);
    scrollToBottom();
  }, [open]);

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

      if (!isPreventAutoscroll) {
        setTimeout(() => {
          scrollToBottom();
        }, 50);
      }
    },
    [lastMessageId]
  );

  useEffect(() => {
    if (open) {
      console.log("SHOWN")
      console.log("messages")
      console.log(messages)
      console.log("open")
      console.log(open)
      if (messages.length > 1) {

        let last_message

        for (let i = messages.length - 1; i >= 0; i--) {
          if (messages[i].ticket_id !== "111") {
            last_message = messages[i];
            break;
          }
        }

        console.log("last_message")
        console.log(last_message)

        if (last_message) {
          console.log("if")
          console.log(((ticket.sessionData?.sessionId || user) !== last_message.user_id) && last_message.shown.me !== 1 && last_message.ticket_id !== "111")
          console.log(((ticket.sessionData?.sessionId || user) !== last_message.user_id))
          console.log(last_message.shown.me !== 1)

          if (((ticket.sessionData?.sessionId || user) !== last_message.user_id) && last_message.shown.me !== 1 && last_message.ticket_id !== "111") {
            shownMessage(last_message.id);
          }


          console.log("user")
          console.log(user)
          console.log(messages[messages.length - 1])
        }
      }
    }
  }, [open, messages]);

  const loadNewMessages = (
    event: WheelEvent<HTMLDivElement> | TouchEvent<HTMLDivElement>
  ) => {
    event.stopPropagation();

    throttledScrollHandler();
  };

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

    if (!sessionData?.ticketId) {
      setIsMessageSending(true);

      const [createTicketresult, createTicketerror] = await createTicket(
        "Unauth title",
        messageField,
        //При создании тикета, если нет у клиента токена, то хедер authorization вовсе не нужно слать
        Boolean(getAuthToken())
      );

      if (createTicketerror) {
        enqueueSnackbar(createTicketerror);
      } else if (createTicketresult) {
        setTicketData({
          ticketId: createTicketresult.Ticket,
          sessionId: createTicketresult.sess,
        });
        setSseEnabled(true);
      }

      setMessageField("");
      setIsMessageSending(false);
    } else {
      setIsMessageSending(true);

      const [_, sendTicketMessageError] = await sendTicketMessage(
        sessionData.ticketId,
        messageField
      );

      if (sendTicketMessageError) {
        enqueueSnackbar(sendTicketMessageError);
      }

      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();
    }
  };

  const sendFile = async (file: File) => {
    if (file === undefined) return true;

    let data;
    if (!ticket.sessionData?.ticketId) {
      try {
        const [createTicketresult] = await createTicket("Unauth title", "");

        if (createTicketresult) {
          data = createTicketresult;
        }

        if (data) {
          setTicketData({
            ticketId: data.Ticket,
            sessionId: data.sess,
          });
        }
      } catch (error: any) {
        const errorMessage = getMessageFromFetchError(error);
        if (errorMessage) enqueueSnackbar(errorMessage);
      }
      setIsMessageSending(false);
    }

    const ticketId = ticket.sessionData?.ticketId || data?.Ticket;
    if (ticketId !== undefined) {
      if (file.size > MAX_FILE_SIZE) return setModalWarningType("errorSize");

      const [, sendFileError] = await sendFileRequest(ticketId, file);

      if (sendFileError) {
        enqueueSnackbar(sendFileError);
      }

      return true;
    }
  };

  const sendFileHC = async (file: File) => {
    const check = checkAcceptableMediaType(file);
    if (check.length > 0) {
      enqueueSnackbar(check);
      return;
    }

    setDisableFileButton(true);
    await sendFile(file);
    setDisableFileButton(false);
  };

  return (
    <>
      {open && (
        <Box
          sx={{
            display: "flex",
            flexDirection: "column",
            height: isMobile
              ? "100%"
              : "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))",
            }}
          >
            {isMobile && (
              <IconButton onClick={onclickArrow}>
                <ArrowLeft color="white" />
              </IconButton>
            )}
            <UserCircleIcon />
            <Box
              sx={{
                mt: "5px",
                display: "flex",
                flexDirection: "column",
                gap: "3px",
              }}
            >
              <Typography>Данила</Typography>
              <Typography
                sx={{
                  fontSize: "16px",
                  lineHeight: "19px",
                }}
              >
                онлайн-консультант
              </Typography>
              <Typography
                sx={{
                  fontSize: "16px",
                  lineHeight: "19px",
                }}
              >
                время работы 10:00-3:00 по мск
              </Typography>
            </Box>
          </Box>
          <Box
            sx={{
              flexGrow: 1,
              backgroundColor: "white",
              borderRadius: "8px",
              display: "flex",
              flexDirection: "column",
            }}
          >
            <Box
              onWheel={loadNewMessages}
              onTouchMove={loadNewMessages}
              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,
              }}
            >
              {ticket.sessionData?.ticketId &&
                messages.map((message) => {
                  const isFileVideo = () => {
                    if (message.files) {
                      return ACCEPT_SEND_MEDIA_TYPES_MAP.video.some(
                        (fileType) =>
                          message.files[0].toLowerCase().endsWith(fileType)
                      );
                    }
                  };
                  const isFileImage = () => {
                    if (message.files) {
                      return ACCEPT_SEND_MEDIA_TYPES_MAP.picture.some(
                        (fileType) =>
                          message.files[0].toLowerCase().endsWith(fileType)
                      );
                    }
                  };
                  const isFileDocument = () => {
                    if (message.files) {
                      return ACCEPT_SEND_MEDIA_TYPES_MAP.document.some(
                        (fileType) =>
                          message.files[0].toLowerCase().endsWith(fileType)
                      );
                    }
                  };
                  if (message.files.length > 0 && isFileImage()) {
                    return (
                      <ChatImage
                        unAuthenticated
                        key={message.id}
                        file={message.files[0]}
                        createdAt={message.created_at}
                        isSelf={
                          (ticket.sessionData?.sessionId || user) ===
                          message.user_id
                        }
                      />
                    );
                  }
                  if (message.files.length > 0 && isFileVideo()) {
                    return (
                      <ChatVideo
                        unAuthenticated
                        key={message.id}
                        file={message.files[0]}
                        createdAt={message.created_at}
                        isSelf={
                          (ticket.sessionData?.sessionId || user) ===
                          message.user_id
                        }
                      />
                    );
                  }
                  if (message.files.length > 0 && isFileDocument()) {
                    return (
                      <ChatDocument
                        unAuthenticated
                        key={message.id}
                        file={message.files[0]}
                        createdAt={message.created_at}
                        isSelf={
                          (ticket.sessionData?.sessionId || user) ===
                          message.user_id
                        }
                      />
                    );
                  }
                  return (
                    <ChatMessage
                      unAuthenticated
                      key={message.id}
                      text={message.message}
                      createdAt={message.created_at}
                      isSelf={
                        (ticket.sessionData?.sessionId || user) ===
                        message.user_id
                      }
                    />
                  );
                })}
              {!ticket.sessionData?.ticketId && (
                <ChatMessage
                  unAuthenticated
                  text={getGreetingMessage.message}
                  createdAt={getGreetingMessage.created_at}
                  isSelf={false}
                />
              )}
            </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={disableFileButton}
                      onClick={() => {
                        if (!disableFileButton) fileInputRef.current?.click();
                      }}
                    >
                      <AttachFileIcon />
                    </IconButton>
                    <input
                      ref={fileInputRef}
                      id="fileinput"
                      onChange={({ target }) => {
                        if (target.files?.[0]) {
                          sendFileHC(target.files?.[0]);
                        }
                      }}
                      style={{ display: "none" }}
                      type="file"
                    />
                    <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>
      )}
    </>
  );
}
