package org.project.entity.players;

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

import java.io.Serializable;

public abstract class Player implements Entity, ICombatActions, Serializable
{
    private static final long serialVersionUID = 1L;

    protected String name;
    protected int hp, maxHP;
    protected int mp, maxMP;
    protected int level = 1;
    protected int xp = 0;

    protected boolean stunned = false;
    protected boolean invisible = false;
    protected boolean defending = false;

    private boolean goblinKey = false;
    private boolean skeletonKey = false;
    private boolean vampireKey = false;

    protected Weapon weapon;

    private static final String RESET = "\u001B[0m";
    private static final String RED = "\u001B[31m";
    private static final String GREEN = "\u001B[32m";
    private static final String YELLOW = "\u001B[33m";
    private static final String BLUE = "\u001B[34m";
    private static final String PURPLE = "\u001B[35m";

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

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

    @Override
    public void defend()
    {
        defending = true;
        System.out.println(BLUE + "🛡️ " + name + " is defending!" + RESET);
    }

    @Override
    public void heal(int amount)
    {
        hp = Math.min(maxHP, hp + amount);
    }

    @Override
    public void fillMana(int amount)
    {
        mp = Math.min(maxMP, mp + amount);
    }

    @Override
    public void takeDamage(int damage)
    {
        if (defending)
        {
            damage /= 2;
            defending = false;
        }
        hp = Math.max(0, hp - damage);
        System.out.println(RED + "💥 " + name + " took " + damage + " damage!" + 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 int getLevel() { return level; }
    @Override
    public String getName() { return name; }

    @Override
    public void setStunned(boolean v) { stunned = v; }
    @Override
    public boolean isStunned() { return stunned; }

    @Override
    public void setInvisible(boolean v) { invisible = v; }
    @Override
    public boolean isInvisible() { return invisible; }

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

    @Override
    public void gainXP(int xp)
    {
        this.xp += xp;
        if (this.xp >= level * 100)
        {
            level++;
            this.xp = 0;
            maxHP += 10;
            maxMP += 5;
            hp = maxHP;
            mp = maxMP;

            System.out.println(GREEN + "⭐ " + name + " leveled up to level " + level + "!" + RESET);
        }
    }

    public boolean hasGoblinKey() { return goblinKey; }
    public boolean hasSkeletonKey() { return skeletonKey; }
    public boolean hasVampireKey() { return vampireKey; }

    public void obtainGoblinKey() { goblinKey = true; }
    public void obtainSkeletonKey() { skeletonKey = true; }
    public void obtainVampireKey() { vampireKey = true; }

    public boolean hasAllKeys()
    {
        return goblinKey && skeletonKey && vampireKey;
    }

    public void resetKeys()
    {
        goblinKey = false;
        skeletonKey = false;
        vampireKey = false;
    }

    public void setHealth(int hp)
    {
        this.hp = Math.min(hp, maxHP);
    }

    public void setMana(int mp)
    {
        this.mp = Math.min(mp, maxMP);
    }

    public int getXP()
    {
        return xp;
    }
}