package eu.jonahbauer.wizard.client.libgdx.state;

import eu.jonahbauer.wizard.client.libgdx.Client;
import eu.jonahbauer.wizard.client.libgdx.ClientSocket;
import eu.jonahbauer.wizard.client.libgdx.screens.ConnectScreen;
import eu.jonahbauer.wizard.client.libgdx.screens.InstructionScreen;
import eu.jonahbauer.wizard.client.libgdx.screens.MainMenuScreen;
import eu.jonahbauer.wizard.common.messages.server.ServerMessage;
import lombok.SneakyThrows;
import lombok.extern.log4j.Log4j2;
import org.java_websocket.framing.CloseFrame;

import java.net.URI;
import java.util.Optional;

@Log4j2
public final class Menu extends BaseState {
    
    @Override
    @SneakyThrows
    public Optional<ClientState> onEnter(Client client) {
        if (client.getSocket() != null && client.getSocket().isOpen()) {
            client.getSocket().close(CloseFrame.GOING_AWAY);
        }
        if (!client.isError()) showMenuScreen(client);
        return super.onEnter(client);
    }

    @Override
    public Optional<ClientState> onErrorDismissed(Client client) {
        showMenuScreen(client);
        return Optional.empty();
    }

    @Override
    public Optional<ClientState> onMessage(Client client, ServerMessage message) {
        // it is possible that there are messages still queued after
        // returning to the menu as a result of a previous message
        log.debug("Dropped message {}.", message);
        return Optional.empty();
    }
    
    @Override
    public Optional<ClientState> onClose(Client client, int code, String reason, boolean remote) {
        super.onClose(client, code, reason, remote);
        return Optional.empty();
    }

    public Optional<ClientState> showConnectScreen(Client client) {
        var game = client.getGame();
        game.setScreen(new ConnectScreen(game));
        return Optional.empty();
    }

    public Optional<ClientState> showMenuScreen(Client client) {
        var game = client.getGame();
        game.setScreen(new MainMenuScreen(game));
        return Optional.empty();
    }

    public Optional<ClientState> showInstructionScreen(Client client) {
        var game = client.getGame();
        game.setScreen(new InstructionScreen(game));
        return Optional.empty();
    }

    public Optional<ClientState> connect(Client client, URI uri) {
        ClientSocket socket = new ClientSocket(uri);
        client.setSocket(socket);
        socket.connect();
        return Optional.of(new AwaitingConnection());
    }
}
