import React, { useEffect, useRef, useState, useCallback } from "react";
import { FiPaperclip, FiSend } from "react-icons/fi";

import { RootState } from "@/app/store/store";
import { useAppSelector } from "@/app/store/hooks";
import {
  acceptOffer,
  conversationDetail,
  storeMessage,
} from "@/lib/actions/chatActions";
import { checkAuthErrorGet } from "@/lib/checkAuthError";
import { toast } from "react-toastify";
import { useRouter } from "next/navigation";
import { useDispatch } from "react-redux";
import { useTranslations } from "next-intl";
import { FaFileAlt } from "react-icons/fa";
import { IoMdClose } from "react-icons/io";
import { Socket } from "socket.io-client";
import Button from "../common/Button";
import MediaPreviewModal from "../chat/ImagePreviewModal";
import { BiCheck, BiCheckDouble } from "react-icons/bi";
import {
  getImageUrl,
  resolveOtherAttributeSmallImage,
  transparentClass,
} from "@/hooks/useImageUrl";
import { OtherAttribute } from "../../../types/common-types";
import Link from "next/link";

interface Message {
  id: string;
  side: "left" | "right";
  time: string;
  type:
    | "text"
    | "offer"
    | "product-intro"
    | "video"
    | "image"
    | "file"
    | "counter-offer"
    | "delivery-extension";
  text?: string;
  product?: {
    id: number;
    name: string;
    price: string;
    image: string;
    hotCount: number;
    mobileNumber?: string | null;
  };
  offerPrice?: string;
  media?: {
    url: string;
    mimeType?: string;
    filename?: string;
  };
  sender?: any;
  status?: string;
  isRead?: boolean;
}
interface SelectedMedia {
  url: string;
  type: "image" | "video";
}

