import React, { useState, useEffect, useContext, useRef, useMemo, useCallback } from "react";
import Paper from '@mui/material/Paper';
import Button from '@mui/material/Button';
import equal from "fast-deep-equal";

import "./Actions.css";
import { PersonName } from './PersonName';
import { GlobalContext } from "./GlobalContext";

const Actions = () => {
  const { ws, chatId, name } = useContext(GlobalContext);
  const [state, setState] = useState('lobby');
  const [color, setColor] = useState(undefined);
  const [priv, setPriv] = useState(undefined);
  const [turn, setTurn] = useState({});
  const [edit, setEdit] = useState(name);
  const [active, setActive] = useState(0);
  const [persons, setPersons] = useState<any>({});
  const [alive, setAlive] = useState(0);

  const fields = useMemo(() => [
    'state', 'turn', 'private', 'active', 'color', 'persons'
  ], []);

  const onWsMessage = (event: any) => {
    const data = JSON.parse(event.data);
    switch (data.type) {
    case 'game-update':
      console.log(`actions - game update`, data.update);
      if ('private' in data.update && !equal(data.update.private, priv)) {
        setPriv(data.update.private);
      }
      if ('state' in data.update && data.update.state !== state) {
        setState(data.update.state);
      }
      if ('color' in data.update && data.update.color !== color) {
        setColor(data.update.color);
      }
      if ('name' in data.update && data.update.name !== edit) {
        setEdit(data.update.name);
      }
      if ('turn' in data.update && !equal(data.update.turn, turn)) {
        setTurn(data.update.turn);
      }
      if ('active' in data.update && data.update.active !== active) {
        setActive(data.update.active);
      }

      if ('persons' in data.update && !equal(data.update.persons, persons)) {
        setPersons(data.update.persons);
      }
      break;
    default:
      break;
    }
  };
  const refWsMessage = useRef(onWsMessage);
  useEffect(() => { refWsMessage.current = onWsMessage; });
  useEffect(() => {
    if (!ws) { return; }
    const cbMessage = (e: any) => refWsMessage.current(e);
    ws.addEventListener('message', cbMessage);
    return () => {
      ws.removeEventListener('message', cbMessage);
    }
  }, [ws, refWsMessage]);
  useEffect(() => {
    if (!ws) { return; }
    ws.send(JSON.stringify({ 
      type: 'get', 
      fields
    }));
  }, [ws, fields]);

  const sendMessage = useCallback((data: any) => {
    if (!ws) {
      console.warn(`No socket`);
    } else {
      ws.send(JSON.stringify(data));
    }
  }, [ws]);

  useEffect(() => {
    let count = 0;
    for (let key in persons) {
      if (persons[key].live) {
        count++;
      }
    }
    setAlive(count);
  }, [persons, setAlive]);

  const setName = (update: any) => {
    if (update !== name) {
      sendMessage({ type: 'player-name', name: update });
    }
    setEdit(name);
  }

  const changeNameClick = () => {
    setEdit("");
  }

  if (!chatId) {
    return (<Paper className="Actions"/>);
  }

  return (
    <Paper className="Actions">
      { edit === "" && <PersonName name={name} setName={setName}/> }
    </Paper>
  );
}

export { Actions };

