package org.project.entity.players;

import org.project.entity.Entity;
import org.project.item.Item;
import org.project.item.armors.Armor;
import org.project.item.weapons.Weapon;
import java.util.ArrayList;
import java.util.List;
import org.project.ConsoleColors;

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 List<Item> inventory;
    protected int coins;
    protected int xp;
    protected int level;
    protected boolean defending;

    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;
        this.inventory = new ArrayList<>();
        this.coins = 0;
        this.xp = 0;
        this.level = 1;
        this.defending = false;
    }
    public void takeRawDamage(int damage) {
        hp -= damage;
        if (hp < 0) hp = 0;
    }
    public void setWeapon(Weapon weapon) {
        this.weapon = weapon;
    }
    public void setArmor(Armor armor) {
        this.armor = armor;
    }
    @Override
    public void attack(Entity target) {
        int damage = weapon.getDamage();
        target.takeDamage(damage);
    }
    @Override
    public void takeDamage(int damage) {
        int defense = armor.isBroke() ? 0 : armor.getDefense();
        int actualDamage = Math.max(damage - defense, 0);
        if (defending) {
            actualDamage = 0;
            defending = false;
        }
        hp -= actualDamage;
        if (hp < 0) hp = 0;
        if (!armor.isBroke()) {
            armor.reduceDurability(1);
        }
    }
    @Override
    public void heal(int health) {
        hp += health;
        if (hp > maxHP) hp = maxHP;
    }
    @Override
    public void fillMana(int mana) {
        mp += mana;
        if (mp > maxMP) mp = maxMP;
    }
    @Override
    public boolean isAlive() {
        return hp > 0;
    }
    @Override
    public int getHp() {
        return hp;
    }
    @Override
    public int getMp() {
        return mp;
    }
    @Override
    public int getMaxHP() {
        return maxHP;
    }
    @Override
    public int getMaxMP() {
        return maxMP;
    }
    public abstract void lightAttack(Entity target);
    public abstract void heavyAttack(Entity target);
    @Override
    public abstract void defend();
    public abstract void specialAbility(Entity target);
    public boolean consumeMana(int cost) {
        if (mp >= cost) {
            mp -= cost;
            return true;
        }
        return false;
    }

    public void addItem(Item item) {
        inventory.add(item);
    }
    public void removeItem(Item item) {
        inventory.remove(item);
    }
    public List<Item> getInventory() {
        return inventory;
    }
    public void addCoins(int amount) {
        coins += amount;
    }
    public int getCoins() {
        return coins;
    }

    public void addXp(int amount) {
        xp += amount;
        checkLevelUp();
    }
    private void checkLevelUp() {
        int xpNeeded = level * 50;
        while (xp >= xpNeeded) {
            xp -= xpNeeded;
            level++;
            maxHP += 20;
            maxMP += 10;
            hp = maxHP;
            mp = maxMP;
            System.out.println(ConsoleColors.YELLOW + name + " leveled up to Level " + level + "!" + ConsoleColors.RESET);
            xpNeeded = level * 50;
        }
    }
    public int getXp() {
        return xp;
    }
    public int getLevel() {
        return level;
    }
    public String getName() {
        return name;
    }
    public Weapon getWeapon() {
        return weapon;
    }
    public Armor getArmor() {
        return armor;
    }
}