from marshmallow import Schema, fields, validate

chartype_field = fields.String(
    required=True,
    validate=validate.OneOf(["human", "humanoid", "mutant", "cyborg"]),
    description='The characters type of being'
)

conscore_field = fields.Integer(
    required=True,
    default=10,
    validate=validate.Range(min=3, max=18),
    description='The constitution score of the character'
)


class MutationSchema(Schema):
    conscore = conscore_field
    intscore = fields.Integer(
        required=True,
        validate=validate.Range(min=3, max=18),
        description='The characters intelligence score'
    )


class HPSchema(Schema):
    chartype = chartype_field
    conscore = conscore_field


class DiceSchema(Schema):
    quantity = fields.Int(
        required=True,
        default=1,
        validate=validate.Range(min=1),
        description='The number of dice to roll'
    )
    geometry = fields.Int(
        required=True,
        default=2,
        validate=validate.Range(min=2),
        description='The number of sides on each die'
    )
    discard_lowest = fields.Bool(required=True, default=False, description='Drop the lowest score')


class CharacterSchema(Schema):
    chartype = chartype_field


class AbilitySchema(Schema):
    chartype = chartype_field
    ability = fields.String(
        required=False,
        default="generic",
        validate=validate.OneOf(
            ["m-strength", "p-strength", "intelligence", "charisma", "constitution", "dexterity", "all"]),
        description='One of the six character attributes from the character sheet'
    )


class CheckSchema(Schema):
    ability_score = fields.Integer(
        required=True,
        default=10,
        validate=validate.Range(min=3, max=21),
        description='The score of the ability to be checked against'
    )
    multiplier = fields.Integer(
        required=True,
        default=4,
        validate=validate.Range(min=2, max=8),
        description='Sets the threshold for the check. In general, the higher the multiplier, the higher the '
                    'likelihood of success. Range: 2 - 7'
    )


class EncounterSchema(Schema):
    terrain = fields.String(
        required=True,
        default="clear",
        validate=validate.OneOf(["clear", "mountains", "forest", "desert", "watery", "ruins", "deathlands"]),
        description='The terrain traversed at the time of the encounter roll'
    )


class MentalAttackSchema(Schema):
    ams = fields.Integer(
        required=True,
        validate=validate.Range(min=3, max=18),
        description='The Attackers Mental Strength'
    )
    dms = fields.Integer(
        required=True,
        validate=validate.Range(min=3, max=18),
        description='The Defenders Mental Strength'
    )
    modifier = fields.Integer(
        required=False,
        default=0,
        validate=validate.Range(min=-100, max=100),
        description='Roll modifier for mental attack'
    )
