import {
  Grid,
  Typography,
  ListItem,
  ListItemText,
  Stack,
  Divider,
  Button,
  Box,
} from "@mui/material";
import React, { useEffect, useMemo, useRef, useState } from "react";
import TranslateOutlinedIcon from "@mui/icons-material/TranslateOutlined";
import {
  AllMsgList,
  BigSideInnerData,
  ChatLog,
  ChatOutlineButton,
  ChatTimeMessage,
  HoverIocns,
  HoverIocnsInn,
  ImageInfoSection,
  ImagePdfSection,
  ImageUploadBox,
  LoadMorBtnBox,
  RRecieverName,
  RSenderName,
  RecieverMessageDetailInfo,
  RecieverMsgBox,
  ReplyRecieverMesgBox,
  ReplySenderMesgBox,
  SenderMessageDetailInfo,
  SenderMsgBox,
  UserNameletter,
} from "../../style";
import Avatar from "@mui/material/Avatar";
import { useDispatch, useSelector } from "react-redux";
import {
  extractFileName,
  fetchChatHistory,
  formatRelativeDate,
  getFileExtension,
  getPrivateChannel,
  getUserIdLocalStorage,
  markMessageAsRead,
  translateText,
} from "@/components/common/common";
import {
  UpdateChat,
  replaceChat,
  setActiveUser,
  translateMessage,
} from "@/hooks/ChatReducer";
import { chatMsgData } from "@/hooks/Interface";
import { styled } from "@mui/material/styles";
import LinkPreview from "../TypingArea/linkPreview";
import Auth from "@/auth/Auth";
import TypingDotIndicator from "./TypingDotIndicator";
import ImagePreviewPopup from "./ImagePreviewPopup";
import { LightTooltip } from "@/components/common/Tooltip/tooltip";
import {
  fileExtensions,
  iconMapping,
  imageExtensions,
  videoExtensions,
} from "../../common/constant";
import { messageReadEvent } from "../../common/events";
import MessageWithTimeStatus from "./messageWithTimeStatus";
import useMessageRecieverEventListener from "../../common/customHooks/useMessageRecieverEventListener";
import QuotationMessage from "../quotationMessage";

/**
 * Renders the message section with a list of messages and a typing dot indicator.
 *
 * @param {Function} handleReplyMessage Function to handle reply message actions.
 * @param {Object} attachedMessageDetails Details of the attached message.
 * @param {Function} setAttachMessageState Function to set the state of the attached message.
 * @returns {JSX.Element} The message rendering section.
 */

