import React from "react";
import { JsonView, darkStyles } from "react-json-view-lite";
import "react-json-view-lite/dist/index.css";
import { WsApi, type WsMessage } from "../api/WsApi";
import { useSnackbar } from "../hooks/contexts_provider/SnackbarProvider";
import { time } from "../utils/DateUtils";
import { useUserInfo } from "../widgets/dashboard/BaseAuthenticatedPage";
import { MatrixGWRouteContainer } from "../widgets/MatrixGWRouteContainer";
import { NotLinkedAccountMessage } from "../widgets/NotLinkedAccountMessage";

const State = {
  Closed: "Closed",
  Connected: "Connected",
  Error: "Error",
} as const;

type TimestampedMessages = WsMessage & { time: number };

export function WSDebugRoute(): React.ReactElement {
  const user = useUserInfo();
  if (!user.info.matrix_account_connected) return <NotLinkedAccountMessage />;

  const snackbar = useSnackbar();

  const [state, setState] = React.useState<string>(State.Closed);
  const wsRef = React.useRef<WebSocket | undefined>(undefined);

  const [messages, setMessages] = React.useState<TimestampedMessages[]>([]);

  React.useEffect(() => {
    const ws = new WebSocket(WsApi.WsURL);
    wsRef.current = ws;

    ws.onopen = () => setState(State.Connected);
    ws.onerror = (e) => {
      console.error(`WS Debug error!`, e);
      snackbar(`WebSocket error! ${e}`);
      setState(State.Error);
    };
    ws.onclose = () => {
      setState(State.Closed);
      wsRef.current = undefined;
    };

    ws.onmessage = (msg) => {
      const dec = JSON.parse(msg.data);
      setMessages((l) => {
        return [{ time: time(), ...dec }, ...l];
      });
    };

    return () => ws.close();
  }, []);

  return (
    <MatrixGWRouteContainer label={"WebSocket Debug"}>
      <div>
        State:{" "}
        <span style={{ color: state == State.Connected ? "green" : "red" }}>
          {state}
        </span>
      </div>
      {messages.map((msg, id) => (
        <div style={{ margin: "10px", backgroundColor: "black" }}>
          <JsonView
            key={id}
            data={msg}
            shouldExpandNode={(level) => level < 2}
            style={{
              ...darkStyles,
              container: "",
            }}
          />
        </div>
      ))}
    </MatrixGWRouteContainer>
  );
}
