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

import java.util.Random;

import cz.jzitnik.game.Game;
import cz.jzitnik.game.annotations.CustomLogic;
import cz.jzitnik.game.annotations.FireImmune;
import cz.jzitnik.game.annotations.Flamable;
import cz.jzitnik.game.entities.Block;
import cz.jzitnik.game.entities.items.Item;
import cz.jzitnik.game.logic.CustomLogicInterface;
import cz.jzitnik.tui.ScreenRenderer;

@CustomLogic
public class LavaFireLogic implements CustomLogicInterface {
    private static final int RADIUS = 30;
    private Random random = new Random();

    @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 y = startY; y <= endY; y++) {
            for (int x = startX; x <= endX; x++) {
                var blocks = world[y][x];

                if (blocks.stream().anyMatch(block -> block.getBlockId().equals("lava"))) {
                    setOnFire(game, x + 1, y);
                    setOnFire(game, x - 1, y);
                    setOnFire(game, x, y + 1);
                    setOnFire(game, x, y - 1);
                }
            }
        }
    }

    public void setOnFire(Game game, int x, int y) {
        var world = game.getWorld();

        if (x < 0 || y < 0 || y >= world.length || x >= world[0].length) {
            return;
        }

        for (Block block : world[y][x]) {
            if ((block.getClass().isAnnotationPresent(Flamable.class) || block.isMob()) && !block.isOnFire()) {
                int maxTime = random.nextInt(8) + 5;

                if (!block.isMob()) {
                    block.setBurningTime(block.getBurningTime() + 1);
                    if (block.getBurningTime() >= maxTime) {
                        block.setOnFire(true);
                        block.setBurningTime(0);
                    }
                } else if (!block.getClass().isAnnotationPresent(FireImmune.class)) {
                    int dealDamage = game.getInventory().getItemInHand().map(Item::getDealDamage).orElse(1);
                    if (block.getHp() - dealDamage <= 0) {
                        // Mob is killed
                        world[y][x].remove(block);
                    } else {
                        block.decreaseHp(dealDamage);
                        block.setSpriteState(game.getGameStates().dependencies.entityHurtAnimation.get(block.getBlockId())
                                .setHurtAnimation(true, block.getSpriteState().get()));
                        if (block.getLinkedMobTexture() != null) {
                            block.getLinkedMobTexture().setSpriteState(game.getGameStates().dependencies.entityHurtAnimation.get(block.getBlockId())
                                    .setHurtAnimation(true, block.getLinkedMobTexture().getSpriteState().get()));
                        }
                    }

                    new Thread(() -> {
                        try {
                            Thread.sleep(500);
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }

                        block.setSpriteState(game.getGameStates().dependencies.entityHurtAnimation.get(block.getBlockId())
                                .setHurtAnimation(false, block.getSpriteState().get()));

                        if (block.getLinkedMobTexture() != null) {
                            block.getLinkedMobTexture().setSpriteState(game.getGameStates().dependencies.entityHurtAnimation.get(block.getBlockId())
                                    .setHurtAnimation(false, block.getLinkedMobTexture().getSpriteState().get()));
                        }
                    }).start();
                }
            }
        }
    }
}
