import React, { useState, useCallback, useEffect, useMemo, useRef, useContext } from "react";
import equal from "fast-deep-equal";

import Paper from "@mui/material/Paper";
import Button from "@mui/material/Button";
import "./ChooseCard.css";
import { Resource } from "./Resource";
import { GlobalContext } from "./GlobalContext";

/* eslint-disable @typescript-eslint/no-explicit-any */

/* eslint-disable @typescript-eslint/no-explicit-any */

const ChooseCard: React.FC = () => {
  const { ws, sendJsonMessage } = useContext(GlobalContext);
  const [turn, setTurn] = useState<any>(undefined);
  const [color, setColor] = useState<string | undefined>(undefined);
  const [state, setState] = useState<string | undefined>(undefined);
  const [cards, setCards] = useState<string[]>([]);
  const fields = useMemo(() => ["turn", "color", "state"], []);

  const onWsMessage = (event: MessageEvent) => {
    const data = JSON.parse(event.data);
    switch (data.type) {
      case "game-update":
        console.log(`choose-card - game-update: `, data.update);
        if ("turn" in data.update && !equal(turn, data.update.turn)) {
          setTurn(data.update.turn);
        }
        if ("color" in data.update && data.update.color !== color) {
          setColor(data.update.color);
        }
        if ("state" in data.update && data.update.state !== state) {
          setState(data.update.state);
        }
        break;
      default:
        break;
    }
  };
  const refWsMessage = useRef(onWsMessage);
  useEffect(() => {
    refWsMessage.current = onWsMessage;
  });
  useEffect(() => {
    if (!ws) {
      return;
    }
    const cbMessage = (e: MessageEvent) => refWsMessage.current(e);
    ws.addEventListener("message", cbMessage);
    return () => {
      ws.removeEventListener("message", cbMessage);
    };
  }, [ws, refWsMessage]);
  useEffect(() => {
    if (!sendJsonMessage) {
      return;
    }
    sendJsonMessage({
      type: "get",
      fields,
    });
  }, [sendJsonMessage, fields]);

  const selectResources = useCallback(() => {
    if (!sendJsonMessage) return;
    sendJsonMessage({
      type: "select-resources",
      cards,
    });
  }, [sendJsonMessage, cards]);

  let count = 0;
  if (turn && turn.actions && turn.actions.indexOf("select-resources") !== -1) {
    if (turn.active) {
      if (turn.color === color) {
        count = turn.active === "monopoly" ? 1 : 2;
      }
    }

    if (state === "volcano") {
      if (!turn.select) {
        count = 0;
      } else if (color && color in turn.select) {
        count = turn.select[color];
      } else {
        count = 0;
      }
    }
  }

  const selectCard = useCallback(() => {
    const selected = document.querySelectorAll(".ChooseCard .Selected");
    if (selected.length > count) {
      for (let i = 0; i < selected.length; i++) {
        selected[i].classList.remove("Selected");
      }
      setCards([]);
      return;
    }

    const tmp: string[] = [];
    for (let i = 0; i < selected.length; i++) {
      const type = selected[i].getAttribute("data-type");
      if (type) tmp.push(type);
    }
    setCards(tmp);
  }, [setCards, count]);

  if (count === 0) {
    return <></>;
  }

  const resources = ["wheat", "brick", "stone", "sheep", "wood"].map((type) => {
    return <Resource key={type} type={type} count={count} onClick={selectCard} />;
  });

  let title: React.ReactElement;
  switch (turn.active) {
    case "monopoly":
      title = (
        <>
          <b>Monopoly</b>! Tap the resource type you want everyone to give you!
        </>
      );
      break;
    case "year-of-plenty":
      title = (
        <>
          <b>Year of Plenty</b>! Tap the two resources you want to receive from the bank!
        </>
      );
      break;
    case "volcano":
      title = (
        <>
          <b>Volcano has minerals</b>! Tap the {count} resources you want to receive from the bank!
        </>
      );
      break;
    default:
      title = <>Unknown card type {turn.active}.</>;
      break;
  }

  return (
    <div className="ChooseCard">
      <Paper>
        <div className="Title">{title}</div>
        <div style={{ display: "flex", flexDirection: "row", justifyContent: "center" }}>{resources}</div>
        <div className="Actions">
          <Button disabled={cards.length !== count} onClick={selectResources}>
            submit
          </Button>
        </div>
      </Paper>
    </div>
  );
};

export { ChooseCard };
