package eu.jonahbauer.wizard.server.machine.states;

import eu.jonahbauer.wizard.common.messages.client.ClientMessage;
import eu.jonahbauer.wizard.common.messages.client.InteractionMessage;
import eu.jonahbauer.wizard.common.messages.client.LeaveSessionMessage;
import eu.jonahbauer.wizard.common.messages.client.ReadyMessage;
import eu.jonahbauer.wizard.server.Lobby;
import eu.jonahbauer.wizard.server.machine.ClientState;
import eu.jonahbauer.wizard.server.machine.Player;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.springframework.web.socket.CloseStatus;

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

@Getter
@RequiredArgsConstructor
public class SessionState implements ClientState {
    private final UUID session;
    private final UUID self;
    private final String name;
    private boolean ready;

    @Override
    public Optional<ClientState> onOpen(Player player) {
        throw new IllegalStateException();
    }

    @Override
    public Optional<ClientState> onMessage(Player player, ClientMessage message) {
        if (message instanceof ReadyMessage ready) {
            Lobby.getInstance().getSession(session).ready(self, ready.isReady());
            this.ready = ready.isReady();
            return Optional.empty();
        } else if (message instanceof LeaveSessionMessage) {
            Lobby.getInstance().getSession(session).leave(self);
            return Optional.of(new LobbyState());
        } else if (message instanceof InteractionMessage interactionMessage) {
            var playerMessage = interactionMessage.getPlayerMessage();
            Lobby.getInstance().getSession(session).handlePlayerMessage(self, playerMessage);
            return Optional.empty();
        } else {
            return ClientState.super.onMessage(player, message);
        }
    }

    @Override
    public Optional<ClientState> onClose(Player player, CloseStatus status) {
        Lobby.getInstance().getSession(session).leave(self);
        return Optional.of(new Closed());
    }

    @Override
    public void onExit(Player context) {
        var session = Lobby.getInstance().getSession(this.session);
        if (session != null) session.leave(self);
    }
}
