"use client";
import { useState, useEffect, useCallback, useRef, useContext } from "react";
import useWebSocket, { ReadyState } from "react-use-websocket";
import MessageDispatcher from "./message";
import { Token } from "@/lib/types";
import dayjs from "dayjs";
import { DanmuContext } from "./provider";

const MOMO_IM_URL = "wss://live-ws.immomo.com/ws/im";

const useGenMessage = () => {
  const [msgId, setMsgId] = useState(3);
  return {
    genMessage(text: string) {
      const msg = {
        msg_id: msgId,
        client_time: Date.now(),
        type: "Bili",
        data: { text },
      };
      setMsgId(msgId + 1);
      return msg;
    },
  };
};

export default function Danmu({ token }: { token: Token }) {
  const [messageHistory, setMessageHistory] = useState<MessageEvent<any>[]>([]);
  const ref = useRef<HTMLDivElement>(null);
  const { liveId, dispatch } = useContext(DanmuContext);
  const { genMessage } = useGenMessage();

  const { sendMessage, lastMessage, readyState } = useWebSocket(MOMO_IM_URL, {
    heartbeat: {
      message: () => {
        const pingMessage = {
          msg_id: 2,
          client_time: Date.now(),
          type: "Ping",
          data: {},
        };
        return JSON.stringify(pingMessage);
      },
      interval: 5000,
    },
  });

  const momoId = token.uid;
  const roomId = liveId;
  const momoToken = token.token;

  useEffect(() => {
    if (ReadyState.OPEN === readyState) {
      const clientTime = Date.now();
      const data = {
        msg_id: 1,
        client_time: clientTime,
        type: "Sauth",
        data: {
          momoid: momoId,
          roomid: roomId,
          role: 6,
          isVisitor: false,
          token: momoToken,
        },
      };
      if (roomId) {
        sendMessage(JSON.stringify(data));
        console.log("重新连接...");
        setMessageHistory([]);
        dispatch({
          type: "listener",
          payload: {
            listener: (msg: string) => {
              const data = genMessage(msg);
              sendMessage(JSON.stringify(data));
            },
          },
        });
      }
    }
  }, [readyState, roomId, momoId, momoToken]);

  useEffect(() => {
    if (lastMessage !== null) {
      if (lastMessage.data) {
        const current = dayjs().format("HH:mm:ss");
        const message = JSON.parse(lastMessage.data);
        if (message.type === "pong") {
          return;
        }
        if (message.type === "group") {
          message.groups.forEach((group: any) => {
            group.current = current;
            setMessageHistory((prev) => prev.concat(group));
            setTimeout(() => {
              if (ref.current) {
                ref.current.scrollTop = ref.current.scrollHeight;
              }
            }, 0);
          });
        } else {
          message.current = current;
          setMessageHistory((prev) => prev.concat(message));
          setTimeout(() => {
            if (ref.current) {
              ref.current.scrollTop = ref.current.scrollHeight;
            }
          }, 0);
        }
      }
    }
  }, [lastMessage]);

  return (
    <div className="h-[60vh] md:h-[40vh] overflow-auto" ref={ref}>
      {messageHistory.map((message, idx) => (
        <MessageDispatcher key={idx} message={message} />
      ))}
    </div>
  );
}
