package org.project;

import org.project.entity.enemies.Dragon;
import org.project.entity.enemies.Enemy;
import org.project.entity.players.Assassin;
import org.project.entity.players.Knight;
import org.project.entity.players.Player;
import org.project.entity.players.Wizard;
import org.project.item.consumables.Flask;
import org.project.item.weapons.Dagger;
import org.project.location.Location;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;

public class Main {
    private static Scanner scanner = new Scanner(System.in);
    private static Random random = new Random();
    private static Player player;
    private static List<Location> locations = new ArrayList<>();
    private static boolean hasGoblinKey = false;
    private static boolean hasSkeletonKey = false;
    private static boolean hasVampireKey = false;
    private static ArrayList<Flask> inventory = new ArrayList<>();


    public static void main(String[] args) {
        System.out.println("\u001B[33m Welcome to JAVA KNIGHT \u001B[0m");
        chooseClass();
        //hasGoblinKey = true;
        //hasVampireKey = true;
        //hasSkeletonKey = true;

        setupLocations();

        boolean gameRunning = true;

        while (gameRunning && player.isAlive()) {
            Location currentLocation = locations.get(0);
            System.out.println("\n\u001B[36m you are in: " + currentLocation.getName() + "\u001B[0m");
            System.out.println(player.getName() + "level: " + player.getLevel() + "HP: " + player.getHp() + "/" + player.getMaxHP() + "MP" + player.getMp() + "/" + player.getMaxMP());
            System.out.println("\n\u001B[33m What do you want to do?\u001B[0m");
            System.out.println("1. Fight an enemy");
            System.out.println("2. Move to another location");

            if (hasSkeletonKey && hasGoblinKey && hasVampireKey) {
                System.out.println("3.Go to castle to fight dragon !");
            } else {
                System.out.println("\u001B[90m🔒 Need All 3 keys: " + (hasGoblinKey ? "✓ Goblin" : "not Goblin") + " | " + (hasSkeletonKey ? "✓ Skeleton" : "not Skeleton") + " | " + (hasVampireKey ? "✓ Vampire" : "not Vampire") + "\u001B[0m");
            }

            System.out.println("\n Choose: ");

            int choice = getIntInput();

            if (choice == 1) {
                fight(currentLocation);
            } else if (choice == 2) {
                moveLocation();
            } else if (choice == 3 && hasVampireKey && hasSkeletonKey && hasGoblinKey) {
                fightDragon();
                break;
            }
        }
        if (!player.isAlive()) {
            System.out.println("\u001B[31m GAME OVER" + player.getName() + "has been defeated \u001B[0m");
        }
    }

    public static int getIntInput(){
        while (!scanner.hasNextInt()){
            System.out.println("Enter an number: ");
            scanner.next();
        }
        return scanner.nextInt();
    }

    private static void chooseClass() {
        System.out.println("\n1.Knight | 2.Wizard | 3.Assassin");
        System.out.println("Choose class :");
        int choice = getIntInput();
        System.out.println("Enter name :");
        String name = scanner.next();

        switch (choice) {
            case 1:
                player = new Knight(name);
                break;
            case 2:
                player = new Wizard(name);
                break;
            case 3:
                player = new Assassin(name);
                break;
            default:
                player = new Knight(name);
        }

        for (int i = 0; i < 3; i++) {
            inventory.add(new Flask());
        }
        System.out.println("You have 3 flask");
    }

    private static void setupLocations(){
        locations = new ArrayList<>();
        locations.add(new Location("Dark forest"));
        locations.add(new Location("Mine"));
        locations.add(new Location("Desert"));
    }

    private static void moveLocation(){
        System.out.println("\n Locations :");
        for (int i = 0; i < locations.size(); i++) {
            System.out.println((i+1) + ". " + locations.get(i).getName());
        }
        System.out.println("Choice :");
        int choice = getIntInput()-1;
        Location selected = locations.get(choice);
        locations.remove(choice);
        locations.add(0,selected);
    }

