const myId = Math.floor(Math.random() * 10000000);
const bucket = "https://storage.googleapis.com/sample-video-watch-together/";

interface MessageT {
  id: number;
  text: string;
}

const App = () => {
  const [movieUrl, setMovieUrl] = React.useState<string>(
    `${bucket}Inside.Out.2015.1080p.BluRay.x264.YIFY.mp4`
  );
  const videoRef = React.useRef<HTMLVideoElement>();
  const [userMedia] = React.useState(() => new UserMedia(320, 240));
  const [conn] = React.useState<WsConn>(() => {
    const conn = new WsConn();
    RegisterVideoHandlers(conn);
    return conn;
  });
  const refCallback = React.useCallback((video: HTMLVideoElement) => {
    video.onplay = conn.EventHandler(() => video.currentTime);
    video.onpause = conn.EventHandler(() => video.currentTime);
    video.onseeking = conn.EventHandler(() => video.currentTime);
    videoRef.current = video;
  }, []);
  const [messages, setMessages] = React.useState<MessageT[]>([]);
  const [clients, setClients] = React.useState<Record<string, Peer>>({});
  const [myName, setMyName] = React.useState<string>("");
  const [serverId, setServerId] = React.useState<string>("");
  const signal = (filter: string, data: Object) => {
    conn.conn.send(
      JSON.stringify({event: "signal", value: {id: serverId, data}, filter})
    );
  };

  const send = (event: React.KeyboardEvent<HTMLInputElement>) => {
    if (event.key != "Enter") return;
    const msg = {text: event.currentTarget.value, id: myId};
    setMessages([...messages, msg]);
    event.currentTarget.value = "";
    conn.conn.send(
      JSON.stringify({event: "message", target: "#app", value: msg})
    );
  };

  const advertise = (name: string, filter: string) => {
    setMyName(name);
    conn.conn.send(
      JSON.stringify({
        event: "advertise",
        value: {id: serverId, name},
        filter,
      })
    );
  };

  React.useEffect(() => {
    const elem = document.getElementById("messages");
    elem.scrollTop = elem.scrollHeight;
  }, [messages]);

  React.useEffect(() => {
    RegisterUiHandlers(
      conn,
      setMessages,
      messages,
      setMovieUrl,
      videoRef,
      myName,
      setServerId,
      clients,
      setClients,
      signal,
      userMedia,
      advertise
    );
  }, [
    conn,
    setMessages,
    messages,
    setMovieUrl,
    videoRef,
    myName,
    setServerId,
    clients,
    setClients,
    signal,
    userMedia,
    advertise,
  ]);

  React.useEffect(() => {
    conn.onclose = () => {
      Object.values(clients).forEach((c) => c?.cleanup());
      setClients({});
    };
  }, [clients]);

  return (
    <>
      <div className="videoPanel">
        <input id="urlInput" value={movieUrl} spellCheck={false} />
        <video
          id="myVideo"
          key={movieUrl}
          src={movieUrl}
          ref={refCallback}
          controls>
          {false && (
            <track
              label="English"
              kind="subtitles"
              srcLang="en"
              src="/movie.vtt"
              default
            />
          )}
        </video>
      </div>
      <div id="chat">
        <div id="updates" className="updates">
          <div className="myProps">
            <input
              className="myName"
              size={5}
              onChange={(ev) => advertise(ev.target.value, "")}
            />
            <span className="myId">({serverId})</span>
          </div>
          {Object.keys(clients).map((id) => (
            <div>
              {clients[id].name} ({id})
            </div>
          ))}
        </div>
        <div className="vcHolder">
          <Video userMedia={userMedia} />
          {Object.keys(clients).map((id) => (
            <div className="video-wrapper">
              <video id={`video-${id}`} autoPlay playsInline />
            </div>
          ))}
        </div>
        <div id="messages" className="messages">
          {messages.map((message) => (
            <div className={message.id == myId ? "right" : "left"}>
              <div
                className="bubble"
                style={{
                  backgroundColor: "#" + ("000000" + message.id).slice(-6),
                }}>
                {message.text}
              </div>
            </div>
          ))}
        </div>
        <input className="inputMsg" onKeyPress={send} />
      </div>
      <div className="fullscreen" onClick={triggerFullscreen}>
        <img src="https://cdn1.iconfinder.com/data/icons/material-core/14/fullscreen-512.png" />
      </div>
    </>
  );
};
