package cz.jzitnik.utils;

import com.googlecode.lanterna.TerminalPosition;
import cz.jzitnik.annotations.Dependency;
import cz.jzitnik.annotations.injectors.InjectState;
import cz.jzitnik.events.MouseAction;
import cz.jzitnik.events.RerenderScreen;
import cz.jzitnik.game.GameRoom;
import cz.jzitnik.game.GameState;
import cz.jzitnik.game.objects.UIClickHandler;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Dependency
public class UIClickHandlerRepository {
    @InjectState
    private GameState gameState;

    private final Map<GameRoom, Map<RerenderScreen.ScreenPart, UIClickHandler>> roomSpecificHandlers = new ConcurrentHashMap<>();

    public int registerCurrentRoomHandler(RerenderScreen.ScreenPart screenPart, UIClickHandler uiClickHandler) {
        GameRoom currentRoom = gameState.getCurrentRoom();
        return registerRoomSpecificHandler(currentRoom, screenPart, uiClickHandler);
    }

    public int registerRoomSpecificHandler(GameRoom gameRoom, RerenderScreen.ScreenPart screenPart, UIClickHandler uiClickHandler) {
        if (!roomSpecificHandlers.containsKey(gameRoom)) {
            roomSpecificHandlers.put(gameRoom, new ConcurrentHashMap<>());
        }

        roomSpecificHandlers.get(gameRoom).put(screenPart, uiClickHandler);

        return screenPart.hashCode();
    }

    public void handleClick(MouseAction mouseAction) {
        if (!roomSpecificHandlers.containsKey(gameState.getCurrentRoom())) {
            return;
        }

        Map<RerenderScreen.ScreenPart, UIClickHandler> handlers = roomSpecificHandlers.get(gameState.getCurrentRoom());

        for (var entry : handlers.entrySet()) {
            RerenderScreen.ScreenPart part = entry.getKey();
            UIClickHandler uiClickHandler = entry.getValue();
            TerminalPosition position = new TerminalPosition(mouseAction.getPosition().getColumn(), mouseAction.getPosition().getRow() * 2);

            if (part.isWithin(position)) {
                uiClickHandler.handleClick(mouseAction);
                return;
            }
        }
    }

    public void removeHandlerForCurrentRoom(int screenPartHashCode, UIClickHandler uiClickHandler) {
        GameRoom currentRoom = gameState.getCurrentRoom();
        if (!roomSpecificHandlers.containsKey(currentRoom)) return;
        Map<RerenderScreen.ScreenPart, UIClickHandler> handlers = roomSpecificHandlers.get(currentRoom);

        for (var key: handlers.keySet()) {
            if (key.hashCode() == screenPartHashCode) {
                handlers.remove(key, uiClickHandler);
            }
        }
    }
}
