from collections.abc import Iterable

from django import forms
import sform

from staff.preprofile.models.hardware_profile import HardwareProfile


class MultipleServicesSuggestField(sform.MultipleSuggestField):
    @property
    def type_name(self):
        return sform.MultipleSuggestField.__name__.lower()[:-5]

    def structure_as_dict(self, *args, **kwargs):
        field_dict = super().structure_as_dict(*args, **kwargs)
        field_dict['types'] = ['services']
        return field_dict

    def clean(self, new_value, old_value, required, trim_on_empty, base_initial, base_data):
        if isinstance(new_value, Iterable):
            if all(isinstance(it, str) for it in new_value):
                new_value = [it.lower() for it in new_value]

        return super().clean(new_value, old_value, required, trim_on_empty, base_initial, base_data)


class HardwareChoiceField(sform.ModelChoiceField):
    def __init__(self, *args, **kwargs):
        def extractor(obj):
            return {
                'name': obj.name,
                'comment': obj.comment
            }

        super(HardwareChoiceField, self).__init__(
            queryset=HardwareProfile.objects.none(),
            label_extractor=extractor,
            empty_label='—',
        )

    @property
    def type_name(self):
        return sform.ModelChoiceField.__name__.lower()[:-5]

    def get_dj_field(self, required=False):
        return forms.ModelChoiceField(
            queryset=HardwareProfile.objects.all(),
            required=False,
            **self.kwargs
        )

    def structure_as_dict(self, *args, **kwargs):
        action_context = kwargs['base_initial'].get('action_context')
        if action_context and action_context.preprofile:
            department_url = action_context.preprofile.department.url
            self.queryset = HardwareProfile.objects.filter(departments__url=department_url)

        field_dict = super(HardwareChoiceField, self).structure_as_dict(*args, **kwargs)
        field_dict['choices'] = [
            {
                'value': choice['value'],
                'label': choice['label']['name'] if type(choice['label']) == dict else choice['label'],
                'meta': choice['label']['comment'] if type(choice['label']) == dict else '',
            }
            for choice in field_dict['choices']
        ]

        return field_dict