    private static void fight(Location location){
        Enemy enemy = location.getRandomEnemy();
        System.out.println(player.getName() + " VS " + enemy.getName());

        boolean enemyTurn = false;

        while (player.isAlive() && enemy.isAlive()){
            if(!enemyTurn){
                System.out.println( player.getHp() + "/" + player.getMaxHP() + "HP|" + player.getMp() + "/" + player.getMaxMP());
                System.out.println("Enemy :" + enemy.getHp() + "/" + enemy.getMaxHP() + "HP");
                System.out.println("\n1.Light(0) 2.Heavy(8) 3.Defend(6) 4.Heal(12) 5.Special 6.Flask(" + inventory.size() + ")");
                System.out.println("Choice: ");

                int action = getIntInput();

                switch (action){
                    case 1:
                        player.lightAttack(enemy);
                        break;
                    case 2:
                        player.heavyAttack(enemy);
                        break;
                    case 3:
                        player.defend();
                        break;
                    case 4:
                        player.heal();
                        break;
                    case 5:
                        player.specialAbility(enemy);
                        break;
                    case 6:
                        if(!inventory.isEmpty())   inventory.remove(0).use(player);
                        else    System.out.println("No flask");
                        break;
                    default:
                        player.lightAttack(enemy);
                }
                if(!enemy.isAlive())   break;

                enemyTurn = true;
            }else{
                System.out.println("\n " + enemy.getName() + " attacks!");
                enemy.specialAbility(player);

                if(!player.isAlive())    break;
                enemyTurn = false;
            }
        }
        if(!enemy.isAlive()){
            System.out.println("\u001B[32 " + " Victory!" + enemy.getXpReward() + "XP\u001B[0m");
            player.gainXp(enemy.getXpReward());
            checkKeyDrop(enemy);
            location.removeEnemy(enemy);
            player.heal(30);
            player.fillMana(20);
        }else if(!player.isAlive()){
            System.out.println("\u001B[32" + " You were  killed! \u001B[0m");
        }
    }

    private static void checkKeyDrop(Enemy enemy){
        String keyType = enemy.geTKeyType();
        if(keyType == null)   return;

        double chance = random.nextDouble();

        if(keyType.equals("Goblin key") && !hasGoblinKey && chance < 0.2 ){
            hasGoblinKey = true;
            System.out.println("\u001B[33m Got Goblin key!  (1/3) \u001B[0m");
        }else if(keyType.equals("Skeleton key") && !hasSkeletonKey && chance < 0.2 ){
            hasSkeletonKey = true;
            System.out.println("\u001B[33m Got Skeleton key!  (2/3) \u001B[0m");
        }else if(keyType.equals("Vampire key") && !hasVampireKey && chance < 0.2 ){
            hasVampireKey = true;
            System.out.println("\u001B[33m Got Vampire key!  (3/3) \u001B[0m");
        }

        if(hasGoblinKey && hasSkeletonKey && hasVampireKey){
            System.out.println("\u001B[33m All 3 keys collected! Castle is open! \u001B[0m");
        }
    }

    private static void fightDragon(){
        Dragon dragon = new Dragon();
        System.out.println("\u001B[31m FINAL BOSS! \u001B[0m");

        boolean enemyTurn = false;

        while(player.isAlive() && dragon.isAlive()){
            if(!enemyTurn){
                System.out.println("\n " + player.getHp() + "/" + player.getMaxHP() +"| " + player.getMp() + "/" + player.getMaxMP());
                System.out.println("Dragon: " + dragon.getHp() + "/" + dragon.getMaxHP());
                System.out.println("\n1.Light 2.Heavy 3.Defend 4.Heal 5.Special 6.Flask (" + inventory.size() + ")");
                System.out.println("Choose: ");

                int action = getIntInput();

                switch (action) {
                    case 1:
                        player.lightAttack(dragon);
                        break;
                    case 2:
                        player.heavyAttack(dragon);
                        break;
                    case 3:
                        player.defend();
                        break;
                    case 4:
                        player.heal();
                        break;
                    case 5:
                        player.specialAbility(dragon);
                        break;
                    case 6:
                        if (!inventory.isEmpty()) inventory.remove(0).use(player);
                        break;
                    default:
                        player.lightAttack(dragon);
                }

                if(!dragon.isAlive()){
                    break;
                }else{
                    dragon.specialAbility(player);
                    enemyTurn = false;
                }
            }
            if(!dragon.isAlive()){
                System.out.println("\u001B[33m You killed dragon ! \u001B[0m");
            }else{
                System.out.println("\u001B[31m Dragon killed you !  \u001B[0m");
            }
        }
    }
}