package org.project;

import org.project.entity.Entity;
import org.project.entity.enemies.*;
import org.project.entity.players.*;
import org.project.location.Location;
import org.project.item.weapons.Sword;
import org.project.item.armors.KnightArmor;

import java.util.ArrayList;
import java.util.Scanner;

public class GameLoop
{
    private Player player;
    private Enemy currentEnemy;
    private Scanner scanner;
    private boolean hasGoblinKey;
    private boolean hasSkeletonKey;
    private boolean hasVampireKey;
    private boolean gameRunning;

    public GameLoop() {
        scanner = new Scanner(System.in);
        hasGoblinKey = false;
        hasSkeletonKey = false;
        hasVampireKey = false;
        gameRunning = true;
    }

    public void start() {
        System.out.println(" Welcome to Java Knight! ");
        System.out.println("================================");

        chooseClass();

        while (gameRunning) {
            mainMenu();
        }

        scanner.close();
    }

    private void chooseClass() {
        System.out.println("\nChoose your class:");
        System.out.println("1. Knight (High HP, High Damage)");
        System.out.println("2. Wizard (Highest HP, Spellcaster)");
        System.out.println("3. Assassin (Highest MP, Critical Hits)");
        System.out.print("Enter choice (1-3): ");

        int choice = scanner.nextInt();
        scanner.nextLine();

        switch (choice) {
            case 1:
                player = new Knight("Sir Duncan");
                System.out.println("You have chosen the Knight!");
                break;
            case 2:
                player = new Wizard("Merlin");
                System.out.println("You have chosen the Wizard!");
                break;
            case 3:
                player = new Assassin("Shadow");
                System.out.println("You have chosen the Assassin!");
                break;
            default:
                player = new Knight("Sir Duncan");
                System.out.println("Default: Knight chosen!");
        }

        System.out.println("\n" + player.getName() + " the " + player.getPlayerClass());
        System.out.println("HP: " + player.getHP() + "/" + player.getMaxHP());
        System.out.println("MP: " + player.getMP() + "/" + player.getMaxMP());
    }

    private void mainMenu() {
        System.out.println("\n=================================");
        System.out.println("Location: Forest of Shadows");
        System.out.println("Player: " + player.getName() + " (Level " + player.level() + ")");
        System.out.println("HP: " + player.getHP() + "/" + player.getMaxHP());
        System.out.println("MP: " + player.getMP() + "/" + player.getMaxMP());
        System.out.println("=================================");
        System.out.println("1.Fight Enemy");
        System.out.println("2.Move to another location");

        if (hasAllKeys()) {
            System.out.println("3.Go to Castle to fight the Dragon!");
        }

        System.out.println("4.Quit Game");
        System.out.print("Choose: ");

        int choice = scanner.nextInt();
        scanner.nextLine();

        switch (choice) {
            case 1:
                spawnEnemy();
                combat();
                break;
            case 2:
                System.out.println("You move to a new location...");
                break;
            case 3:
                if (hasAllKeys()) {
                    fightDragon();
                } else {
                    System.out.println("You need all 3 keys to enter the Castle!");
                }
                break;
            case 4:
                System.out.println("Thanks for playing Java Knight!");
                gameRunning = false;
                break;
            default:
                System.out.println("Invalid choice!");
        }
    }


    private boolean hasAllKeys() {
        return hasGoblinKey && hasSkeletonKey && hasVampireKey;
    }

    private void spawnEnemy() {
        int random = (int)(Math.random() * 3);
        switch (random) {
            case 0:
                currentEnemy = new Goblin();
                break;
            case 1:
                currentEnemy = new Skeleton();
                break;
            case 2:
                currentEnemy = new Vampire();
                break;
        }
    }

    private void combat() {
        System.out.println("\n COMBAT STARTED! ");
        System.out.println("=================================");

        while (player.isAlive() && currentEnemy.isAlive()) {
            playerTurn();
            if (currentEnemy.isAlive()) {
                enemyTurn();
            }
        }

        if (player.isAlive()) {
            System.out.println("\n VICTORY! ");
            handleVictory();
        } else {
            System.out.println("\n GAME OVER! You have been defeated! ");
            gameRunning = false;
        }
    }