function ChatWindow({
  conversationId,
  product,
  currUser,
  socket,
}: {
  conversationId: string;
  product: any;
  currUser: any;
  socket: Socket;
}) {
  const router = useRouter();
  const dispatch = useDispatch();
  const t = useTranslations();
  const containerRef = useRef<HTMLDivElement>(null);
  const [messages, setMessages] = useState<Message[]>([]);

  const [page, setPage] = useState<number>(1);
  const [loading, setLoading] = useState<boolean>(false);

  const prevScrollHeightRef = useRef<number>(0);
  const [hasMore, setHasMore] = useState<boolean>(true);
  const { user } = useAppSelector((state: RootState) => state.auth);

  const [text, setText] = useState<string>("");
  const [selectedFile, setSelectedFile] = useState<File | null>(null);
  const fileInputRef = useRef<HTMLInputElement | null>(null);
  const [counterOffer, setCounterOffer] = useState<string>("");

  const [scroll, setScroll] = useState<boolean>(true);

  const [showConfirmModal, setShowConfirmModal] = useState<null | "on">(null);

  const [chatId, setChatId] = useState<string | null>(null);

  const [isTyping, setIsTyping] = useState(false);
  const [typingUserId, setTypingUserId] = useState<string | null>(null);
  const [socketConnected, setSocketConnected] = useState(false);
  const [reconnectAttempts, setReconnectAttempts] = useState(0);

  const typingTimeoutRef = useRef<NodeJS.Timeout>();
  const reconnectTimeoutRef = useRef<NodeJS.Timeout>();
  const conversationIdRef = useRef(conversationId);
  const currUserRef = useRef(currUser);
  const socketRef = useRef<Socket | null>(null);

  const [inputRequired, setInputRequired] = useState<boolean>(false);
  const inputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    if (inputRequired) {
      const timer = setTimeout(() => {
        setInputRequired(false);
      }, 2000);

      return () => clearTimeout(timer);
    }
  }, [inputRequired]);

  useEffect(() => {
    conversationIdRef.current = conversationId;
    currUserRef.current = currUser;
  }, [conversationId, currUser]);

  const fetchConversationDetail = async () => {
    // if (!conversationId || !user?.id || !hasMore) return;

    try {
      setLoading(true);
      const res: any = await conversationDetail(user.token, conversationId, {
        page: page,
      });

      const apiMessages = res.data.messages || [];
      const totalPages = res.data.totalPages ?? 0;

      setHasMore(page < totalPages);

      const initialChat: Message = {
        id: "initial",
        side: product.seller === user.id ? "left" : "right",
        time: product.createdAt,
        type: product.seller === user.id ? "product-intro" : "offer",
        product: {
          id: product?.productId,
          name: product.product.title,
          price: `${
            process.env.NEXT_PUBLIC_CURRENCY_TYPE
          } ${product.product.price.toLocaleString()}`,
          image: resolveOtherAttributeSmallImage({
            otherAttr: {
              ...(product?.product?.otherAttribute as OtherAttribute),
              valueType: product?.product?.otherAttribute?.valueType,
            },
            productImage: product.product.image,
          }) as string,
          mobileNumber: product.product.isOtherAttribute
            ? product.product.otherAttribute.content[0].number
            : null,
          hotCount: 3,
        },
        status: "read",
        isRead: true,
      };

      if (
        (product?.initialOffer !== undefined &&
          product.initialOffer.toLocaleString()) != 0
      ) {
        initialChat.offerPrice = product.initialOffer.toLocaleString();
      }

      if (
        product?.initialText !== undefined &&
        product.initialText?.trim() != ""
      ) {
        initialChat.text = product.initialText;
      }
      let convertedChats = apiMessages.map((msg: any) => {
        const side = msg.sender === user.id ? "right" : "left";
        const date = new Date(msg.createdAt);
        const formattedTime = date.toLocaleTimeString("en-US", {
          hour: "2-digit",
          minute: "2-digit",
          hour12: true,
        });

        const mimeType = msg.attachment?.[0]?.mimeType || "";
        const isMedia =
          mimeType.startsWith("image/") ||
          mimeType.startsWith("video/") ||
          mimeType.length > 0;

        const hasAttachment = msg.attachment && msg.attachment.length > 0;

        const isOffer =
          hasAttachment && !isMedia && /\$?\s?(\d{3,6})/.test(msg.text);

        const isCounterOffer = msg.offer;
        const isDeliveryExtension = msg?.deliveryExtension;

        if (isCounterOffer) {
          return {
            id: msg._id,
            side,
            time: formattedTime,
            sender: msg.sender,
            type: "counter-offer",
            text: msg.text,
            offerType: msg.offer,
            status: msg.status,
            isRead: msg.isRead,
          };
        }

        if (isDeliveryExtension) {
          return {
            id: msg._id,
            side,
            time: formattedTime,
            sender: msg.sender,
            type: "delivery-extension",
            text: msg.text,
            offerType: msg.offer,
            status: msg.status,
            isRead: msg.isRead,
          };
        }

        if (isOffer) {
          const offerPriceMatch = msg.text.match(/\$?\s?(\d{3,6})/);
          const offerPrice = offerPriceMatch
            ? `${process.env.NEXT_PUBLIC_CURRENCY_TYPE} ${offerPriceMatch[1]}`
            : null;

          return {
            id: msg._id,
            side,
            time: formattedTime,
            sender: msg.sender,
            type: "offer",
            product: {
              id: 1,
              name: product.product.title,
              price: `${
                process.env.NEXT_PUBLIC_CURRENCY_TYPE
              } ${product.product.price.toLocaleString()}`,
              image: msg.attachment[0]?.url || product.product.image,
              hotCount: 3,
            },
            offerPrice,
            text: msg.text,
            status: msg.status,
            isRead: msg.isRead,
          };
        }

        if (isMedia) {
          return {
            id: msg._id,
            sender: msg.sender,
            side,
            time: formattedTime,
            type: mimeType.startsWith("image/")
              ? "image"
              : mimeType.startsWith("video/")
                ? "video"
                : "file",
            media: {
              url: msg.attachment[0].url,
              mimeType: mimeType,
              filename: msg.attachment[0].filename,
            },
            text: msg.text,
            status: msg.status,
            isRead: msg.isRead,
          };
        }

        return {
          id: msg._id,
          side,
          time: formattedTime,
          sender: msg.sender,
          type: "text",
          text: msg.text,
          status: msg.status,
          isRead: msg.isRead,
        };
      });

      convertedChats = [...convertedChats].reverse();

      setMessages((prev) => {
        if (page === 1 && totalPages > 1) {
          return [...convertedChats];
        }

        if (page === 1 && (totalPages === 1 || totalPages === 0)) {
          return [initialChat, ...convertedChats];
        }

        if (page === totalPages) {
          return [initialChat, ...convertedChats, ...prev];
        }

        return [...convertedChats, ...prev];
      });
    } catch (error: any) {
      if (checkAuthErrorGet(error, dispatch, router)) return;

      const errorMsg =
        error?.response?.data?.message || t("validation.error_msg");
      toast.error(errorMsg);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    fetchConversationDetail();
  }, [page]);

  const scrollToBottom = (force = false) => {
    const container = containerRef.current;
    if (!container) return;

    const threshold = 100;
    const isNearBottom =
      container.scrollHeight - container.scrollTop - container.clientHeight <
      threshold;

    if (scroll || isNearBottom) {
      container.scrollTo({
        top: container.scrollHeight,
        behavior: "smooth",
      });
    }
  };

  useEffect(() => {
    const container = containerRef.current;
    if (!container) return;

    if (scroll) {
      scrollToBottom(false);
    } else {
      const newScrollHeight = container.scrollHeight;
      const scrollDiff = newScrollHeight - prevScrollHeightRef.current;

      container.scrollTop = scrollDiff;

      setScroll(true);
    }

    prevScrollHeightRef.current = container.scrollHeight;
  }, [messages]);

  const handleScroll = () => {
    const container = containerRef.current;
    if (!container || loading || !hasMore) return;

    if (container.scrollTop === 0) {
      prevScrollHeightRef.current = container.scrollHeight;
      setPage((prev) => prev + 1);
      setScroll(false);
      return;
    }
  };

  const handleTextChange = useCallback(
    (e: React.ChangeEvent<HTMLInputElement>) => {
      setInputRequired(false);
      const newText = e.target.value;
      setText(newText);

      // Clear existing timeout
      if (typingTimeoutRef.current) {
        clearTimeout(typingTimeoutRef.current);
      }

      if (newText.length > 0) {
        // Emit typing start immediately
        socket.emit("handle_typing", {
          conversationId: conversationIdRef.current,
          receiverId: currUserRef.current?._id,
          flag: true,
        });

        // Set timeout to stop typing after 1 second of inactivity
        typingTimeoutRef.current = setTimeout(() => {
          socket.emit("handle_typing", {
            conversationId: conversationIdRef.current,
            receiverId: currUserRef.current?._id,
            flag: false,
          });
        }, 1000);
      } else {
        // If text is empty, immediately stop typing
        socket.emit("handle_typing", {
          conversationId: conversationIdRef.current,
          receiverId: currUserRef.current?._id,
          flag: false,
        });
      }
    },
    [socket],
  );

  const socketListener = useCallback(() => {
    if (!socket) return;

    const handleConnect = () => {
      setSocketConnected(true);
      setReconnectAttempts(0);

      // // Re-mark conversation as read on reconnect
      socket.emit("conversation_read", {
        conversationId: conversationIdRef.current,
        userId: currUserRef.current?._id,
      });
    };

    const handleDisconnect = (reason: string) => {
      // console.log("❌ Socket disconnected:", reason);
      setSocketConnected(false);

      // Attempt reconnection for certain disconnect reasons
      if (reason === "io server disconnect" || reason === "transport close") {
        const attempt = reconnectAttempts + 1;
        setReconnectAttempts(attempt);

        const delay = Math.min(1000 * Math.pow(2, attempt), 30000); // Exponential backoff max 30s
        reconnectTimeoutRef.current = setTimeout(() => {
          socket.connect();
        }, delay);
      }
    };

    const handleConnectError = (error: Error) => {
      // console.error("Socket connection error:", error);
      setSocketConnected(false);
    };

    const handleMessage = (msg: any) => {
      setScroll(true);

      if (msg?.offer?.status == "accepted") {
        fetchConversationDetail();
        return;
      }
      const {
        sender,
        text,
        attachment,
        status,
        _id,
        conversationId: convId,
        offer,
      } = msg;
      const isCurrentUser = sender === user.id;

      const newMessage = {
        id: _id || `temp-${Date.now()}`,
        side: isCurrentUser ? "right" : "left",
        time: new Date().toLocaleTimeString("en-US", {
          hour: "2-digit",
          minute: "2-digit",
          hour12: true,
        }),
        type:
          attachment.length > 0
            ? attachment[0].mimeType.startsWith("image/")
              ? "image"
              : attachment[0].mimeType.startsWith("video/")
                ? "video"
                : "file"
            : msg.offer
              ? "counter-offer"
              : "text",
        media:
          attachment.length > 0
            ? {
                url: attachment[0].url,
                mimeType: attachment[0].type,
                filename: attachment[0].name,
              }
            : undefined,
        text: text,
        sender: {
          id: sender,
          name: sender?.name,
          avatar: sender?.avatar,
        },
        status: status || "sent",
        offerType: msg.offer,
      };
      if (conversationIdRef.current === convId) {
        // @ts-ignore
        setMessages((prev) => [...prev, newMessage]);
      }
    };

    const handleReceivedMessage = (data: any) => {
      const {
        conversationId: convId,
        messageId,
        senderId,
        receiverId,
      } = data.data;

      // Use ref values for comparison
      if (
        conversationIdRef.current === convId &&
        senderId === currUserRef.current?._id
      ) {
        socket.emit("chat_message_read", {
          conversationId: conversationIdRef.current,
          messageId,
          senderId,
        });
      }
    };

    const handleTypingStart = (data: any) => {
      const { conversationId, receiverId } = data;

      if (
        conversationId === conversationIdRef.current &&
        receiverId === user.id
      ) {
        setIsTyping(true);
      }
    };

    const handleTypingStop = (data: any) => {
      const { conversationId, receiverId } = data;
      if (
        conversationId === conversationIdRef.current &&
        receiverId === user.id
      ) {
        setIsTyping(false);
      }
    };

    const handleChatMessageRead = (data: any) => {
      // if(data.conversationId === containerRef.current) {
      setMessages((prev) =>
        prev.map((item) =>
          data.messageId === item.id
            ? { ...item, status: "read", isRead: true }
            : item,
        ),
      );
    };

    const handleConversationRead = (data: any) => {
      // mark all messages read
      setMessages((prev) =>
        prev.map((item) => ({
          ...item,
          status: "read",
          isRead: true,
        })),
      );
    };

    socket.on("connect", handleConnect);
    socket.on("disconnect", handleDisconnect);
    socket.on("connect_error", handleConnectError);
    socket.on("message_received", handleMessage);
    socket.on("user_typing_start", handleTypingStart);
    socket.on("received_messaged", handleReceivedMessage);
    socket.on("user_typing_stop", handleTypingStop);
    socket.on("chat_message_read", handleChatMessageRead);
    socket.on("conversation_read", handleConversationRead);

    if (socket.connected) {
      setSocketConnected(true);
    }

    // Store socket reference
    socketRef.current = socket;

    return () => {
      socket.off("connect", handleConnect);
      socket.off("disconnect", handleDisconnect);
      socket.off("connect_error", handleConnectError);
      socket.off("message_received", handleMessage);
      socket.off("received_messaged", handleReceivedMessage);
      socket.off("user_typing_start", handleTypingStart);
      socket.off("user_typing_stop", handleTypingStop);
      socket.off("chat_message_read", handleChatMessageRead);
      socket.off("conversation_read", handleConversationRead);

      // Clear timeouts
      if (typingTimeoutRef.current) {
        clearTimeout(typingTimeoutRef.current);
      }
      if (reconnectTimeoutRef.current) {
        clearTimeout(reconnectTimeoutRef.current);
      }
    };
  }, [socket, user?.id, typingUserId, reconnectAttempts]);

  useEffect(() => {
    const cleanup = socketListener();
    return cleanup;
  }, [socketListener]);

  const sendMessage = async () => {
    if (inputRef && inputRef.current) inputRef.current.focus();
    try {
      if (!text.trim() && !counterOffer.trim() && !selectedFile) {
        setInputRequired(true);
        return;
      }

      if (typingTimeoutRef.current) {
        clearTimeout(typingTimeoutRef.current);
      }

      socket.emit("handle_typing", {
        conversationId: conversationIdRef.current,
        receiverId: currUserRef.current?._id,
        flag: false,
      });
      setIsTyping(false);

      setLoading(true);

      const formData = new FormData();
      formData.append("conversationId", conversationId);
      formData.append("sender", user.id);
      formData.append("text", text);

      formData.append("isSeller", String(currUser.seller === user.id));
      formData.append("productId", product?.productId);

      if (user.id === currUser.seller) {
        formData.append("type", "buy_now");
      } else {
        formData.append("type", "counter_offer");
      }

      if (counterOffer.trim() != "") {
        formData.append("amount", counterOffer);
      }

      if (selectedFile) {
        formData.append("attachment", selectedFile);
      }

      setText("");
      setCounterOffer("");
      setSelectedFile(null);

      await storeMessage(user.token, formData);

      await fetchConversationDetail();
    } catch (error: any) {
      if (checkAuthErrorGet(error, dispatch, router)) return;

      const errorMsg =
        error?.response?.data?.message || t("validation.error_msg");
      toast.error(errorMsg);
    } finally {
      setLoading(false);
    }
  };

  const handleFileSelect = (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0];
    if (file) {
      setSelectedFile(file);
    }
  };

  const handleIconClick = () => {
    fileInputRef.current?.click();
  };

  const handleRemoveFile = () => {
    setSelectedFile(null);
    if (fileInputRef.current) fileInputRef.current.value = "";
  };

  const handleAcceptOffer = async () => {
    try {
      setLoading(true);
      if (!chatId) return;

      const response = await acceptOffer(user.token, {
        chatId: chatId,
        action: "accept",
      });

      if (response.success) {
        toast.success("Offer Accepted");
      }
    } catch (error: any) {
      if (checkAuthErrorGet(error, dispatch, router)) return;

      const errorMsg =
        error?.response?.data?.message || t("validation.error_msg");
      toast.error(errorMsg);
    } finally {
      setLoading(false);
      setShowConfirmModal(null);
    }
  };

  const handleBuyNow = async (data: { chatId: string; sender: string }) => {
    const { chatId, sender } = data;

    const payload = {
      chatId: chatId,
      sender: sender,
      conversationId,
      productId: product.productId,
    };

    const queryString = new URLSearchParams(payload).toString();

    router.push(`/checkout?${queryString}`);
  };

  const handleProductRedirect = async (id: string) => {
    router.push(`/products/${id}`);
  };

  const [selectedMedia, setSelectedMedia] = useState<SelectedMedia | null>(
    null,
  );

  return (
    <div className="relative h-full chatbg">
      {/* Message content can go here */}
      <div>
        <div
          ref={containerRef}
          onScroll={handleScroll}
          className={`custom-scrollbar flex-1 justify-end overflow-y-auto space-y-6 m-1 mb-0 p-8 pb-8 pr-1.5 rtl:pl-1.5 max-2xl:pl-1.5 ${
            !selectedFile
              ? "h-[calc(100vh-280px)]"
              : selectedFile.type.startsWith("image/")
                ? "h-[calc(100vh-370px)]"
                : "h-[calc(100vh-326px)]"
          }`}
        >
          {messages.length > 0 &&
            messages.map((msg: any, index: number) => (
              <div
                key={index}
                className={
                  msg.side === "left"
                    ? "leftchat"
                    : "flex flex-col w-fit ml-auto items-end justify-end right-chat rtl:mr-auto rtl:ml-0"
                }
              >
                {/* Left Chat Avatar */}
                {msg.side === "left" && (
                  <div>
                    <div className="flex items-start gap-3">
                      <div className="w-8 h-8">
                        <img
                          src={`${getImageUrl(currUser?.profileImage?.url, true)}`}
                          alt="William"
                          onError={(e) => {
                            if (
                              e.currentTarget.src.endsWith(
                                "/profile-avatar.png",
                              )
                            )
                              return;
                            e.currentTarget.onerror = null;
                            e.currentTarget.src = "/profile-avatar.png";
                          }}
                          className="w-8 h-8 rounded-full"
                        />
                      </div>
                      <div className="w-[calc(100%-32px)]">
                        {msg?.type === "product-intro" && (
                          <>
                            <div
                              className="max-w-[342px] flex p-2.5 border rounded-lg bg-white border-neutrals100 gap-2 dark:bg-background dark:border-darkborder cursor-pointer"
                              onClick={() =>
                                handleProductRedirect(msg?.product?.id)
                              }
                            >
                              <div>
                                <img
                                  src={msg?.product?.image}
                                  alt="Preview"
                                  className={`w-[93px] h-[93px] rounded-md object-cover ${transparentClass}`}
                                />
                              </div>
                              <div className="w-fit">
                                <p className="font-semibold text-sm text-neutrals800 line-clamp-2 mb-1 dark:text-neutrals300">
                                  {msg?.product?.name}
                                </p>
                                <p className="text-sm font-bold text-primary500 dark:text-primary400">
                                  {msg?.product?.price}
                                </p>
                                <p className="text-sm font-bold text-primary500 dark:text-primary400">
                                  {msg?.product?.mobileNumber}
                                </p>
                              </div>
                            </div>
                          </>
                        )}

                        {msg?.type === "image" && msg?.media?.url && (
                          <div>
                            <img
                              src={`${process.env.NEXT_PUBLIC_API}${msg?.media?.url}`}
                              alt="Image message"
                              className="max-w-[342px] rounded-lg object-cover cursor-pointer"
                              onClick={() =>
                                setSelectedMedia({
                                  url: `${process.env.NEXT_PUBLIC_API}${msg?.media?.url}`,
                                  type: "image",
                                })
                              }
                            />
                          </div>
                        )}

                        {msg?.type === "video" && msg?.media?.url && (
                          <div
                            className="max-w-[342px] rounded-lg overflow-hidden cursor-pointer"
                            onClick={() =>
                              setSelectedMedia({
                                url: `${process.env.NEXT_PUBLIC_API}${msg?.media?.url}`,
                                type: "video",
                              })
                            }
                          >
                            <video
                              controls
                              className="w-full h-auto object-cover rounded-lg"
                            >
                              <source
                                src={`${process.env.NEXT_PUBLIC_API}${msg?.media?.url}`}
                                type={msg?.media?.mimeType || "video/mp4"}
                              />
                              {t("doesnot_support_video")}
                            </video>
                          </div>
                        )}
                        {msg?.type === "file" && msg?.media?.url && (
                          <div className="flex items-center gap-4 p-3 rounded-lg bg-gray-100 dark:bg-darkbg border border-gray-300 dark:border-darkborder max-w-[342px]">
                            <div className="truncate text-sm font-medium text-gray-800 dark:text-white max-w-[200px]">
                              {msg?.media?.filename || "Untitled File"}
                            </div>
                            <a
                              href={`${process.env.NEXT_PUBLIC_API}${msg?.media?.url}`}
                              download
                              className="px-3 py-1 text-sm font-semibold text-white bg-primary100 rounded hover:bg-primary200 transition"
                            >
                              {t("chat.download")}
                            </a>
                          </div>
                        )}

                        {msg.type !== "delivery-extension" &&
                          msg?.text?.trim().length > 0 && (
                            <p className="bg-white w-fit px-4 py-2 rounded-md rounded-bl-none text-sm mt-0 mr-3 mb-1 dark:bg-background dark:text-neutrals200 rtl:mr-0 rtl:ml-3 rtl:rounded-br-none rtl:rounded-md">
                              {msg?.text}
                            </p>
                          )}

                        {/* Show Counter offer made by buyer or seller */}
                        {msg?.type == "counter-offer" &&
                          msg?.offerType &&
                          msg?.offerType?.type === "counter_offer" && (
                            <div className="flex flex-col w-fit mr-auto items-start justify-start right-chat rtl:mr-auto rtl:ml-0 pr-[100px] rtl:pr-0 rtl:pl-0">
                              <div className="max-w-fit min-w-[200px] ml-auto border rounded-lg overflow-hidden bg-white border-neutrals200 dark:bg-background dark:border-darkborder">
                                <div className="flex items-center justify-between gap-1 bg-neutrals100 p-2.5 dark:bg-gray-700">
                                  <span className="text-sm text-primary500 dark:text-neutrals300">
                                    {msg?.offerType?.type == "counter_offer"
                                      ? `${t("chat.counter_offer")}:`
                                      : `${t("chat.seller_offer")}:`}
                                  </span>
                                  <span className="text-sm text-primary500 font-bold dark:text-primary400">
                                    {process.env.NEXT_PUBLIC_CURRENCY_TYPE}{" "}
                                    {msg?.offerType?.amount}
                                  </span>
                                </div>
                                <button
                                  onClick={() => {
                                    // show modal popup
                                    setShowConfirmModal("on");
                                    setChatId(msg.id);
                                  }}
                                  type="button"
                                  disabled={
                                    msg?.offerType?.status === "accepted"
                                  }
                                  className="w-full text-xs capitalize font-bold text-white p-2 bg-kzgreen600 rounded-sm"
                                  aria-label="Accept offer"
                                >
                                  {t("chat.accept_offer")}
                                </button>
                              </div>
                            </div>
                          )}

                        {/* Button to make buyer buy */}
                        {msg?.type === "counter-offer" &&
                          msg?.offerType &&
                          msg?.offerType?.type === "buy_now" && (
                            <div className="flex flex-col w-fit">
                              {/* <div className="text-xs text-neutrals500 mb-1.5 pl-10 ml-1 rtl:pl-0 dark:text-neutrals400 rtl:mr-1 rtl:ml-auto">
                                  09 Sep 25 04:25 PM
                                </div> */}
                              <div className="max-w-[342px] min-w-[200px] ml-auto rounded-lg overflow-hidden bg-white rtl:mr-auto rtl:ml-0 dark:bg-background">
                                <button
                                  onClick={() => {
                                    handleBuyNow({
                                      chatId: msg.id,
                                      sender: msg.sender,
                                    });
                                  }}
                                  type="button"
                                  className="w-full text-xs capitalize font-bold text-white p-2 bg-primary400 rounded-sm dark:border-primary400"
                                  aria-label="Buy now"
                                >
                                  {t("chat.buy_now")}:{" "}
                                  {process.env.NEXT_PUBLIC_CURRENCY_TYPE}{" "}
                                  {msg?.offerType?.amount}
                                </button>
                              </div>
                            </div>
                          )}

                        {/* Left side, that means seller has request so redirect to buyer's order page */}
                        {msg?.type === "delivery-extension" && (
                          <Link
                            href={`/my-orders?id=${conversationId}`}
                            className="bg-white w-fit px-4 py-2 rounded-md rounded-bl-none text-sm mt-0 mr-3 mb-1 dark:bg-background dark:text-neutrals200 rtl:mr-0 rtl:ml-3 rtl:rounded-br-none rtl:rounded-md"
                          >
                            {msg?.text}
                          </Link>
                        )}
                      </div>
                    </div>
                  </div>
                )}

                {/* Right Chat */}
                {msg.side === "right" && (
                  <>
                    {msg?.type === "text" && (
                      <>
                        <div className="bg-primary500 text-white px-4 py-3 rounded-br-none ml-3 rounded-lg text-sm rtl:rounded-bl-none rtl:rounded-br-md dark:bg-primary400 rtl:ml-0">
                          {msg.text}
                        </div>
                      </>
                    )}

                    {msg?.type === "delivery-extension" && (
                      <Link
                        href={`/my-orders?id=${conversationId}`}
                        className="bg-primary500 text-white px-4 py-3 rounded-br-none ml-3 rounded-lg text-sm rtl:rounded-bl-none rtl:rounded-br-md dark:bg-primary400 rtl:ml-0"
                      >
                        {msg?.text}
                      </Link>
                    )}

                    {msg?.type === "counter-offer" && msg?.offerType && (
                      <div className="flex flex-col w-fit ml-auto items-end justify-end right-chat rtl:ml-auto rtl:mr-0 pl-[100px] rtl:pl-0 rtl:pr-[0]">
                        {msg?.text.trim().length > 0 && (
                          <div className="flex items-end gap-2 mb-2">
                            <p className="bg-primary500 text-white px-4 py-3 rounded-md rounded-br-none text-sm dark:bg-primary400">
                              {msg?.text}
                            </p>
                          </div>
                        )}
                        <div className="max-w-fit min-w-[200px] ml-auto border rounded-lg overflow-hidden bg-white border-neutrals200 dark:bg-background dark:border-darkborder">
                          <div className="flex items-center justify-between gap-1 bg-neutrals100 p-2.5 dark:bg-gray-700">
                            <span className="text-sm text-primary500 dark:text-neutrals300">
                              {msg?.offerType?.type == "counter_offer"
                                ? `${t("chat.counter_offer")}:`
                                : `${t("chat.seller_offer")}:`}
                            </span>
                            <span className="text-sm text-primary500 font-bold dark:text-primary400">
                              {process.env.NEXT_PUBLIC_CURRENCY_TYPE}{" "}
                              {msg?.offerType?.amount}
                            </span>
                          </div>
                        </div>
                      </div>
                    )}

                    {msg?.type === "offer" && (
                      <div className="flex items-end gap-3 rtl:items-start">
                        <div>
                          <div
                            className="max-w-[342px] ml-auto border rounded-lg overflow-hidden bg-white border-neutrals200 rtl:mr-auto rtl:ml-0 dark:bg-background dark:border-card cursor-pointer"
                            onClick={() =>
                              handleProductRedirect(msg?.product?.id)
                            }
                          >
                            <div className="flex items-start p-2.5 gap-2">
                              <div>
                                <img
                                  src={msg?.product?.image}
                                  alt="Preview"
                                  className={`w-[93px] h-[93px] rounded-md object-cover ${transparentClass}`}
                                />
                              </div>
                              <div className="w-fit">
                                <p className="font-semibold text-sm text-neutrals800 line-clamp-2 mb-1 dark:text-neutrals200">
                                  {msg?.product?.name}
                                </p>
                                <p className="text-sm font-bold text-primary500 dark:text-primary400">
                                  {msg?.product?.price}
                                </p>
                                <p className="text-sm font-bold text-primary500 dark:text-primary400">
                                  {msg?.product?.mobileNumber}
                                </p>
                              </div>
                            </div>
                            {msg.offerPrice && (
                              <div className="flex items-center justify-between gap-1 bg-neutrals100 p-2.5 dark:bg-darkbg">
                                <span className="text-sm text-primary500 dark:text-neutrals400">
                                  {t("chat.offered_price")}:
                                </span>
                                <span className="text-sm text-primary500 font-bold dark:text-primary400">
                                  {msg?.offerPrice}
                                </span>
                              </div>
                            )}
                          </div>
                          {msg.text && (
                            <p className="bg-primary500 text-white px-4 py-3 ml-3 rounded-md rounded-br-none text-sm mt-2.5 rtl:rounded-bl-none rtl:rounded-br-md dark:bg-primary400">
                              {msg?.text}
                            </p>
                          )}
                        </div>
                      </div>
                    )}

                    {msg?.type === "image" && msg?.media?.url && (
                      <div>
                        <img
                          src={`${process.env.NEXT_PUBLIC_API}${msg?.media?.url}`}
                          alt="Image message"
                          className="max-w-[342px] rounded-lg object- cursor-pointer max-md:max-w-[250px]"
                          onClick={() =>
                            setSelectedMedia({
                              url: `${process.env.NEXT_PUBLIC_API}${msg.media?.url}`,
                              type: "image",
                            })
                          }
                        />
                        {msg.text && (
                          <div className="bg-primary500 text-white px-4 py-3 rounded-br-none ml-3 rounded-lg text-sm rtl:rounded-bl-none rtl:rounded-br-md dark:bg-primary400">
                            {msg.text}
                          </div>
                        )}
                      </div>
                    )}

                    {msg?.type === "video" && msg?.media?.url && (
                      <div
                        className="max-w-[342px] rounded-lg overflow-hidden cursor-pointer"
                        onClick={() =>
                          setSelectedMedia({
                            url: `${process.env.NEXT_PUBLIC_API}${msg?.media?.url}`,
                            type: "video",
                          })
                        }
                      >
                        <video
                          controls
                          className="w-full h-auto object-cover rounded-lg"
                        >
                          <source
                            src={`${process.env.NEXT_PUBLIC_API}${msg?.media?.url}`}
                            type={msg?.media?.mimeType || "video/mp4"}
                          />
                          {t("doesnot_support_video")}
                        </video>
                      </div>
                    )}

                    {msg?.type === "file" && msg?.media?.url && (
                      <div className="flex items-center gap-4 p-3 rounded-lg bg-gray-100 dark:bg-darkbg border border-gray-300 dark:border-darkborder max-w-[342px]">
                        <div className="truncate text-sm font-medium text-gray-800 dark:text-white max-w-[200px]">
                          {msg?.media?.filename || "Untitled File"}
                        </div>
                        <a
                          href={`${process.env.NEXT_PUBLIC_API}${msg?.media?.url}`}
                          download
                          className="px-3 py-1 text-sm font-semibold text-white bg-primary500  transition"
                        >
                          {t("chat.download")}
                        </a>
                      </div>
                    )}
                  </>
                )}

                <div
                  className={`${
                    msg.side === "right" ? "mt-1" : ""
                  } flex gap-0.5`}
                >
                  {/* Time */}
                  <div
                    className={`text-xs text-neutrals500 mb-1.5 ${
                      msg.side === "left"
                        ? "pl-10 ml-1 rtl:pr-11"
                        : "pr-0 rtl:pl-0"
                    } dark:text-neutrals400`}
                  >
                    {msg.time}
                  </div>
                  {/* checkmark */}
                  {msg.side === "right" && (
                    <div className="">
                      {msg.status === "read" && msg.isRead === true && (
                        <div>
                          <BiCheckDouble className="text-kzgreen600" />
                        </div>
                      )}
                      {msg.status !== "read" && msg.isRead === false && (
                        <div>
                          <BiCheck className="text-neutrals400" />
                        </div>
                      )}
                    </div>
                  )}
                </div>
              </div>
            ))}

          {isTyping && (
            <div className="w-fit mt-2 bg-white p-1 px-2 rounded-md translate-y-[10px] dark:bg-darkbg">
              <div className="flex items-center space-x-1.5">
                <span className="text-sm font-normal text-neutrals500 dark:text-neutrals400">
                  {t("typing")}
                </span>
                <span className="flex space-x-1">
                  <span className="text-xl font-semibold text-neutrals400 rounded-full animate-bounce">
                    .
                  </span>
                  <span className="text-xl font-semibold text-neutrals400 rounded-full animate-bounce [animation-delay:0.2s]">
                    .
                  </span>
                  <span className="text-xl font-semibold text-neutrals400 rounded-full animate-bounce [animation-delay:0.4s]">
                    .
                  </span>
                </span>
              </div>
            </div>
          )}
        </div>
        {showConfirmModal && (
          <div
            className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-30 w-full top-0 left-0"
            onClick={() => setShowConfirmModal(null)}
          >
            <div
              onClick={(e) => e.stopPropagation()}
              className="bg-white rounded-xl shadow-2xl p-6 w-full max-w-sm dark:bg-darkbg transition-all"
            >
              <div className="flex items-start gap-3 mb-4">
                <div className="flex-shrink-0 mt-1">
                  <svg
                    className="w-6 h-6 text-red-500"
                    fill="none"
                    stroke="currentColor"
                    strokeWidth="2"
                    viewBox="0 0 24 24"
                  >
                    <path
                      strokeLinecap="round"
                      strokeLinejoin="round"
                      d="M12 9v2m0 4h.01M5.07 19H18.93a2 2 0 001.78-2.9l-6.93-12a2 2 0 00-3.56 0l-6.93 12a2 2 0 001.78 2.9z"
                    />
                  </svg>
                </div>

                <div>
                  <h2 className="text-lg font-bold text-neutrals800 dark:text-neutrals100">
                    {t("chat.confirm_accept_offer")}
                  </h2>
                  <p className="mt-1 text-sm text-neutrals600 dark:text-neutrals300">
                    {t("chat.confirm_accept_offer_message")}
                  </p>
                </div>
              </div>

              <hr className="my-4 border-t border-neutrals200 dark:border-neutrals700" />

              <div className="flex justify-end gap-3">
                <Button
                  variant="outline"
                  onClick={() => setShowConfirmModal(null)}
                  label={t("chat.cancel")}
                />

                <Button
                  label={
                    loading ? `${t("chat.accepting")}...` : t("chat.accept")
                  }
                  type="button"
                  onClick={() => handleAcceptOffer()}
                  disabled={loading}
                  variant="outline"
                />
              </div>
            </div>
          </div>
        )}
      </div>

      {/* Input Box */}
      <div className="w-full absolute bottom-0 left-0 p-1 max-lg:bottom-1.5">
        <div className="w-full p-4 flex items-end bg-white rounded-lg dark:bg-background max-sm:px-2 max-sm:py-3">
          <div className="relative w-full">
            {/* File preview */}
            {selectedFile && (
              <div className="mb-2 flex items-start gap-3 p-2 border border-neutrals200 rounded bg-neutrals100  dark:bg-darkbg dark:border-darkborder">
                {selectedFile.type.startsWith("image/") ? (
                  <img
                    src={URL.createObjectURL(selectedFile)}
                    alt="preview"
                    className="w-16 h-16 object-cover rounded"
                  />
                ) : (
                  <div className="flex items-center gap-2">
                    <FaFileAlt className="text-gray-500" />
                    <span className="text-sm">{selectedFile.name}</span>
                  </div>
                )}
                <button
                  onClick={handleRemoveFile}
                  className="ml-auto text-red-500 dark:text-white opacity-90 hover:opacity-100 rtl:mr-auto rtl:ml-0"
                  aria-label="Close"
                >
                  <IoMdClose size={18} />
                </button>
              </div>
            )}

            {/* Input field */}
            <div className="relative w-full">
              {inputRequired && (
                <span className="w-full absolute left-0 -top-7 z-30 text-sm bg-neutrals100 p-1 px-2 border border-neutrals300 rounded-[4px] rounded-b-none mb-0 dark:text-neutrals100 dark:bg-darkbg dark:border-darkborder">
                  {t("please_enter_something")}
                </span>
              )}
              <input
                ref={inputRef}
                type="text"
                placeholder={t("chat.type_message")}
                value={text}
                autoFocus
                onChange={handleTextChange}
                onKeyDown={(e) => {
                  if (e.key === "Enter" && !e.shiftKey) {
                    e.preventDefault();
                    sendMessage();
                  }
                }}
                className="w-full bg-neutrals100 px-4 py-2.5 min-h-11 pl-3 pr-[240px] border border-neutrals100 rounded-md font-normal text-sm placeholder:text-neutrals400 focus:outline-none focus:ring-1 focus:ring-primary500 dark:bg-darkbg dark:border-darkborder dark:text-neutrals100 dark:focus:ring-primary400 rtl:pl-[260px] rtl:pr-3 max-sm:pr-[150px] max-sm:rtl:pl-[150px]"
              />

              <div className="counter-amount absolute right-1 top-1/2 -translate-y-1/2 rtl:left-0.5 rtl:right-auto max-sm:max-w-28">
                <input
                  type="number"
                  name="amount"
                  value={counterOffer}
                  onChange={(e) => {
                    let value = Number(e.target.value);
                    if (value < 0) {
                      value = 0;
                    } else {
                      setCounterOffer(e.target.value);
                    }
                  }}
                  className="bg-neutrals100 py-2.5 min-h-11 px-3 border border-neutrals100 font-normal text-sm placeholder:text-neutrals400 dark:bg-darkbg dark:border-darkborder border-r-0 dark:text-neutrals100 border-l-gray-300 focus:outline-none focus:ring-1 focus:ring-primary500 dark:focus:ring-primary400 focus:rounded-md rtl:border-l-0 rtl:border-r-gray-300 rtl:border-r max-sm:w-full max-sm:px-1"
                  placeholder={t("chat.type_counter_offer")}
                  id="CounterAmount"
                />
              </div>

              <FiPaperclip
                className="absolute right-[210px] top-1/2 -translate-y-1/2 text-neutrals500 cursor-pointer rtl:right-auto rtl:left-[210px] max-sm:right-[125px] max-sm:rtl:left-[125px]"
                size={18}
                onClick={handleIconClick}
              />
              <input
                type="file"
                name="attachment"
                ref={fileInputRef}
                onChange={handleFileSelect}
                style={{ display: "none" }}
              />
            </div>
          </div>
          <button
            onClick={sendMessage}
            className="w-11 h-11 flex items-center justify-center ml-2 bg-primary500 text-white py-2.5 rounded-md hover:bg-primary600 dark:bg-primary400 rtl:mr-2 rtl:ml-0"
            aria-label="Send"
          >
            <FiSend className="w-5 h-5" />
          </button>
        </div>
      </div>

      {selectedMedia && (
        <MediaPreviewModal
          mediaUrl={selectedMedia.url}
          mediaType={selectedMedia.type}
          onClose={() => setSelectedMedia(null)}
        />
      )}
    </div>
  );
}

export default ChatWindow;
