package org.project.entity.players;

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


public abstract class Player implements Entity, combatOptions {
    protected String name;
    Weapon weapon;
    Armor armor;
    private int hp;
    private int maxHP;
    private int mp;
    private int maxMP;
    private boolean defending = false;
    private double defendRate;
    private boolean isUsingSpecialAbility = false;
    private double attackMultiplier = 1;
    private boolean hasGoblinKey = false;
    private boolean hasSkeletonKey = false;
    private boolean hasVampireKey = false;
    private boolean successfulAction = true;

    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) {
        double damage = getAttackMultiplier() * weapon.getDamage();
        if (target.isDefending()) {
            target.takeDamage( (int) (damage * (1 - target.getDefendRate())));
            target.setDefending(false);
        }
        else {
            target.takeDamage((int) damage);
        }
    };

    @Override
    public void lightAttack(Entity target) {
        System.out.println(this.getClass().getSimpleName() + " light attacking");
    }

    @Override
    public void heavyAttack(Entity target) {
        System.out.println(this.getClass().getSimpleName() + " heavy attacking");
    }

    @Override
    public void defend(){
        System.out.println(this.getClass().getSimpleName() + " is defending");
        setDefending(true);
    };

    @Override
    public abstract void specialAbility(Entity target);


    @Override
    public void takeDamage(int damage) {

        int finalDamage = armor.getDefense() - damage;
        if (finalDamage < 0) {
            System.out.println(this.getClass().getSimpleName() + " took " + -finalDamage + " damages!");
            setHP(getHP() + finalDamage);
            armor.setDefense(0);
        }
        else {
            System.out.println(this.getClass().getSimpleName() + " took " + damage + " damages!");
            armor.setDefense(finalDamage);
        }
    }

    @Override
    public void takeDamage(int damage, Entity target) {
        this.takeDamage(damage);
    }

    @Override
    public void heal(int health) {
        System.out.println(this.getClass().getSimpleName() + " is healing " + health + " HPs");
        setHP(getHP() + health);
    }


    public String getName() {
        return name;
    }

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

    @Override
    public void setHP(int hp) {
        this.hp = hp;
        if (this.hp > maxHP) {
            this.hp = maxHP;
        } else if (this.hp < 0) {
            this.hp = 0;
        }
    }

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

    @Override
    public void setMaxHP(int maxHP) {
        this.maxHP = maxHP;
    }


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

    @Override
    public void setMP(int mana) {
        mp = mana;
        if (mp > maxMP) {
            mp = maxMP;
        } else if (mp < 0) {
            mp = 0;
        }
    }


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

    @Override
    public void setMaxMP(int maxMP) {
        this.maxMP = maxMP;
    }

    @Override
    public Weapon getWeapon() {
        return weapon;
    }

    public Armor getArmor() {
        return armor;
    }

    @Override
    public boolean isDefending() { return defending; }

    @Override
    public void setDefending(boolean defending) { this.defending = defending; }

    @Override
    public double getDefendRate() { return defendRate; }

    @Override
    public void setDefendRate(double defendRate) { this.defendRate = defendRate; }

    public boolean getUsingSpecialAbility() { return isUsingSpecialAbility; }

    public void setUsingSpecialAbility(boolean isUsingSpecialAbility) { this.isUsingSpecialAbility = isUsingSpecialAbility; }

    @Override
    public double getAttackMultiplier() {
        return attackMultiplier;
    }

    @Override
    public void setAttackMultiplier(double multiplier) {
        attackMultiplier = multiplier;
    }

    public boolean HasGoblinKey() { return hasGoblinKey; }
    public boolean HasSkeletonKey() { return hasSkeletonKey; }
    public boolean HasVampireKey() { return hasVampireKey; }

    public void achieveKey(Entity target) {
        if ( target instanceof Goblin) { hasGoblinKey = true; }
        else if (target instanceof Skeleton) { hasSkeletonKey = true; }
        else { hasVampireKey = true; }
    }

    public void setSuccessfulAction(boolean successfulAction) {
        this.successfulAction = successfulAction;
    }

    public boolean isSuccessfulAction() {
        return successfulAction;
    }

}
