import React, { useState } from 'react';
import './App.css';
import 'semantic-ui-css/semantic.min.css';
import socketIOClient from 'socket.io-client';
import { ILoginMessage, IJankenResult, IJankenSelect } from './model/messages';

import { Button } from 'semantic-ui-react';

import { Janken } from './component/janken/Janken';
import { Stage } from './component/stage/Stage';

function App(): JSX.Element {

  const [socket, setSocket] = useState<SocketIOClient.Socket | null>(null);
  const [stages, setStages] = useState<string[]>([]);
  const [currentUser, setCurrentUser] = useState<string>('');
  const [currentPlayers, setCurrentPlayers] = useState<ILoginMessage>({playerOne:'', playerTwo:''});
  const [currentIndex, setCurrentIndex] = useState<number>(0);
  const [jankenResult, setJankenResult] = useState<IJankenResult | null>(null);

  const join = (): void => {
    const wsUrl: string | undefined = process.env.REACT_APP_WEBSOCKET;
    if (wsUrl){
      const sock: SocketIOClient.Socket = socketIOClient(wsUrl);
      sock.on('connect', () => {
        if (sock.connected) {
          console.log('接続！');
        } else if (sock.disconnected) {
          setSocket(null);
          setStages([]);
          setCurrentUser('');
          setCurrentPlayers({playerOne:'', playerTwo:''});
          setCurrentIndex(0);
          setJankenResult(null);
        } else {
          console.log('しらんがな', sock);
        }
      });
      sock.on('login', (data: ILoginMessage) => {
        console.log('login', data);
        setCurrentPlayers(data);
      });
      sock.on('registerUser', (data: string) => {
        console.log(data);
        setCurrentUser(data);
      });
      sock.on('jankenResult', (data: IJankenResult) => {
        setJankenResult(data);
      });
      sock.on('againGame', () => {
        setJankenResult(null);
      });
      sock.on('stages', (data: string[]) => {
        setStages(data);
        setCurrentIndex(0);
      });
      sock.on('updateIndex', (data: number) => {
        setCurrentIndex(data);
      });
      sock.on('exitGame', () => {
        setSocket(null);
        setStages([]);
        setCurrentUser('');
        setCurrentPlayers({playerOne:'', playerTwo:''});
        setCurrentIndex(0);
        setJankenResult(null);
      });
      setSocket(sock);
    }
  }
  const janken = (option: string, room: string): void => {
    if (socket && currentUser) {
      const message: IJankenSelect = {
        userName: currentUser,
        room,
        option
      };
      socket.emit('janken', message);
    }
  };
  const moveToStage = (): void => {
    if (socket) {
      socket.emit('moveToStage');
    }
  };
  const registerUser = (username: string, room: string): void => {
    if (socket) {
      socket.emit('registerUser', { username, room });
    }
  };
  const previousIndex = (): void => {
    if (socket && currentIndex > 0) {
      socket.emit('previousIndex');
    }
  };
  const nextIndex = (): void => {
    if (socket && currentIndex < stages.length) {
      socket.emit('nextIndex');
    }
  };
  const againGame = (room: string): void => {
    if (socket) {
      socket.emit('againGame', room);
    }
  };
  const exitGame = (): void => {
    if (socket) {
      socket.emit('exitGame');
    }
  };
  const render = (): JSX.Element => {
    if (socket === null) {
      return (
        <div className="EnterButton">
          <Button
            color='pink'
            size='large'
            onClick={join}
          >
            JOIN
          </Button>
        </div>
      );
    } else {
      if (stages.length === 0) {
        return (
          <Janken
            currentUser={currentUser}
            currentPlayers={currentPlayers}
            jankenResults={jankenResult}
            janken={janken}
            onSubmit={registerUser}
            moveToStage={moveToStage}
            againGame={againGame}
          />
        );
      } else {
        return (
          <Stage
            stages={stages}
            currentIndex={currentIndex}
            previousIndex={previousIndex}
            nextIndex={nextIndex}
            exitGame={exitGame}
            />
        );
      }
    }

  };
  return (
    <div className="App">
      {render()}
      <div className="HiddenExit">
          <Button
            color='pink'
            size='large'
            onClick={exitGame}
          >
            exit
          </Button>
      </div>
    </div>
  );

}

export default App;
