package cz.jzitnik.events.handlers;

import com.googlecode.lanterna.TextColor;
import com.googlecode.lanterna.graphics.TextGraphics;
import cz.jzitnik.annotations.EventHandler;
import cz.jzitnik.annotations.injectors.InjectState;
import cz.jzitnik.events.RerenderScreen;
import cz.jzitnik.game.Constants;
import cz.jzitnik.states.ScreenBuffer;
import cz.jzitnik.states.TerminalState;
import cz.jzitnik.ui.pixels.Empty;
import cz.jzitnik.ui.pixels.Pixel;
import cz.jzitnik.utils.DependencyManager;
import cz.jzitnik.utils.events.AbstractEventHandler;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;

@Slf4j
@EventHandler(RerenderScreen.class)
public class CliHandler extends AbstractEventHandler<RerenderScreen> {
    @InjectState
    private TerminalState terminalState;

    @InjectState
    private ScreenBuffer screenBuffer;

    public CliHandler(DependencyManager dm) {
        super(dm);
    }

    @Override
    public void handle(RerenderScreen event) {
        var parts = event.parts();
        var buffer = screenBuffer.getRenderedBuffer();
        var terminalScreen = terminalState.getTerminalScreen();
        var tg = terminalState.getTextGraphics();

        for (RerenderScreen.ScreenPart part : parts) {
            var start = part.getStart();
            int startYNormalized = (start.getRow() / 2) * 2; // Round to multiple of 2 down
            var end = part.getEnd();
            int endYNormalized = ((end.getRow() - 1) / 2) * 2; // Round to multiple of 2 ceil

            for (int y = startYNormalized; y <= endYNormalized; y += 2) {
                for (int x = start.getColumn(); x <= end.getColumn(); x++) {
                    Pixel topPixel = buffer[y][x];
                    Pixel bottomPixel = (y + 1 <= end.getRow())
                            ? buffer[y + 1][x]
                            : new Empty();

                    TextColor topColor = topPixel instanceof Empty
                            ? Constants.DEFAULT_COLOR
                            : topPixel.getColor();

                    TextColor bottomColor = bottomPixel instanceof Empty
                            ? Constants.DEFAULT_COLOR
                            : bottomPixel.getColor();

                    drawHalfPixel(tg, x, y / 2, topColor, bottomColor);
                }
            }
        }

        try {
            terminalScreen.refresh();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private void drawHalfPixel(TextGraphics tg, int x, int y,
                               TextColor topColor,
                               TextColor bottomColor) {
        tg.setBackgroundColor(topColor);     // upper half
        tg.setForegroundColor(bottomColor);  // lower half
        tg.setCharacter(x, y, '▄');
    }
}
