"""A collection of monsters. Also useful for building a list of wild
shape forms.

"""

from abc import ABCMeta


from dungeonsheets.content import Creature
from dungeonsheets.spells import Spell


xp_by_challenge_rating = {
    0: 10,
    (1 / 8): 25,
    (1 / 4): 50,
    (1 / 2): 100,
    1: 200,
    2: 450,
    3: 700,
    4: 1100,
    5: 1800,
    6: 2300,
    7: 2900,
    8: 3900,
    9: 5000,
    10: 5900,
    11: 7200,
    12: 8400,
    13: 10000,
    14: 11500,
    15: 13000,
    16: 15000,
    17: 18000,
    18: 20000,
    19: 22000,
    20: 25000,
    21: 33000,
    22: 41000,
    23: 50000,
    24: 62000,
    25: 75000,
    26: 90000,
    27: 105000,
    28: 120000,
    29: 130000,
    30: 155000,
}


def challenge_rating_to_xp(cr):
    """Determine the XP awarded for slaying a monster with the given
    challenge rating *cr*.

    """
    xp = xp_by_challenge_rating[cr]
    return "{:,}".format(xp)


class SpellFactory(ABCMeta):
    """Meta class to resolve spell strings into the ``spells.Spell``.
    
    For classes using this metaclass, the *spell* attribute, if
    present, should be a list of spells that the entity knows. For
    each entry on that list, anything that is not already a spell
    class (so probably a string) will be resolved into the
    corresponding ``spells.Spell`` class.
    
    """
    def __init__(self, name, bases, attrs):
        for idx, spell in enumerate(self.spells):
            TheSpell = self._resolve_mechanic(spell, SuperClass=Spell)
            self.spells[idx] = TheSpell


class Monster(Creature, metaclass=SpellFactory):

    """A monster that may be encountered when adventuring."""

    name = "Generic Monster"
    description = ""
    challenge_rating = 0
    skills = "Perception +3, Stealth +4"
    damage_resistances = ""
    damage_immunities = ""
    damage_vulnerabilities = ""
    condition_immunities = ""
    saving_throws = ""
    # TODO: Consider refactoring stats.Speed to consider all of these
    # just like we do stats.Ability

    swim_speed = 0
    fly_speed = 0
    climb_speed = 0
    burrow_speed = 0
    hp_max = 10
    hit_dice = "1d6"
    spells = []

    def __init__(self):
        super(Monster, self).__init__()

    @property
    def is_beast(self):
        is_beast = "beast" in self.description.lower()
        return is_beast
