/* eslint-disable react-hooks/exhaustive-deps */
/* eslint-disable @typescript-eslint/no-explicit-any */
import { FormEvent, useEffect, useRef, useState } from "react";
import useSocketStore from "../stores/useSocketStore";
import { UIEvent } from "react";
import "./Chat.css";
import ChevronDownIcon from "./icons/ChevronDownIcon";
import CloseIcon from "./icons/CloseIcon";
import useChatStore from "../stores/useChatStore";

interface ChatProps {
  className?: string;
  handleClose: () => void;
}

function Chat({ className, handleClose }: ChatProps) {
  const socket = useSocketStore((state) => state.socket);
  const [message, setMessage] = useState<string>("");
  const [messages, setMessages] = useChatStore((state) => [
    state.messages,
    state.setMessages,
  ]);
  const [isBottom, setIsBottom] = useState<boolean>(true);
  const [isNewMessage, setIsNewMessage] = useState<boolean>(false);
  const inputRef = useRef<HTMLInputElement>(null);
  const messagesEndRef = useRef<HTMLDivElement>(null);

  function sendMessage(e: FormEvent) {
    e.preventDefault();

    if (!socket || !message) return;

    socket.emit("message", socket.id, message);

    setMessage("");
    inputRef.current?.focus();
    messagesEndRef.current?.scrollIntoView();
  }

  const handleScroll = (e: UIEvent<HTMLDivElement>) => {
    if (
      e.currentTarget.scrollHeight - Math.round(e.currentTarget.scrollTop) ===
      e.currentTarget.clientHeight
    ) {
      setIsBottom(true);
      setIsNewMessage(false);
    } else {
      setIsBottom(false);
    }
  };

  useEffect(() => {
    function handleKeyUp(e: KeyboardEvent) {
      if (e.key === "Escape") {
        handleClose();
      }
    }

    document.addEventListener("keyup", handleKeyUp);

    return () => {
      document.removeEventListener("keyup", handleKeyUp);
    };
  }, []);

  useEffect(() => {
    if (!socket) return;

    socket.on("message", (socketId, message) => {
      setMessages([
        ...useChatStore.getState().messages,
        { id: socketId, message },
      ]);
    });

    return () => {
      socket.off("message");
    };
  }, [socket]);

  useEffect(() => {
    if (isBottom) {
      messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
    } else {
      setIsNewMessage(true);
    }
  }, [messages]);

  return (
    <div
      className={[
        "relative p-4 flex flex-col gap-4 w-80 h-screen bg-neutral-900 transition-all",
        className,
      ].join(" ")}
    >
      <div className="border-b pb-3 border-y-neutral-800 flex justify-between">
        <p className="text-2xl font-gilroy">Чат</p>
        <button onClick={handleClose}>
          <CloseIcon />
        </button>
      </div>
      <div
        onScroll={handleScroll}
        className="messages flex flex-col gap-4 overflow-y-auto overflow-x-hidden flex-1 pr-2"
      >
        {messages.map((data, index) => (
          <p key={index} className="break-words">
            <b>{data.city && data.city + ":"}</b> <span>{data.message}</span>
          </p>
        ))}

        <div ref={messagesEndRef}></div>
      </div>

      <div
        onClick={() =>
          messagesEndRef.current?.scrollIntoView({ behavior: "smooth" })
        }
        className={[
          "absolute mr-8 right-0 bottom-[136px] bg-neutral-950 p-2 rounded-full shadow transition-opacity",
          isBottom
            ? "opacity-0 pointer-events-none cursor-auto"
            : "opacity-100 pointer-events-auto cursor-pointer",
        ].join(" ")}
      >
        <ChevronDownIcon className="w-5 h-5" />

        <div
          className={[
            "absolute top-0 right-0 w-3 h-3 flex justify-center items-center rounded-full bg-red-500 shadow transition-opacity",
            isNewMessage ? "opacity-100" : "opacity-0",
          ].join(" ")}
        ></div>
      </div>

      <form onSubmit={sendMessage} className="flex flex-col gap-4">
        <input
          ref={inputRef}
          type="text"
          placeholder="Написать сообщение..."
          autoFocus
          autoComplete="off"
          value={message}
          onChange={(e) => setMessage(e.target.value)}
          className="px-3 py-2 outline-none rounded"
        />
        <button
          type="submit"
          className="p-2 bg-blue-700 hover:bg-blue-800 transition-colors outline-none rounded"
        >
          Отправить
        </button>
      </form>
    </div>
  );
}

export default Chat;
