package org.project.entity.players;

import org.project.entity.Entity;
import org.project.item.armors.Armor;
import org.project.item.weapons.Weapon;

public abstract class Player implements Entity {
    protected String name;
    protected Weapon weapon;
    protected Armor armor;

    protected int hp;
    protected int maxHP;
    protected int mp;
    protected int maxMP;

    protected int level = 1;
    protected int xp = 0;
    protected int xpToNextLevel = 50;

    protected boolean isDefending = false;
    protected boolean isInvisible = false;
    protected boolean nextAttackCritical = false;

    public Player(String name, int hp, int mp, Weapon weapon, Armor armor) {
        this.name = name;
        this.hp = hp;
        this.maxHP = hp;
        this.mp = mp;
        this.maxMP = mp;
        this.weapon = weapon;
        this.armor = armor;
    }

    @Override
    public void attack(Entity target) {
        lightAttack(target);
    }

    public void lightAttack(Entity target) {
        int damage = weapon != null ? weapon.getDamage() : 10;
        if (nextAttackCritical) {
            damage *= 2;
            nextAttackCritical = false;
            System.out.println("\u001B[35m💥 CRITICAL HIT!\u001B[0m");
        }
        System.out.println("⚔️ " + name + " used Light Attack! (0 Mana)");
        target.takeDamage(damage);
    }

    public void heavyAttack(Entity target) {
        int manaCost = 8;
        if (mp < manaCost) {
            System.out.println("❌ Not enough Mana/Stamina! Using Light Attack instead.");
            lightAttack(target);
            return;
        }
        mp -= manaCost;
        int damage = (weapon != null ? weapon.getDamage() : 10) + 12;
        if (nextAttackCritical) {
            damage *= 2;
            nextAttackCritical = false;
            System.out.println("\u001B[35m💥 CRITICAL HIT!\u001B[0m");
        }
        System.out.println("⚔️ " + name + " used Heavy Attack! (-" + manaCost + " Mana)");
        target.takeDamage(damage);
    }

    @Override
    public void defend() {
        int manaCost = 6;
        if (mp < manaCost) {
            System.out.println("❌ Not enough Mana/Stamina to Defend!");
            return;
        }
        mp -= manaCost;
        isDefending = true;
        System.out.println("🛡️ " + name + " is Defending! (-" + manaCost + " Mana)");
    }

    @Override
    public void heal(int health) {
        hp += health;
        if (hp > maxHP) hp = maxHP;
    }

    public void castHeal() {
        int manaCost = 12;
        if (mp < manaCost) {
            System.out.println("❌ Not enough Mana/Stamina to Heal!");
            return;
        }
        mp -= manaCost;
        int healAmount = 25;
        heal(healAmount);
        System.out.println("💚 " + name + " healed for " + healAmount + " HP! (-" + manaCost + " Mana)");
    }

    public abstract void specialAbility(Entity target);

    @Override
    public void fillMana(int mana) {
        mp += mana;
        if (mp > maxMP) mp = maxMP;
    }

    @Override
    public void takeDamage(int damage) {
        if (isInvisible) {
            System.out.println("👻 " + name + " dodged the attack completely (Invisible)!");
            isInvisible = false;
            return;
        }

        int actualDamage = damage;
        if (armor != null) {
            actualDamage -= armor.getDefense();
        }
        if (isDefending) {
            actualDamage /= 2;
            isDefending = false;
            System.out.println("🛡️ Defense reduced incoming damage!");
        }

        if (actualDamage < 0) actualDamage = 0;
        hp -= actualDamage;
        System.out.println("💥 " + name + " took \u001B[31m" + actualDamage + "\u001B[0m damage!");
    }

    public void addXp(int amount) {
        xp += amount;
        System.out.println("\u001B[33m✨ Gained " + amount + " XP!\u001B[0m");
        if (xp >= xpToNextLevel) {
            levelUp();
        }
    }

    private void levelUp() {
        level++;
        xp -= xpToNextLevel;
        xpToNextLevel = (int) (xpToNextLevel * 1.5);
        maxHP += 20;
        maxMP += 15;
        hp = maxHP;
        mp = maxMP;
        System.out.println("\u001B[32m🎉 LEVEL UP! Reached Level " + level + "! Max HP and Mana increased!\u001B[0m");
    }

    public void restoreStats() {
        hp = maxHP;
        mp = maxMP;
        isDefending = false;
        isInvisible = false;
        nextAttackCritical = false;
    }

    @Override public boolean isAlive() { return hp > 0; }
    public String getName() { return name; }
    @Override public int getHp() { return hp; }
    @Override public int getMaxHP() { return maxHP; }
    @Override public int getMp() { return mp; }
    @Override public int getMaxMP() { return maxMP; }
    public Weapon getWeapon() { return weapon; }
    public Armor getArmor() { return armor; }
}