package eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris.game;

import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import eu.mhsl.minenet.minigames.util.BatchUtil;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.instance.batch.AbsoluteBlockBatch;
import net.minestom.server.instance.block.Block;

public class Playfield {
    private final Pos lowerLeftCorner;
    private final StatelessGame instance;

    public Playfield(Pos lowerLeftCorner, StatelessGame instance) {
        this.lowerLeftCorner = lowerLeftCorner;
        this.instance = instance;
    }

    public Pos getPlayerSpawnPosition() {
        return this.lowerLeftCorner.add(6, 8, 15);
    }

    public Pos getTetrominoSpawnPosition() {
        return this.lowerLeftCorner.add(5, 21, 1);
    }

    public void generate() {
        AbsoluteBlockBatch batch = new AbsoluteBlockBatch();

        for(int x=0; x<12; x++) {
            for(int y=0; y<21; y++) {
                batch.setBlock(this.lowerLeftCorner.add(x, y, 0), Block.STONE);

                if(x==0 || x==11 || y==0) {
                    batch.setBlock(this.lowerLeftCorner.add(x, y, 1), Block.GRAY_CONCRETE);
                }
            }
        }

        batch.setBlock(getPlayerSpawnPosition().sub(0, 1, 0), Block.STONE);

        BatchUtil.loadAndApplyBatch(batch, this.instance, () -> {});
    }

    public int removeFullLines() {
        int removedLinesCounter = 0;
        for(int y=1; y<21; y++) {
            boolean isFullLine = true;
            for(int x=1; x<11; x++) {
                if(this.instance.getBlock(this.lowerLeftCorner.add(x, y, 1)) == Block.AIR) isFullLine = false;
            }
            if(isFullLine) {
                removeFullLine(y);
                removedLinesCounter += 1;
                y -= 1;
            }
        }
        return removedLinesCounter;
    }

    private void removeFullLine(int positionY) {
        for(int y=positionY; y<21; y++) {
            for(int x=1; x<11; x++) {
                Block blockAbove = this.instance.getBlock(this.lowerLeftCorner.add(x, y+1, 1));
                this.instance.setBlock(this.lowerLeftCorner.add(x, y, 1), blockAbove);
            }
        }
    }
}