type User = {
  id: string;
  name?: string;
};
const urlPattern = /^(ftp|http|https):\/\/[^ "]+$/;
const MessagesSection = ({
  handleReplyMessage,
  attachedMessageDetails,
  setAttatchMessageState,
}) => {
  const { chats, roomId, activeUser } = useSelector(
    (state: any) => state.chatData
  );
  const { request_status, isSearchedMessage, room_id } = activeUser || {};
  const [isTyping, setIsTyping] = useState(false);
  const [typingUser, setTypingUser] = useState<User | null>(null);
  const [fileUrl, setFileUrl] = useState(null);

  const [imagePreviewOpen, setImagePreviewOpen] = React.useState(false);
  const dispatch = useDispatch();

  const chatContainer = useRef(null);
  const { id, message: attatchedMessage } = attachedMessageDetails || {};

  const {
    detail: { data },
  } = useSelector((state: any) => state.productDetail);

  const Root = styled("div")(({ theme }) => ({
    width: "100%",
    ...theme.typography.body2,
    color: theme.palette.text.secondary,
    "& > :not(style) ~ :not(style)": {
      marginTop: theme.spacing(2),
    },
  }));

  const scrollToDown = (position?: number) => {
    if (chatContainer && chatContainer.current) {
      const container = chatContainer.current;
      if (container) {
        const scrollToBottom = position ? position : container.scrollHeight;
        container.scrollTo({
          top: scrollToBottom,
          behavior: "smooth",
        });
      }
    }
  };
  useEffect(() => {
    scrollToDown();
  }, [chats?.length]);

  const handleScroll = () => {
    if (
      chatContainer?.current?.scrollTop === 0 &&
      (activeUser?.previousChatUrl || activeUser?.previousChatUrlEndpont)
    ) {
      // const handleSeeOlderMessage = () => {
      fetchChatHistory({
        userId: activeUser?.id,
        url: activeUser?.previousChatUrl,
        pageNumberParam: activeUser?.previousChatUrlEndpont,
      })
        .then((responseData) => {
          const { nextPageUrl, data, previousPageUrl } =
            responseData?.data?.message?.all;
          const updatedUser = {
            ...activeUser,
            previousChatUrl: nextPageUrl,
            previousChatUrlEndpont: nextPageUrl
              ? nextPageUrl.split("?")[1]
              : null,
          };
          dispatch(setActiveUser(updatedUser));
          const previousChats = [...chats];
          const updatedChats = [...data, ...previousChats];
          dispatch(replaceChat(updatedChats));
          scrollToDown(50);
        })
        .catch((error) => {
          console.log(error);
        });
      // };
    }
  };

  const loadMoreChat = () => {
    if (activeUser?.nextChatUrlEndpoint) {
      const container = chatContainer?.current;
      if (
        container &&
        container.scrollTop + container.clientHeight >=
          container.scrollHeight - 1
      ) {
        fetchChatHistory({
          userId: activeUser?.id,
          url: activeUser?.previousChatUrl,
          pageNumberParam: activeUser?.nextChatUrlEndpoint,
        })
          .then((responseData) => {
            const { nextPageUrl, data, previousPageUrl } =
              responseData?.data?.message?.all;
            const updatedUser = {
              ...activeUser,
              nextPageUrl: previousPageUrl,
              nextChatUrlEndpoint: previousPageUrl
                ? previousPageUrl.split("?")[1]
                : null,
            };
            dispatch(setActiveUser(updatedUser));
            const previousChats = [...chats];
            const updatedChats = [...previousChats, ...data];
            dispatch(replaceChat(updatedChats));
            scrollToDown(50);
          })
          .catch((error) => {
            console.log(error);
          });
      }
    }
  };

  useEffect(() => {
    const isChatRequestAccepted = request_status === "pending";
    scrollToDown();
    if (!isChatRequestAccepted) {
      const lastMessageId = chats[chats?.length - 1]?.id;
      messageReadEvent(
        roomId,
        activeUser?.id,
        activeUser?.message,
        lastMessageId
      );
    }
    const lastMessage = chats?.length - 1;
    if (
      +currentLoggedUserId !== +chats[lastMessage]?.sender_id &&
      !isChatRequestAccepted
    )
      markMessageAsRead(chats[lastMessage]?.id, roomId);
  }, [activeUser?.id, activeUser?.room_id]);

  useEffect(() => {
    let echoInstance;
    if (activeUser?.room_id) {
      echoInstance = getPrivateChannel(activeUser?.room_id);
      echoInstance.listenForWhisper("typing", (e) => {
        const { userID, roomId, userName = "" } = e;
        if (+activeUser?.is_blocked === 1) {
          return;
        }
        const typingTimeout = 2000;

        if (typingTimeoutId) {
          clearTimeout(typingTimeoutId);
        }

        if (+roomId === +activeUser?.room_id) {
          setIsTyping(true);
          setTypingUser({ id: userID, name: userName });
        }

        typingTimeoutId = setTimeout(() => {
          setIsTyping(false);
          setTypingUser(null);
          typingTimeoutId = null;
        }, typingTimeout);
      });
    }

    // Cleanup function to remove the listener
    return () => {
      if (echoInstance) {
        echoInstance.stopListeningForWhisper("typing");
      }
    };
  }, [activeUser?.is_blocked, activeUser?.room_id]);
  useEffect(() => {
    if (chatContainer && chatContainer.current)
      chatContainer.current.addEventListener("scroll", handleScroll);

    return () => {
      if (chatContainer && chatContainer.current)
        chatContainer.current.removeEventListener("scroll", handleScroll);
    };
  }, [chats?.length]);

  const handleReplyClick = (message) => {
    handleReplyMessage(message?.id, message?.message);
  };

  const currentLoggedUserId = getUserIdLocalStorage();

  useMessageRecieverEventListener(
    activeUser,
    currentLoggedUserId,
    roomId,
    dispatch,
    scrollToDown,
    markMessageAsRead,
    messageReadEvent
  );

  useEffect(() => {
    if ((window as any)?.Echo) {
      (window as any).Echo.private(`chat.${roomId}`).listenForWhisper(
        "MessageRead",
        (e) => {
          const {
            roomId,
            userId,
            message,
            message_type = "",
            lastMessageId,
            chatLength,
          } = e || {};
          if (userId !== activeUser?.id && message_type !== "log") {
            //make a copy of chats which is stored in redux state
            const updatedChats = [...(chats ?? [])];
            // Get the index of the last chat message
            const lastChatIndex = updatedChats?.length - 1;
            if (
              lastChatIndex >= 0 &&
              updatedChats[lastChatIndex]?.status !== "read"
            ) {
              // Update the status property of the last chat message to "read"
              updatedChats[updatedChats?.length - 1] = {
                ...updatedChats[updatedChats?.length - 1],
                status: "read",
              };
              const lastMessage = chats[chats?.length - 1]?.message;
              if (chatLength !== undefined && chatLength === chats?.length) {
                dispatch(replaceChat(updatedChats));
                return;
              }
              if (message && lastMessage === message) {
                dispatch(replaceChat(updatedChats));
              }
            }
          }
        }
      );
    }
    if ((window as any)?.Echo) {
      (window as any).Echo.private(`chat.${roomId}`).listenForWhisper(
        "MessageRequestAccepted",
        (e) => {
  
          const { roomId, userID, acceptedBy, userName } = e || {};
          if (+roomId === +room_id && acceptedBy !== currentLoggedUserId) {
            const updatedUserDetails = {
              ...activeUser,
              request_status: "approved",
            };
            dispatch(setActiveUser(updatedUserDetails));
          }
        }
      );
    }
  }, [chats?.length, activeUser?.room_id]);

  /**
   * Checks if the given text is in English.
   * @param {string} text - The text to be checked.
   * @returns {Boolean} - Returns true if the text is in English, otherwise false.
   */
  const isTextInEnglish = (text = "") => {
    const englishRegex = /^[A-Za-z0-9\s]*$/;
    return englishRegex.test(text);
  };

  const handleTranslate = async ({ textToTranslate = "", chatId = 0 }: any) => {
    // if (urlPattern?.test(textToTranslate)) return;
    // const isMessageIsInEnglish = isTextInEnglish(textToTranslate);

    const to = "ar";

    let translatedText = "";

    // if (isMessageIsInEnglish) {
    translatedText = await translateText(textToTranslate, to);
    // }

    dispatch(
      translateMessage({
        chatId,
        message: translatedText,
        // isMessageIsInEnglish: isMessageIsInEnglish,
        textToTranslate: textToTranslate,
      })
    );
  };
  // const isLastMessageIsSeen = chats[chats?.length - 1]?.status === "read";

  const indexOfLastMessageRead = chats
    .map((chat) => chat?.status)
    .lastIndexOf("read");

  const groupMessagesByDate = useMemo(() => {
    if (!chats || chats?.length === 0) {
      return {};
    }
    const memoizedConvertToDatestring = (createdAt) =>
      new Date(createdAt).toDateString();
    return chats.reduce((acc, message) => {
      const messageDate = memoizedConvertToDatestring(message?.created_at);
      acc[messageDate] = acc[messageDate] || [];
      acc[messageDate].push(message);
      return acc;
    }, {});
  }, [chats]);

  //function for refetching the file data
  /**
   * @param message  recievies the message from chat on the condition in map return jsx which have message_type = 'file'
   * @returns {data} returns the data which contains a string response which is the tag returned in string format from backend response
   */
  async function fetchMessageResponse(message) {
    let data;
    try {
      const response = await fetch(message?.message, {
        method: "GET",
        headers: {
          // "Content-Type": "application/json",
          Authorization: `Bearer ${Auth?.token()}`,
        },
      });
      if (response?.ok) {
        data = await response?.text();
      }
    } catch (error) {
      console.log(error);
    }
    return data;
  }

  const handleClickOpen = (fileUrl) => {
    setFileUrl(fileUrl);
    setImagePreviewOpen(true);
  };
  const handleClose = () => {
    setImagePreviewOpen(false);
  };

  const renderMessageContent = (message) => {
    const isUrl =
      urlPattern?.test(message?.message) || message?.message_type === "url";
    const fileExtension = getFileExtension(message?.message);

    // if (fileExtension.length > 1) {
    const fileUrls = message?.message?.split(",").map((url) => url.trim());

    const isCurrentLoggedUserShared = message?.sender_id == currentLoggedUserId;
    if (message?.message_type === "quot") {
      return (
        <QuotationMessage
          quotationDetails={message}
          isQuotationSending={false}
          isCurrentLoggedUserShared={isCurrentLoggedUserShared}
        />
      );
    }

    return (
      <div>
        {fileExtension.map((fileExtension, index) => {
          const fileUrl = fileUrls[index];
          const isFile =
            message?.message_type === "file" &&
            fileExtensions.includes(fileExtension);
          const isImage =
            message?.message_type === "file" &&
            imageExtensions.includes(fileExtension);
          const isVideo =
            message?.message_type === "file" &&
            videoExtensions.includes(fileExtension);
          const isQuotation = message?.message_type === "quot";

          if (isFile) {
            const icon = iconMapping[fileExtension] || iconMapping.default;
            return (
              <a href={fileUrl} download={fileUrl} target="_blank" key={index}>
                <ImagePdfSection>
                  <ImageUploadBox>
                    <img src={icon} alt="File Icon" />
                  </ImageUploadBox>
                  <ImageInfoSection>
                    <Typography variant="h5">
                      {extractFileName(fileUrl)}
                    </Typography>
                  </ImageInfoSection>
                </ImagePdfSection>
              </a>
            );
          }

          if (isImage) {
            return (
              <>
                <ImagePdfSection key={index}>
                  <ImageUploadBox>
                    <img
                      src={fileUrl}
                      alt="Image"
                      loading="lazy"
                      onClick={() => handleClickOpen(fileUrl)}
                    />
                  </ImageUploadBox>
                </ImagePdfSection>
              </>
            );
          }

          if (isVideo) {
            return (
              <ImagePdfSection key={index}>
                <ImageUploadBox>
                  <video
                    width="100%"
                    height="100%"
                    controls
                    controlsList="noloop noremoteplayback"
                  >
                    <source src={fileUrl} type={`video/${fileExtension}`} />
                  </video>
                </ImageUploadBox>
              </ImagePdfSection>
            );
          }

          if (isUrl) {
            return <LinkPreview url={fileUrl} key={index} />;
          }

          return message?.message;
        })}
      </div>
    );
    // }
  };

  let typingTimeoutId = null;
  return (
    <>
      <AllMsgList ref={chatContainer}>
        {imagePreviewOpen && (
          <ImagePreviewPopup handleClose={handleClose} fileUrl={fileUrl} />
        )}
        {/* {activeUser.previousChatUrl && (
          <button onClick={handleSeeOlderMessage}>see older messages</button>
        )} */}
        {/* <QuotationMessage productDetails={data} isQuotationSending={false} /> */}
        {groupMessagesByDate &&
          Object.keys(groupMessagesByDate).map((date, index) => (
            <div key={date}>
              <BigSideInnerData>
                <Root>
                  <Divider>{formatRelativeDate(date, false)}</Divider>
                </Root>
              </BigSideInnerData>
              {groupMessagesByDate[date]?.map((message, index) => {
                // let file_data;
                // let file_name;
                // if(message?.message_type === 'file')
                //   {
                //     const data = fetchMessageResponse(message)
                //    data.then(resData => {
                //     file_data = resData;
                //     file_name = extractFileName(message?.message);
                //     console.log("file name", file_name);
                //     console.log("file data", file_data);
                //    }).catch(err => {console.log(err)})
                //   }
                return (
                  <ListItem key={`${date}-${index}`}>
                    <Grid container>
                      {message?.message_type !== "log" ? (
                        <>
                          <Grid item xs={12}>
                            {message?.sender_id == currentLoggedUserId ? (
                              <SenderMessageDetailInfo>
                                <HoverIocns className="messagehover">
                                  <HoverIocnsInn>
                                    <LightTooltip
                                      arrow
                                      disableInteractive
                                      title="Reply"
                                    >
                                      <i
                                        className="icon-reply-single"
                                        onClick={() =>
                                          handleReplyClick(message)
                                        }
                                      ></i>
                                    </LightTooltip>
                                    {!(
                                      message?.message_type === "file" ||
                                      message?.message_type === "link" ||
                                      urlPattern?.test(message?.message)
                                    ) && (
                                      <LightTooltip
                                        arrow
                                        disableInteractive
                                        title="Translate"
                                      >
                                        <TranslateOutlinedIcon
                                          onClick={() =>
                                            handleTranslate({
                                              textToTranslate: message?.message,
                                              chatId: message?.id,
                                            })
                                          }
                                        />
                                      </LightTooltip>
                                    )}
                                  </HoverIocnsInn>
                                </HoverIocns>
                                <SenderMsgBox>
                                  {message?.replied_parent_id && (
                                    <ReplySenderMesgBox>
                                      <RSenderName>
                                        {+message?.replied_message
                                          ?.sender_id === +currentLoggedUserId
                                          ? "You"
                                          : message?.replied_message?.user_name}
                                      </RSenderName>
                                      <Typography>
                                        {message?.replied_message?.message}
                                      </Typography>
                                    </ReplySenderMesgBox>
                                    // <ImagePdfSection>
                                    //   <ImageUploadBox>
                                    //     <img src="https://staging.powercozmo.com/public/uploads/product/gallery/Screenshot from 2024-04-25 09-42-27.png" />
                                    //   </ImageUploadBox>
                                    //   <ImageInfoSection>
                                    //     <Typography variant="h5">
                                    //       Hondagx390-Engine digital Brocchure .pdf
                                    //     </Typography>
                                    //     <Typographybody variant="body2">
                                    //       14 pages . 14 MB . PDF
                                    //     </Typographybody>
                                    //   </ImageInfoSection>
                                    // </ImagePdfSection>
                                  )}
                                  <Typography>
                                    {renderMessageContent(message)}
                                  </Typography>
                                </SenderMsgBox>
                              </SenderMessageDetailInfo>
                            ) : (
                              <RecieverMessageDetailInfo>
                                <Stack direction="row" spacing={2}>
                                  <Avatar sx={{ width: 24, height: 24 }}>
                                    <UserNameletter>
                                      {message?.user_name &&
                                        message?.user_name
                                          ?.charAt(0)
                                          .toUpperCase()}
                                    </UserNameletter>
                                  </Avatar>
                                </Stack>
                                <RecieverMsgBox>
                                  {message?.replied_parent_id && (
                                    <ReplyRecieverMesgBox>
                                      <RRecieverName>
                                        {+message?.replied_message
                                          ?.sender_id === +currentLoggedUserId
                                          ? "You"
                                          : message?.replied_message?.user_name}
                                      </RRecieverName>
                                      <Typography>
                                        {message?.replied_message?.message}
                                      </Typography>
                                    </ReplyRecieverMesgBox>
                                  )}

                                  <Typography>
                                    {renderMessageContent(message)}
                                  </Typography>
                                </RecieverMsgBox>
                                <HoverIocns className="messagehover">
                                  <HoverIocnsInn>
                                    <LightTooltip
                                      arrow
                                      disableInteractive
                                      title="Reply"
                                    >
                                      <i
                                        className="icon-reply-single"
                                        onClick={() =>
                                          handleReplyClick(message)
                                        }
                                      ></i>
                                    </LightTooltip>
                                    {!(
                                      message?.message_type === "file" ||
                                      message?.message_type === "link" ||
                                      urlPattern?.test(message?.message)
                                    ) && (
                                      <LightTooltip
                                        arrow
                                        disableInteractive
                                        title="Translate"
                                      >
                                        <TranslateOutlinedIcon
                                          onClick={() =>
                                            handleTranslate({
                                              textToTranslate: message?.message,
                                              chatId: message?.id,
                                            })
                                          }
                                        />
                                      </LightTooltip>
                                    )}
                                  </HoverIocnsInn>
                                </HoverIocns>
                              </RecieverMessageDetailInfo>
                            )}
                          </Grid>
                          <Grid item xs={12}>
                            <MessageWithTimeStatus
                              message={message}
                              currentLoggedUserId={currentLoggedUserId}
                              indexOfLastMessageRead={indexOfLastMessageRead}
                              index={index}
                              activeUser={activeUser}
                            />
                          </Grid>
                        </>
                      ) : (
                        <ChatLog>{message?.message}</ChatLog>
                      )}
                    </Grid>
                  </ListItem>
                );
              })}
              {activeUser?.nextChatUrlEndpoint && (
                <LoadMorBtnBox>
                  <Divider>
                    <ChatOutlineButton
                      size="small"
                      variant="outlined"
                      onClick={loadMoreChat}
                    >
                      Load More
                    </ChatOutlineButton>
                  </Divider>
                </LoadMorBtnBox>
              )}
            </div>
          ))}
      </AllMsgList>
      {isTyping && +typingUser?.id !== +currentLoggedUserId && (
        <TypingDotIndicator typingUser={typingUser} />
      )}
    </>
  );
};

export default MessagesSection;
