package org.project.entity.enemies;

import org.project.entity.Entity;
import org.project.item.weapons.Sword;
import org.project.item.weapons.Weapon;


public abstract class Enemy  implements Entity {
    Weapon weapon;
    private int hp;
    private int maxHP;
    private int mp;
    private int maxMP;
    private boolean defending = false;
    private double defendRate;
    private double attackMultiplier = 1;
    private boolean hasKey = false;
    private static boolean keyFound = false;
    private boolean successfulAction = true;

    public Enemy(int hp, int mp, Weapon weapon) {
        this.hp = hp;
        this.maxHP = hp;
        this.mp = mp;
        this.maxMP = mp;
        this.weapon = weapon;
        if (!keyFound) { hasKey = Math.random() < .2;}
    }

    @Override
    public  void attack(Entity target) {
        if (getMP() >= weapon.getManaCost()) {
            System.out.println(this.getClass().getSimpleName() + ": attacking " + target.getClass().getSimpleName());
            double damage = getAttackMultiplier() * weapon.getDamage();
            if(((Sword)(weapon)).charge()) damage *= 1.4;
            if (target.isDefending()) {
                target.takeDamage((int) (damage * (1 - target.getDefendRate())),this);
                target.setDefending(false);
            } else {
                target.takeDamage((int) damage,this);
            }
            setMP(getMP() - weapon.getManaCost());
        }
        else {
            System.out.println("not enough mana");
            setSuccessfulAction(false);
        }
    }

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

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

    @Override
    public void takeDamage(int damage) {
        if (isDefending()) {
            setHP(getHP() - (int) ((1 - getDefendRate())) * damage);
            System.out.println(this.getClass().getSimpleName() + " took " + (int) ((1 - getDefendRate())) * damage + " damages!");
        }
        else {
            System.out.println(this.getClass().getSimpleName() + " took " + damage + " damages!");
            setHP(getHP() - damage);
            if (getHP() <= 0) {
                setHP(0);
            }
        }
    }

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

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

    @Override
    public void setHP(int hp) {
        this.hp = hp;
    }

    @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 mp) {
        this.mp = mp;
    }

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

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

    @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;
    }

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

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

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

    @Override
    public String toString() {
        return getClass().getSimpleName();
    }

    public boolean dropKey() {
        if (hp  <= 0 && hasKey) {
            keyFound = true;
            return true;
        }
        return false;
    }

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

    public boolean isSuccessfulAction() {
        return successfulAction;
    }
}

