package org.project.entity.players;

import org.project.entity.Entity;
import org.project.entity.ICombatActions;
import org.project.item.weapons.Weapon;
import org.project.utils.ConsoleColors;

public abstract class Player implements Entity, ICombatActions {
    protected String name;
    protected int hp;
    protected int maxHP;
    protected int mp;
    protected int maxMP;
    protected int damage;
    protected int level;
    protected int xp;
    protected Weapon weapon;
    protected boolean defending;

    public Player(String name, int maxHP, int maxMP, int damage, Weapon weapon) {
        this.name = name;
        this.maxHP = maxHP;
        this.hp = maxHP;
        this.maxMP = maxMP;
        this.mp = maxMP;
        this.damage = damage;
        this.weapon = weapon;
        this.level = 1;
        this.xp = 0;
        this.defending = false;
    }

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

    @Override
    public void lightAttack(Entity target) {
        int totalDamage = damage;
        if (weapon != null) {
            totalDamage += weapon.getDamage();
        }
        System.out.println(ConsoleColors.CYAN_BOLD + name + " used Light Attack!" + ConsoleColors.RESET);
        target.receiveAttack(totalDamage, false);
    }

    @Override
    public void heavyAttack(Entity target) {
        if (mp < 8) {
            System.out.println(ConsoleColors.RED + "Not enough Mana!" + ConsoleColors.RESET);
            return;
        }
        mp -= 8;
        int totalDamage = damage * 2;
        if (weapon != null) {
            totalDamage += weapon.getDamage();
        }
        System.out.println(ConsoleColors.PURPLE_BOLD + name + " used Heavy Attack!" + ConsoleColors.RESET);
        target.receiveAttack(totalDamage, false);
    }

    @Override
    public void defend() {
        if (mp < 5) {
            System.out.println(ConsoleColors.RED + "Not enough Mana!" + ConsoleColors.RESET);
            return;
        }
        mp -= 5;
        defending = true;
        System.out.println(ConsoleColors.CYAN + name + " is defending." + ConsoleColors.RESET);
    }

    @Override
    public void heal() {
        if (mp < 10) {
            System.out.println(ConsoleColors.RED + "Not enough Mana!" + ConsoleColors.RESET);
            return;
        }
        mp -= 10;
        hp += 25;
        if (hp > maxHP) {
            hp = maxHP;
        }
        System.out.println(ConsoleColors.GREEN_BOLD + name + " healed for 25 HP." + ConsoleColors.RESET);
    }

    @Override
    public void heal(int amount) {
        hp += amount;
        if (hp > maxHP) {
            hp = maxHP;
        }
        System.out.println(ConsoleColors.GREEN + name + " healed for " + amount + " HP." + ConsoleColors.RESET);
    }

    @Override
    public abstract void specialAbility(Entity target);

    @Override
    public void receiveAttack(int damage, boolean ignoreDefense) {
        if (defending && !ignoreDefense) {
            damage /= 2;
            defending = false;
        }
        hp -= damage;
        if (hp < 0) {
            hp = 0;
        }
        System.out.println(ConsoleColors.RED + name + " took " + damage + " damage." + ConsoleColors.RESET);
    }

    // Convenience method
    public void takeDamage(int damage) {
        receiveAttack(damage, false);
    }

    @Override
    public void fillMana(int amount) {
        mp += amount;
        if (mp > maxMP) {
            mp = maxMP;
        }
        System.out.println(ConsoleColors.BLUE + name + " restored " + amount + " Mana." + ConsoleColors.RESET);
    }

    @Override
    public boolean isAlive() {
        return hp > 0;
    }

    public void gainXP(int amount) {
        xp += amount;
        while (xp >= level * 100) {
            xp -= level * 100;
            level++;
            maxHP += 10;
            maxMP += 5;
            damage += 3;
            hp = maxHP;
            mp = maxMP;
            System.out.println(ConsoleColors.YELLOW_BOLD + "🌟 " + name + " reached level " + level + "!" + ConsoleColors.RESET);
        }
    }

    @Override
    public int getHP() {
        return hp;
    }

    @Override
    public int getMP() {
        return mp;
    }

    @Override
    public int getMaxHP() {
        return maxHP;
    }

    @Override
    public int getMaxMP() {
        return maxMP;
    }

    @Override
    public String getName() {
        return name;
    }

    public int getLevel() {
        return level;
    }

    public Weapon getWeapon() {
        return weapon;
    }

    public void setWeapon(Weapon weapon) {
        this.weapon = weapon;
    }

    public int getDamage() {
        return damage;
    }
}