import * as Automerge from "@automerge/automerge";
import { useContext, useState } from "react";
import useWebSocket from "react-use-websocket";
import { wsUrl } from "./constants";
import CBOR from "cbor";
import { RoomContext } from "./lib/roomContext";

export default function Grub() {
  const { roomId, clientId } = useContext(RoomContext);
  const [doc, setDoc] = useState(Automerge.init());
  const [syncState, setSyncState] = useState(Automerge.initSyncState());
  const [addItemName, setAddItemName] = useState("");

  function updateDoc(newDoc) {
    setDoc(newDoc);
  }

  const { sendMessage } = useWebSocket(wsUrl, {
    share: true,
    onOpen: ({}) => {
      console.log("Shiet, connected.");
    },
    onMessage: async (event) => {
      const data = CBOR.decode(await event.data.arrayBuffer());

      if (data.type === "Automerge") {
        const [nextDoc, nextSyncState, patch] = Automerge.receiveSyncMessage(
          doc,
          syncState,
          data.message[1]
        );
        setDoc(nextDoc);
        setSyncState(nextSyncState);
        console.log("patch", patch);
      }
    },
  });

  function sendCborMessage(data) {
    let cbor = CBOR.encode(data);
    sendMessage(cbor);
  }

  function addItem(e) {
    e.preventDefault();
    const newDoc = Automerge.change(doc, (doc) => {
      if (!doc.items) doc.items = [];
      doc.items.push({
        id: uuid.v4(),
        content: addItemName,
      });
    });
    updateDoc(newDoc);
    const [syncMessage, binary] = Automerge.generateSyncMessage(doc, syncState);
    if (syncMessage)
      sendCborMessage({
        type: "Automerge",
        client_id: clientId,
        room_id: roomId,
        message: binary,
      });
    setAddItemName("");
  }

  const items = doc.items || [];

  return (
    <>
      Grubs:
      <ul>
        {items.map((x) => (
          <li key={x.id}>{x.content}</li>
        ))}
      </ul>
      <form onSubmit={addItem}>
        <input
          type="text"
          value={addItemName}
          onChange={(e) => setAddItemName(e.target.value)}
          placeholder="Type a message..."
        />
        <button type="submit">add item</button>
      </form>
    </>
  );
}
