package cz.jzitnik.game.logic.services.farmland;

import cz.jzitnik.game.Game;
import cz.jzitnik.game.annotations.CustomLogic;
import cz.jzitnik.game.annotations.Farmable;
import cz.jzitnik.game.entities.items.ItemBlockSupplier;
import cz.jzitnik.game.logic.CustomLogicInterface;
import cz.jzitnik.game.sprites.Farmland.FarmlandState;
import cz.jzitnik.tui.ScreenRenderer;

@CustomLogic
public class FarmlandLogic implements CustomLogicInterface {
    private static final int RADIUS = 50;
    private static final int WATER_DISTANCE = 4;
    private static final int DRY_TO_DIRT_THRESHOLD = 11;
    private static final int AGE_THRESHOLD = 5;

    @Override
    public void nextIteration(Game game, ScreenRenderer ignored) {
        int[] data = game.getPlayerCords();
        var world = game.getWorld();
        int playerX = data[0];
        int playerY = data[1];

        int startX = Math.max(0, playerX - RADIUS);
        int startY = Math.max(0, playerY - RADIUS);
        int endX = Math.min(world[0].length - 1, playerX + RADIUS);
        int endY = Math.min(world.length - 1, playerY + RADIUS);

        for (int x = startX; x <= endX; x++) {
            for (int y = startY; y <= endY; y++) {
                var blocks = world[y][x];
                var farmlandOptional = blocks.stream()
                        .filter(block -> block.getBlockId().equals("farmland"))
                        .findFirst();

                if (farmlandOptional.isEmpty()) continue;

                var farmland = farmlandOptional.get();
                var farmlandData = (FarmlandData) farmland.getData();

                boolean waterNearby = false;

                for (int dx = -WATER_DISTANCE; dx <= WATER_DISTANCE && !waterNearby; dx++) {
                    for (int dy = -WATER_DISTANCE; dy <= WATER_DISTANCE && !waterNearby; dy++) {
                        int checkX = x + dx;
                        int checkY = y + dy;

                        if (checkX < 0 || checkX >= world[0].length || checkY < 0 || checkY >= world.length) continue;

                        var nearbyBlocks = world[checkY][checkX];
                        if (nearbyBlocks.stream().anyMatch(b -> b.getBlockId().equals("water"))) {
                            waterNearby = true;
                        }
                    }
                }

                if (farmlandData.isWatered() != waterNearby) {
                    farmlandData.setAge(farmlandData.getAge() + 1);
                    if (farmlandData.getAge() >= AGE_THRESHOLD) {
                        farmlandData.setWatered(waterNearby);
                        farmland.setSpriteState(waterNearby ? FarmlandState.WET : FarmlandState.NORMAL);
                        farmlandData.setAge(0);
                    }
                } else {
                    farmlandData.setAge(0);
                }

                if (!farmlandData.isWatered()) {
                    farmlandData.setDryAge(farmlandData.getDryAge() + 1);
                    if (farmlandData.getDryAge() >= DRY_TO_DIRT_THRESHOLD) {
                        blocks.remove(farmland);
                        blocks.add(ItemBlockSupplier.getBlock("dirt"));

                        world[y-1][x].removeIf(block -> block.getClass().isAnnotationPresent(Farmable.class));
                        farmlandData.setDryAge(0);
                    }
                } else {
                    farmlandData.setDryAge(0);
                }
            }
        }
    }
}
