import React, {
  useRef,
  useState,
  useCallback,
  useMemo,
  useContext,
} from "react";
import { Box, Grid, IconButton, TextField, Typography } from "@mui/material";
import { useDispatch, useSelector } from "react-redux";
import Emoji from "./emoji/index";
import LinkPreview from "./linkPreview/index";
import Auth from "@/auth/Auth";
import { BASE_URL_CHAT } from "@/utils/staticValues";
import AlertDialog from "./BlockPopup/index";
import SendIcon from "@mui/icons-material/Send";
import ClearIcon from "@mui/icons-material/Clear";
import ClearRoundedIcon from "@mui/icons-material/ClearRounded";
import {
  BottomTypingArea,
  BottomTypingAreaOuter,
  ChatImageBox,
  ChatImageCancelBox,
  ChatTypingBox,
  EmojiOpenBox,
  OneFilledButton,
  ReplyFooterSection,
  SuggestionsSection,
  TypingAreaIcons,
  TypingAreaOuter,
} from "../../style";
import {
  UpdateChat,
  setActiveUser,
  setMessage,
  setTyping,
  setUsersList,
} from "@/hooks/ChatReducer";
import {
  convertSize,
  getCurrentPageURL,
  getPrivateChannel,
  getUserIdLocalStorage,
  randomStr,
  sendMessage,
  sendQuotation,
} from "@/components/common/common";
import dynamic from "next/dynamic";
import AdditionalSuggestionSection from "../../common/components/additionSuggestionBox.tsx";
import useTransferChat from "../../common/customHooks/useTransferChat";
import { ThreeDots } from "react-loader-spinner";
import { debounce } from "@/components/Helper";
import {
  chatFileUploadSize,
  fileExtensions,
  imageExtensions,
  videoExtensions,
} from "../../common/constant";
import { toast } from "react-toastify";
const GroupLeft = dynamic(() => import("../../userList/group-chat/GroupLeft"));