    private void playerTurn() {
        System.out.println("\n--- YOUR TURN ---");
        System.out.println("[" + player.getName() + " - " + player.getHP() + "/" + player.getMaxHP() + " HP | "
                + player.getMP() + "/" + player.getMaxMP() + " MP]");
        System.out.println("[" + currentEnemy.getName() + " - " + currentEnemy.getHP() + "/" + currentEnemy.getMaxHP() + " HP]");
        System.out.println("\nChoose action:");
        System.out.println("1. Light Attack (0 MP)");
        System.out.println("2. Heavy Attack (-10 MP)");
        System.out.println("3. Defend (-6 MP)");
        System.out.println("4. Heal (-12 MP)");
        System.out.println("5. Special Ability (-15/18 MP)");
        System.out.print("Choice: ");

        int choice = scanner.nextInt();
        scanner.nextLine();

        switch (choice) {
            case 1:
                player.lightAttack(currentEnemy);
                break;
            case 2:
                player.heavyAttack(currentEnemy);
                break;
            case 3:
                player.defend();
                break;
            case 4:
                player.heal(25);
                break;
            case 5:
                player.specialAbility(currentEnemy);
                break;
            default:
                System.out.println("Invalid! Using Light Attack.");
                player.lightAttack(currentEnemy);
        }

        System.out.println("\nPress Enter to continue...");
        scanner.nextLine();
    }

    private void enemyTurn() {
        System.out.println("\n--- ENEMY TURN ---");
        currentEnemy.attack(player);
        System.out.println("\nPress Enter to continue...");
        scanner.nextLine();
    }

    private void handleVictory() {
        int xpReward = currentEnemy.getXpReward();
        player.gainXp(xpReward);
        System.out.println("Earned " + xpReward + " XP!");

        checkKeyDrop();

        player.restoreAfterBattle();

        System.out.println("\nPress Enter to continue...");
        scanner.nextLine();
    }

    private void checkKeyDrop() {
        String enemyType = currentEnemy.getEnemyType();
        int dropChance = 30;

        if (Math.random() * 100 < dropChance) {
            switch (enemyType) {
                case "GOBLIN":
                    if (!hasGoblinKey) {
                        hasGoblinKey = true;
                        System.out.println("You obtained the GOBLIN KEY! (1/3)");
                    } else {
                        System.out.println("You already have the Goblin Key.");
                    }
                    break;
                case "SKELETON":
                    if (!hasSkeletonKey) {
                        hasSkeletonKey = true;
                        System.out.println("You obtained the SKELETON KEY! (2/3)");
                    } else {
                        System.out.println("You already have the Skeleton Key.");
                    }
                    break;
                case "VAMPIRE":
                    if (!hasVampireKey) {
                        hasVampireKey = true;
                        System.out.println("You obtained the VAMPIRE KEY! (3/3)");
                    } else {
                        System.out.println("You already have the Vampire Key.");
                    }
                    break;
            }
        } else {
            System.out.println("No key dropped this time... Keep fighting!");
        }
    }

    private void fightDragon() {
        System.out.println("\nYou enter the Castle and face the DRAGON!");
        System.out.println("THE FINAL BOSS APPEARS!");

        currentEnemy = new Dragon();

        while (player.isAlive() && currentEnemy.isAlive()) {
            playerTurn();
            if (currentEnemy.isAlive()) {
                enemyTurn();
            }
        }

        if (player.isAlive()) {
            System.out.println("\nCONGRATULATIONS!");
            System.out.println("You have slain the Dragon and broken the curse!");
            System.out.println("The land of Javanest is saved!");
            System.out.println("YOU WIN!");
            gameRunning = false;
        } else {
            System.out.println("\nThe Dragon has defeated you!");
            System.out.println("The curse remains... Game Over!");
            gameRunning = false;
        }
    }
}
