package org.project.location;

import org.project.entity.enemies.*;
import org.project.entity.players.Player;
import java.util.*;

public class GameEngine
{
    int keys = 0;
    boolean goblinKey = false;
    boolean skeletonKey = false;
    boolean vampireKey = false;

    GameDisplay display = new GameDisplay();
    Player player;
    Random random = new Random();

    List<Location> locations = new ArrayList<>();

    public GameEngine(Player player)
    {
        this.player = player;
        createLocations();
    }

    public void runGame()
    {
        Location dragonLoc = locations.get(locations.size() - 1);

        List<Location> enemyLoc = new ArrayList<>(locations);
        enemyLoc .remove(enemyLoc .size() - 1);

        Collections.shuffle(enemyLoc , random);

        while (true)
        {
            if (keys >= 3)
            {
                System.out.println(display.YELLOW + "\n>>> You have collected all 3 Keys!🔑" + display.RESET);
                System.out.println(">>> 🔓 Final battle : ");
                System.out.println("----------------------------------------\n");

                fightEnemies(dragonLoc.getEnemies(), dragonLoc.getName());

                if(!player.isAlive())
                {
                    System.out.println(display.RED + "\n ❌ GAME OVER! ❌ " + display.RESET);
                    return;
                }
                else
                {
                    System.out.println(display.YELLOW + "\n🎉 CONGRATULATIONS! 🎉" + display.RESET);
                    return;
                }
            }


            for (Location loc : enemyLoc)
            {
                System.out.println(">>> Entering: " + loc.getName());
                System.out.println("----------------------------------------");

                fightEnemies(loc.getEnemies(), loc.getName());

                if (!player.isAlive())
                {
                    System.out.println(display.RED + "\n ❌ You died! GAME OVER ❌" + display.RESET);
                    return;
                }
                if (keys >= 3) break;
            }
        }
    }

    private void fightEnemies(List<Enemy> enemies, String locationName)
    {
        for (int i = 0; i < enemies.size(); i++)
        {
            Enemy enemy = enemies.get(i);

            System.out.println("❗An enemy is coming : " + enemy.getName() + "❗");

            while (enemy.isAlive() && player.isAlive())
            {
                display.showStatus(player, enemy, this);

                String choice = display.battleChoices();

                switch (choice)
                {
                    case "1":
                        display.showPlayerTurn(player);
                        player.attack(enemy);
                        break;
                    case "2":
                        display.showPlayerTurn(player);
                        player.heavyAttack(enemy);
                        break;
                    case "3":
                        display.showPlayerTurn(player);
                        player.defend();
                        break;
                    case "4":
                        display.showPlayerTurn(player);
                        player.specialAbility(enemy);
                        break;
                    case "5":
                        display.showPlayerTurn(player);
                        player.heal();
                        break;
                    case "6":
                        display.showPlayerTurn(player);
                        player.fillMana();
                        break;
                    case "7":
                        display.showPlayerTurn(player);
                        player.fillHp();
                        break;
                    default:
                        System.out.println("Invalid option. Try again.");
                        continue;
                }

                if (!enemy.isAlive())
                {
                    System.out.println(display.BLUE + ">> Enemy died ! ✔️" + display.RESET);
                    break;
                }

                enemyTurn(enemy);

                if (!player.isAlive()) break;
            }

            if (player.isAlive() && !enemy.isAlive())
            {
                int xp= 0;
                boolean isLastEnemyInLocation = (i == enemies.size() - 1);

                if (enemy instanceof Goblin)
                {
                    xp = 10;
                    if (!goblinKey)
                    {
                        if (isLastEnemyInLocation || random.nextDouble() < 0.4)
                        {
                            goblinKey = true;
                            keys++;
                            System.out.println(display.YELLOW + ">> You found the Goblin Key! 🔑" + display.RESET);
                        }
                    }
                }
                else if (enemy instanceof Skeleton)
                {
                    xp = 15;
                    if (!skeletonKey)
                    {
                        if (isLastEnemyInLocation || random.nextDouble() < 0.4)
                        {
                            skeletonKey = true;
                            keys++;
                            System.out.println(display.YELLOW + ">> You found the Skeleton Key!🔑" + display.RESET);
                        }
                    }
                }
                else if (enemy instanceof Vampire)
                {
                    xp = 20;
                    if (!vampireKey)
                    {
                        if (isLastEnemyInLocation || random.nextDouble() < 0.4)
                        {
                            vampireKey = true;
                            keys++;
                            System.out.println(display.YELLOW + ">> You found the Vampire Key!🔑" + display.RESET);
                        }
                    }
                }
                player.gainXp(xp);
            }
            if (keys >= 3) return;
        }
    }

    private void enemyTurn(Enemy enemy)
    {
        enemy.resetDefendState();
        System.out.println("\n--- Enemy's Turn ---");
        int action = random.nextInt(4);

        switch (action)
        {
            case 0:
                enemy.attack(player);
                break;
            case 1:
                enemy.defend();
                break;
            case 2:
                enemy.specialAbility(player);
                break;
            case 3:
                enemy.heal();
                break;
        }
    }

    private void createLocations()
    {
        List<Enemy> goblins = new ArrayList<>();
        for (int i = 0; i < 4; i++)
        {
            goblins.add(new Goblin(10, 10, "Goblin👹"));
        }

        List<Enemy> skeletons = new ArrayList<>();
        for (int i = 0; i < 4; i++)
        {
            skeletons.add(new Skeleton(20, 20, "Skeleton💀"));
        }

        List<Enemy> vampires = new ArrayList<>();
        for (int i = 0; i < 4; i++)
        {
            vampires.add(new Vampire(30, 30, "Vampire🧛‍♂️"));
        }

        List<Enemy> dragon = new ArrayList<>();
        dragon.add(new Dragon(100, 100, "Dragon🐉"));

        locations.add(new Location("Goblin Forest", goblins));
        locations.add(new Location("Skeleton Graveyard", skeletons));
        locations.add(new Location("Vampire Castle", vampires));
        locations.add(new Location("Dragon Cave", dragon));
    }
}