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

import eu.jonahbauer.wizard.client.libgdx.Client;
import eu.jonahbauer.wizard.client.libgdx.screens.GameScreen;
import eu.jonahbauer.wizard.client.libgdx.screens.WaitingScreen;
import eu.jonahbauer.wizard.common.messages.data.PlayerData;
import eu.jonahbauer.wizard.common.messages.server.*;
import eu.jonahbauer.wizard.common.model.Configuration;
import lombok.Getter;
import lombok.Setter;

import java.util.Optional;
import java.util.UUID;

@Getter
public final class Session extends BaseState {
    
    private SessionJoinedMessage joined;
    private WaitingScreen sessionScreen;
    
    private final UUID self;
    private final String secret;

    private final UUID session;
    private final String sessionName;
    private final Configuration configuration;
    private final String playerName;

    private boolean ready;
    @Setter
    private Boolean nextReady;

    public Session(SessionJoinedMessage joined, String sessionName, Configuration configuration, String playerName) {
        this.self = joined.getPlayer();
        this.secret = joined.getSecret();
        this.session = joined.getSession();
        this.sessionName = sessionName;
        this.configuration = configuration;
        this.joined = joined;
        this.playerName = playerName;
    }

    @Override
    public Optional<ClientState> onEnter(Client client) {
        sessionScreen = new WaitingScreen(client.getGame());
        client.getGame().setScreen(sessionScreen);
        sessionScreen.setPlayers(joined.getPlayers().toArray(new PlayerData[0]));
        sessionScreen.setReady(false);
        sessionScreen.setPlayerName(playerName);
        sessionScreen.setSession(session, sessionName, configuration);
        
        joined = null;
        return super.onEnter(client);
    }

    @Override
    public Optional<ClientState> onMessage(Client client, ServerMessage message) {
        if (message instanceof PlayerJoinedMessage join) {
            sessionScreen.addPlayer(join.getPlayer());
            return Optional.empty();
        } else if (message instanceof PlayerLeftMessage leave) {
            sessionScreen.removePlayer(leave.getPlayer());
            return Optional.empty();
        } else if (message instanceof PlayerModifiedMessage modified) {
            sessionScreen.modifyPlayer(modified.getPlayer());
            return Optional.empty();
        } else if (message instanceof StartingGameMessage) {
            client.getGame().setScreen(new GameScreen(client.getGame()));
            return Optional.empty();
        } else if (nextReady != null && message instanceof NackMessage nack) {
            // TODO display error
            System.out.println("Error: " + nack.getMessage());
            sessionScreen.setReady(!nextReady);
            nextReady = null;
            return Optional.empty();
        } else if (nextReady != null && message instanceof AckMessage) {
            sessionScreen.setReady(nextReady);
            ready = nextReady;
            nextReady = null;
            return Optional.empty();
        } else {
            return unexpectedMessage(client, message);
        }
    }
}
