import { useEffect, useState } from "react";
import { useWebSocketContext } from "../contexts/useWebSocketContext";
import type { Channel } from "phoenix";

export const ClusterStatus = () => {
  const { socket, isConnected } = useWebSocketContext();
  const [channelStatus, setChannelStatus] = useState<string>("waiting");
  const [channel, setChannel] = useState<Channel | undefined>();
  const [clusterStatus, setClusterStatus] = useState<
    { otherNodes: string[]; connectedNode: string } | undefined
  >();

  useEffect(() => {
    if (!socket || !isConnected) {
      return;
    }

    const channelName = "cluster_status";
    console.log(`Joining channel: ${channelName}`);
    const newChannel = socket.channel(channelName, {});

    newChannel
      .join()
      .receive("ok", () => {
        setChannelStatus("connected");
        setChannel(newChannel);
        newChannel.push("get_nodes", {});
      })
      .receive("error", (resp: unknown) => {
        console.log(`Failed to join channel ${channelName}:`, resp);
        setChannelStatus("join failed");
      })
      .receive("timeout", () => {
        setChannelStatus("timeout");
      });

    newChannel.on(
      "node_list",
      (payload: { other_nodes: string[]; connected_node: string }) => {
        console.log("Received node list:", payload.other_nodes);
        setClusterStatus({
          otherNodes: payload.other_nodes,
          connectedNode: payload.connected_node,
        });
      },
    );

    return () => {
      console.log(`Leaving channel: ${channelName}`);
      newChannel.leave();
      setChannel(undefined);
      setChannelStatus("waiting");
    };
  }, [socket, isConnected]);

  const allNodes = clusterStatus
    ? [...clusterStatus.otherNodes, clusterStatus.connectedNode].sort()
    : [];

  return (
    <div>
      <div>ClusterStatus</div>
      <div>Channel: {channelStatus}</div>
      <div>
        {allNodes.length === 0 ? (
          <span className="text-navy-300">No nodes available</span>
        ) : (
          <>
            {allNodes.map((node) => {
              const isConnected = node === clusterStatus?.connectedNode;
              return (
                <div
                  key={node}
                  className={
                    isConnected
                      ? "text-navy-100 font-semibold"
                      : "text-navy-400"
                  }
                >
                  {node}
                  {isConnected && (
                    <span className="ml-2 text-xs text-navy-300">(you)</span>
                  )}
                  <button
                    onClick={() => {
                      channel?.push("kill_node", { node });
                    }}
                  >
                    kill
                  </button>
                </div>
              );
            })}
          </>
        )}
      </div>
    </div>
  );
};
