# -*- coding: utf-8 -*-

from dndtools import django_filters2
from dndtools.dnd.models import (
    Spell, DndEdition, SpellSchool, SpellSubSchool, SpellDescriptor, FeatCategory,
    CharacterClass, Rulebook, Domain, Feat, Skill, Item, Language, RaceType, ItemSlot,
    ItemProperty, Deity, Rule)
from dndtools.dnd.filters_fields import FeatMultiPrerequisiteFieldFilter


def rulebook_choices(unknown_entry=True):
    rulebook_choices = [
        (edition.name,
         [(rulebook.slug, rulebook.name)
          for rulebook in edition.rulebook_set.all()])
        for edition in DndEdition.objects.all()]
    if unknown_entry:
        rulebook_choices.insert(0, ('', 'Unknown'))

    return rulebook_choices


def edition_choices(unknown_entry=True):
    edition_choices = [(edition.slug, edition.name) for edition in
                       DndEdition.objects.all()]
    if unknown_entry:
        edition_choices.insert(0, ('', 'Unknown'))

    return edition_choices


def spell_level_choices():
    spell_level_choices = [(i, i) for i in range(0, 10)]

    return spell_level_choices


def character_class_choices():
    character_class_choices = [
        (clazz.slug, clazz.name) for clazz in CharacterClass.objects.all()
    ]
    character_class_choices.insert(0, ('', 'Unknown'))

    return character_class_choices


def character_class_casting_choices():
    character_class_choices = [
        (clazz.slug, clazz.name) for clazz in
        CharacterClass.objects.filter(spellclasslevel__id__isnull=False).distinct()
    ]
    character_class_choices.insert(0, ('', 'Unknown'))

    return character_class_choices


def domain_choices():
    domain_choices = [
        (domain.slug, domain.name) for domain in Domain.objects.all()
    ]
    domain_choices.insert(0, ('', 'Unknown'))

    return domain_choices


class SpellFilter(django_filters2.FilterSet):
    school_choices = [(school.slug, school.name)
                      for school in SpellSchool.objects.all()]
    school_choices.insert(0, ('', 'Unknown'))

    sub_school_choices = [(sub_school.slug, sub_school.name)
                          for sub_school in SpellSubSchool.objects.all()]
    sub_school_choices.insert(0, ('', 'Unknown'))

    descriptor_choices = [(descriptor.slug, descriptor.name)
                          for descriptor in SpellDescriptor.objects.all()]
    descriptor_choices.insert(0, ('', 'Unknown'))

    name = django_filters2.CharFilter(
        lookup_type='icontains', label='Spell name'
    )
    # noinspection PyShadowingBuiltins
    range = django_filters2.CharFilter(
        lookup_type='icontains',
    )
    casting_time = django_filters2.CharFilter(
        lookup_type='icontains',
    )
    spell_resistance = django_filters2.CharFilter(
        lookup_type='icontains',
    )
    area = django_filters2.CharFilter(
        lookup_type='icontains'
    )
    duration = django_filters2.CharFilter(
        lookup_type='icontains'
    )
    saving_throw = django_filters2.CharFilter(
        lookup_type='icontains'
    )

    school__slug = django_filters2.ChoiceFilter(
        choices=school_choices, label='School'
    )
    sub_school__slug = django_filters2.ChoiceFilter(
        choices=sub_school_choices, label='Sub-school'
    )
    descriptors__slug = django_filters2.ChoiceFilter(
        choices=descriptor_choices, label='Descriptor'
    )
    verbal_component = django_filters2.BooleanFilter()
    somatic_component = django_filters2.BooleanFilter()
    material_component = django_filters2.BooleanFilter()
    arcane_focus_component = django_filters2.BooleanFilter()
    divine_focus_component = django_filters2.BooleanFilter()
    xp_component = django_filters2.BooleanFilter()

    rulebook__dnd_edition__slug = django_filters2.MultipleChoiceFilter(
        choices=edition_choices(unknown_entry=False),
        label='Edition',
    )
    rulebook__slug = django_filters2.ChoiceFilter(
        label='Rulebook', choices=rulebook_choices()
    )
    description = django_filters2.CharFilter(
        lookup_type='icontains',
    )
    class_levels__slug = django_filters2.ChoiceFilter(
        choices=character_class_casting_choices(),
        help_text='Shows only classes with own spell lists',
        label='Class',
        grouped=True,
    )
    spellclasslevel__level = django_filters2.MultipleChoiceFilter(
        choices=spell_level_choices(),
        label='Level for class',
        help_text='Use ctrl to select more levels!',
        grouped=True,
    )
    domain_levels__slug = django_filters2.ChoiceFilter(
        choices=domain_choices(),
        label='Domain',
        grouped=True,
    )
    spelldomainlevel__level = django_filters2.MultipleChoiceFilter(
        choices=spell_level_choices(),
        label='Level for domain',
        help_text='Use ctrl to select more levels!',
        grouped=True,
    )

    class Meta:
        model = Spell
        fields = [
            'name', 'range', 'spell_resistance', 'area', 'duration', 'saving_throw', 'casting_time',
            'school__slug', 'sub_school__slug', 'descriptors__slug',
            'verbal_component', 'somatic_component', 'material_component',
            'arcane_focus_component', 'divine_focus_component',
            'xp_component', 'rulebook__slug', 'rulebook__dnd_edition__slug', 'description',
            'class_levels__slug', 'spellclasslevel__level',
            'domain_levels__slug', 'spelldomainlevel__level', ]


class SpellFilterAdmin(SpellFilter):
    verified = django_filters2.BooleanFilter(
    )

    class Meta:
        model = SpellFilter.Meta.model
        fields = ['verified', ] + SpellFilter.Meta.fields


class ItemFilter(django_filters2.FilterSet):
    type_choices = [itemType for itemType in Item.ITEM_TYPE]
    type_choices.insert(0, ('', 'Unknown'))

    item_slot_choices = [
        (itemSlot.slug, itemSlot.name) for itemSlot in
        ItemSlot.objects.all()
    ]
    item_slot_choices.insert(0, ('', 'Unknown'))

    property_choices = [
        (property.slug, property.name) for property in ItemProperty.objects.all()
    ]

    name = django_filters2.CharFilter(
        lookup_type='icontains', label='Item name'
    )
    rulebook__dnd_edition__slug = django_filters2.MultipleChoiceFilter(
        choices=edition_choices(unknown_entry=False),
        label='Edition',