import React, { useState, useEffect, useContext, useRef } from "react";
import { Paper, List } from '@material-ui/core';

import "./PlayerList.css";
import { PlayerColor } from './PlayerColor.js';
import { MediaAgent, MediaControl } from "./MediaControl.js";

import { GlobalContext } from "./GlobalContext.js";

const PlayerList = () => {
  const { ws, name } = useContext(GlobalContext);
  const [players, setPlayers] = useState({});
  const [unselected, setUneslected] = useState([]);
  const [state, setState] = useState('lobby');
  const [color, setColor] = useState(undefined);
  const [peers, setPeers] = useState({});

  const onWsMessage = (event) => {
    const data = JSON.parse(event.data);
    switch (data.type) {
    case 'game-update':
      console.log(`player-list - game update`, data.update);
     
      if ('unselected' in data.update) {
        setUneslected(data.update.unselected);
      }

      if ('players' in data.update) {
        let found = false;
        for (let key in data.update.players) {
          if (data.update.players[key].name === name) {
            found = true;
            setColor(key);
            break;
          }
        }
        if (!found) {
          setColor(undefined);
        }
        setPlayers(data.update.players);
      }
      
      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 => 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: [ 'state', 'players', 'unselected' ]
    }));
  }, [ws]);

  const toggleSelected = (key) => {
    ws.send(JSON.stringify({ 
      type: 'set', 
      field: 'color',
      value: color === key ? "" : key
    }));
  }

  const playerElements = [];

  const inLobby = state === 'lobby';
  const sortedPlayers = [];

  for (let key in players) {
    sortedPlayers.push(players[key]);
  }

  const sortPlayers = (A, B) => {
    /* active player first */
    if (A.name === name) {
      return -1;
    }
    if (B.name === name) {
      return +1;
    }
    
    /* Sort active players first */
    if (A.name && !B.name) {
      return -1;
    }
    if (B.name && !A.name) {
      return +1;
    }

    /* Ohterwise, sort by color */
    return A.color.localeCompare(B.color);
  };

  sortedPlayers.sort(sortPlayers);

  /* Array of just names... */
  unselected.sort((A, B) => {
    /* active player first */
    if (A === name) {
      return -1;
    }
    if (B === name) {
      return +1;
    }
    /* Then sort alphabetically */
    return A.localeCompare(B);
  });

  const videoClass = sortedPlayers.length <= 2 ? 'Medium' : 'Small';
  
  sortedPlayers.forEach(player => {
    const name = player.name;
    const selectable = inLobby && (player.status === 'Not active' || color === player.color);
    playerElements.push(
      <div
        data-selectable={selectable}
        data-selected={player.color === color}
        className="PlayerEntry"
        onClick={() => { inLobby && selectable && toggleSelected(player.color) }} 
        key={`player-${player.color}`}>
        <div>
          <PlayerColor color={player.color}/>
          <div className="Name">{name ? name : 'Available' }</div>
        { name && !player.live && <div className="NoNetwork"></div> }
        </div>
        { name && player.live && <MediaControl className={videoClass} peer={peers[name]} 
          isSelf={player.color === color}/> }
        { !name && <div></div> }
      </div>
    );
  });

  const waiting = unselected.map((player) => {
    return <div className={player === name ? 'Self' : ''} key={player}>
      <div>{ player }</div>
      <MediaControl className={'Small'} peer={peers[player]} isSelf={name === player}/>
    </div>
  });

  return (
    <Paper className={`PlayerList ${videoClass}`}>
      <MediaAgent setPeers={setPeers}/>
      <List className="PlayerSelector">
        { playerElements }
      </List>
      { unselected && unselected.length !== 0 && <div className="Unselected">
        <div>In lobby</div>
        <div>
          { waiting }
        </div>
      </div> }
    </Paper>
  );
}

export { PlayerList };