const urlPattern = /^(ftp|http|https):\/\/[^ "]+$/;

const TypingArea = (props) => {
  const dispatch = useDispatch();
  const { attachedMessageDetails, setAttatchMessageState } = props;
  const { id: replyingId, message: replyingMessage } =
    attachedMessageDetails || {};

  const fileInputRef = useRef(null);
  const [showEmoji, setShowEmoji] = useState(false);
  const [attachment, setAttachment] = useState([]);
  const [attachmentURL, setAttachmentUrl] = useState([]);
  const [isUrl, setIsUrl] = useState(false);
  const [url, setUrl] = useState("");
  const [isSending, setIsSending] = useState(false);
  const [isOpen, setIsopen] = useState({ open: false, data: null });

  const {
    message: currentTypingMessage,
    roomId,
    activeUser,
    usersList,
    chats,
  } = useSelector((state: any) => state?.chatData || {});

  const { user_info } = useSelector((state: any) => state.userData);
  const { id: currentlyLoggedInUserID, name: currentLoggedUserName } =
    user_info;

  const {
    id: activeUserID,
    room_id,
    is_group,
    is_blocked,
    group_users,
    quotationUrl: activeUserQuotationUrl,
    request_status,
    is_transfer,
    name: activelyChattingwithUserName,
    request_send_from,
    name: userName,
    sendQuotation: shouldSendQuotation = false,
  } = activeUser;

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

  const currentLoggedUserId = getUserIdLocalStorage();

  const { message: attatchedMessage } = attachedMessageDetails || {};

  const { transferChat, isSubmitting } = useTransferChat();

  const isMyselfSendedRequest = +currentLoggedUserId === +request_send_from;

  const isChatRequestIsPending = request_status === "pending";

  const isNewChatInitiating = !chats?.length;
  const isGroupExited = useMemo(() => {
    if (is_group === 1) {
      return !!group_users?.find((user) => +user?.id === +currentLoggedUserId);
    }
    return true;
  }, [is_group, group_users, currentLoggedUserId]);

  const quotationUrl = useMemo(() => {
    if (isNewChatInitiating) {
      return user_id === activeUserID
        ? getCurrentPageURL()
        : activeUserQuotationUrl;
    }
    return null;
  }, [isNewChatInitiating, user_id, activeUserID, activeUserQuotationUrl]);

  const handleMessageTyping = useCallback(
    (e) => {
      if ((window as any)?.Echo) {
        const { value } = e?.target;

        //checking if the input of the user is url or not
        const isUrl = !!value && urlPattern.test(value);

        setIsUrl(isUrl);
        setUrl(isUrl ? value : "");

        //setting the typing messages value to redux
        dispatch(setMessage(value));
        dispatch(setTyping({ userId: currentLoggedUserId, isTyping: true }));

        setTimeout(() => {
          dispatch(setTyping({ userId: currentLoggedUserId, isTyping: false }));
        }, 2000);
        if (+is_blocked === 0 && request_status !== "pending") {
          getPrivateChannel(room_id).whisper("typing", {
            userID: currentLoggedUserId,
            roomId: roomId,
            isBlocked: +activeUser?.is_blocked,
            userName: currentLoggedUserName,
          });
        }
      }
    },
    [dispatch, currentLoggedUserId, is_blocked, room_id, roomId, request_status]
  );

  const handleFileClick = () => {
    if (fileInputRef && fileInputRef?.current) {
      fileInputRef?.current?.click();
    }
  };

  const handleFileChange = useCallback((event) => {
    const selectedFiles = event?.target?.files as FileList;
    const newFiles = [];
    if (!selectedFiles) return;
    const validExtensions = [
      ...videoExtensions,
      ...imageExtensions,
      ...fileExtensions,
    ];
    for (const a of selectedFiles) {
      const fileSize = convertSize(a?.size, "MB");
      const fileType = a.type.split("/")[1]; // Extract file type (e.g., 'image', 'text', etc.)
      const fileExtension = fileType.split(".").pop();
      if (fileSize > chatFileUploadSize) {
        if (fileInputRef.current) {
          fileInputRef.current.value = "";
        }
        toast.error("upload less that 10 MB", {
          autoClose: 3500,
        });
        return;
      } else if (fileSize <= 0) {
        toast.error("Currepted images are not allowed", {
          autoClose: 3500,
        });
      } else if (validExtensions.includes(fileExtension)) {
        newFiles.push(a);
      } else {
        toast.error(`The file format ${fileExtension ?? ""} is not supported`, {
          autoClose: 3500,
        });
        if (fileInputRef.current) {
          fileInputRef.current.value = "";
        }
        return;
      }
    }
    // const filesArray = Array.from(selectedFiles).filter(
    //   (file) => file?.size > 0
    // );
    const filesBlobArray = newFiles.map((file) => ({
      url: URL.createObjectURL(file),
      type: file.type.split("/")[0],
    }));

    if (newFiles?.length > 0 && filesBlobArray?.length > 0) {
      setAttachmentUrl(filesBlobArray);
      setAttachment((prev) => newFiles);
    } else {
      console.error("No files selected.");
    }

    if (fileInputRef.current) {
      fileInputRef.current.value = "";
    }
  }, []);

  const handleSendMessage = async () => {
    let data;
    if (+is_blocked === 1) {
      data = "block";
    } else if (is_transfer === 1 && group_users?.length > 2) {
      const isOwner = group_users?.some(
        (user) => currentLoggedUserId === user?.id && user?.is_owner === 1
      );
      if (isOwner) data = "transferred chat";
    }

    if (data) {
      setIsopen({ open: true, data });
      return null;
    }
    const quotationURL = quotationUrl ? quotationUrl : activeUser?.quotationUrl;

    if (!currentTypingMessage?.trim() && !(attachment?.length > 0)) {
      return null;
    }

    const sendMessageAndUpdateState = async (message) => {
      if (
        isChatRequestIsPending &&
        !isMyselfSendedRequest
        // &&  activeUser?.is_group !== 1
      ) {
        return;
      }
      let messageType = "";
      if (isUrl) {
        messageType = "link";
      } else if (attachment?.length > 0) {
        messageType = "file";
      }
      const chatTransferredId = chats[chats?.length - 1]?.chat_transfer_id;

      setIsSending(true);
      const responseJson = await sendMessage({
        currentTypingMessage: message,
        activeUserID:
          activeUserID?.length > 0 ? activeUserID?.split(",")[0] : activeUserID,
        roomId: room_id,
        currentlyLoggedInUserID,
        messageType,
        selectedFiles: attachment,
        chat_transfer_id: chatTransferredId,
        replied_message: replyingMessage,
        replyingId,
      });

      const { messages } = responseJson || {};
      let responseMessage = messages?.message;

      // Update sender's last message in usersList
      const updatedUsersList = usersList?.map((user) => {
        if (user?.room_id === room_id) {
          return { ...user, message: responseMessage };
        }
        return user;
      });

      setAttatchMessageState();
      if (messages) {
        dispatch(UpdateChat([messages]));
        dispatch(setUsersList(updatedUsersList));
        dispatch(setMessage(""));
        setShowEmoji(false);
        setIsUrl(false);
        setUrl("");
        setAttachment([]);
      }
      setIsSending(false);
    };

    await sendMessageAndUpdateState(currentTypingMessage);

    if (quotationUrl) {
      const quotationData = {
        ...activeUser,
        enquiry_user_id: currentLoggedUserId,
        unique_session_id: randomStr(),
      };
      sendQuotation(quotationData);
    }
    // if (quotationURL) {
    //   await sendMessageAndUpdateState(quotationURL);
    // }
    const updatedUser = { ...activeUser, quotationUrl: null };
    dispatch(setActiveUser(updatedUser));
  };

  const debouncedSendMessage = debounce(handleSendMessage, 1000);

  const handleKeyPress = useCallback(
    (event) => {
      if (
        (event?.key === "Enter" && !event?.shiftKey) ||
        event?.type === "click"
      ) {
        event?.preventDefault();
        debouncedSendMessage();
      }
    },
    [debouncedSendMessage]
  );

  const handleSelectEmoji = useCallback(
    (event) => {
      dispatch(setMessage(currentTypingMessage + event?.emoji));
    },
    [dispatch, currentTypingMessage]
  );

  const handleUnblock = useCallback(async () => {
    try {
      const response = await fetch(
        `${BASE_URL_CHAT}block-user?blocked_id=${activeUserID}`,
        {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
            Authorization: `Bearer ${Auth.token()}`,
          },
        }
      );
      if (response.ok) {
        const isUserBlocked = {
          ...activeUser,
          is_blocked: 0,
        };

        dispatch(setActiveUser(isUserBlocked));
        setIsopen({ open: false, data: null });
      }
    } catch (error) {
      console.log(error);
    }
  }, [activeUserID, activeUser, dispatch]);

  const handleCloseBlockDailog = (value) => {
    setIsopen({ open: false, data: null });
  };

  const handleRemoveAttatchment = (index) => {
    setAttachmentUrl((prev) => {
      const newAttachments = [
        ...prev.slice(0, index),
        ...prev.slice(index + 1),
      ];
      return newAttachments;
    });
    setAttachment((prevFiles) => {
      const newFiles = [
        ...prevFiles?.slice(0, index),
        ...prevFiles?.slice(index + 1),
      ];
      return newFiles;
    });
  };

  const renderFile = useCallback((file, index) => {
    const commonProps = {
      style: { maxWidth: "100%", height: "100%" },
      alt: file.type === "image" ? "Uploaded" : "File Icon",
    };
    let fileComponent;
    switch (file.type) {
      case "image":
        fileComponent = <img src={file.url} {...commonProps} />;
        break;
      case "video":
        fileComponent = <video src={file.url} {...commonProps} />;
        break;
      default:
        fileComponent = (
          <img src="assets/chat/documents.png" {...commonProps} />
        );
    }

    return (
      <>
        <ChatImageBox sx={{}}>
          {fileComponent}
          <ChatImageCancelBox>
            <ClearIcon
              onClick={() => handleRemoveAttatchment(index)}
              sx={{ color: "#d7282f", fontSize: "16px !important" }}
            />
          </ChatImageCancelBox>
        </ChatImageBox>
      </>
    );
  }, []);

  const ownerUser = group_users?.find(
    (user) => user.is_owner !== 1 && user?.name !== activelyChattingwithUserName
  );
  const { name = "" } = ownerUser || {};
  return (
    <>
      {attachment?.length > 0 && isSending && (
        <div className="loader-wrapper">
          <div className="loader"></div>
        </div>
      )}
      <BottomTypingAreaOuter>
        <BottomTypingArea>
          {isOpen?.data === "block" ? (
            <AlertDialog
              isOpen={isOpen?.open}
              handleCloseBlockDailog={handleCloseBlockDailog}
              handleUnblock={handleUnblock}
              title="Block & Report Spam"
              description="Blocked contacts cannot call or send you messages. This contact will
            not be notified."
              type="block"
            />
          ) : (
            <AlertDialog
              isOpen={isOpen?.open}
              handleCloseBlockDailog={handleCloseBlockDailog}
              handleUnblock={handleUnblock}
              title="Transferred chat"
              description={`You have currently transferred the chat to ${name} subseller. If you wish to continue the conversation with ${activelyChattingwithUserName}, please pull it back to yourself.`}
            >
              <div>
                <OneFilledButton
                  sx={{ marginTop: "20px" }}
                  variant="contained"
                  onClick={async () => {
                    await transferChat(room_id, currentlyLoggedInUserID);
                    setIsopen({ open: false, data: null });
                  }}
                >
                  {isSubmitting ? (
                    <ThreeDots
                      height="20"
                      width="40"
                      radius="9"
                      color="white"
                      ariaLabel="three-dots-loading"
                      wrapperStyle={{}}
                      visible={true}
                    />
                  ) : (
                    <>Transfer to Myself</>
                  )}
                </OneFilledButton>
              </div>
            </AlertDialog>
          )}
          {/* {isQuotationAttached && quotationUrl && (
          <QuotationMessage
            productDetails={data}
            isQuotationSending={true}
            handleRemoveQuotation={handleRemoveQuotation}
          />
        )} */}
          {quotationUrl && isNewChatInitiating && shouldSendQuotation && (
            <LinkPreview url={quotationUrl} />
          )}
          {isGroupExited ? (
            <>
              {(!isChatRequestIsPending || isMyselfSendedRequest) && (
                <>
                  <AdditionalSuggestionSection dispatch={dispatch} />

                  <Grid container>
                    <Grid item xs={12}>
                      {attatchedMessage && (
                        <ReplyFooterSection>
                          <ClearRoundedIcon
                            className="clearright"
                            onClick={setAttatchMessageState}
                          />
                          <Typography className="replymsg">
                            {" "}
                            {attatchedMessage}
                          </Typography>
                        </ReplyFooterSection>
                      )}
                    </Grid>
                    <Grid item xs={12}>
                      <TypingAreaOuter>
                        <TypingAreaIcons>
                          <Box sx={{ position: "relative" }}>
                            <i
                              className="icon-icon-emoji"
                              onClick={() => setShowEmoji((prev) => !prev)}
                            ></i>
                            <EmojiOpenBox>
                              {showEmoji && (
                                <Emoji onEmojiSelect={handleSelectEmoji} />
                              )}
                            </EmojiOpenBox>
                          </Box>

                          {/* <i className="icon-icon-document"></i> */}
                          {/* <i className="icon-icon-chatgrid"></i> */}
                          <i
                            className="icon-icon-attatchment"
                            onClick={handleFileClick}
                          ></i>
                          <input
                            type="file"
                            ref={fileInputRef}
                            onChange={handleFileChange}
                            multiple
                          />
                          {/* <i className="icon-icon-upload"></i> */}
                        </TypingAreaIcons>
                        {/* <span className="fullscreen-icon">
                    <UnfoldMoreIcon />
                  </span> */}
                      </TypingAreaOuter>
                    </Grid>
                  </Grid>
                  <ChatTypingBox>
                    <Grid container>
                      <Grid item xs={11} spacing={1}>
                        {isUrl && <LinkPreview url={url} />}
                        <Box
                          sx={{
                            display: "flex",
                            flexDirection: "row",
                            gap: "18px",
                          }}
                        >
                          {attachment?.length > 0 &&
                            attachmentURL?.map((item, index) => (
                              <Box key={index}>{renderFile(item, index)}</Box>
                            ))}
                        </Box>
                        {/* <TextField id="outlined-basic-email" placeholder="Please type your message here..." fullWidth /> */}
                        <TextField
                          fullWidth
                          size="small"
                          id="outlined-multiline-static"
                          multiline
                          maxRows={3}
                          // rows={2}
                          placeholder="Please type your message here..."
                          onChange={handleMessageTyping}
                          value={currentTypingMessage}
                          onKeyPress={handleKeyPress}
                        />
                      </Grid>
                      <Grid
                        xs={1}
                        sx={{
                          alignItems: "start",
                          display: "flex",
                          justifyContent: "flex-end",
                        }}
                      >
                        <IconButton
                          aria-label="delete"
                          onClick={handleKeyPress}
                        >
                          <SendIcon className="sendiconhere" />
                        </IconButton>
                      </Grid>
                    </Grid>
                  </ChatTypingBox>
                </>
              )}
            </>
          ) : (
            <GroupLeft />
          )}
        </BottomTypingArea>
      </BottomTypingAreaOuter>
    </>
  );
};

export default TypingArea;
