# barbacompta - invoicing for dummies
# Copyright (C) 2010-2020 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

from django.forms import ModelMultipleChoiceField, SelectMultiple
from taggit.managers import TaggableManager as UpstreamTaggableManager
from taggit.models import Tag


class TagWidget(SelectMultiple):
    template_name = 'tag_widget.html'

    class Media:
        '''Enable use of Select2 in template'''

        js = [
            'xstatic/jquery.js',
            'xstatic/jquery-ui.js',
            'xstatic/select2.js',
        ]
        css = {
            'all': ['xstatic/select2.css'],
        }


class TagField(ModelMultipleChoiceField):
    widget = TagWidget

    def prepare_value(self, value):
        if value is None:
            return value
        # TagManager returns Trough model and not the target model, we must adapt
        if hasattr(value, '__iter__') and not isinstance(value, str) and not hasattr(value, '_meta'):
            if value and hasattr(value[0], '_meta'):
                value = list(value.select_related('tag').values_list('tag__name', flat=True))
            return value
        return value.name

    def _check_values(self, value):
        return frozenset(value)


class TaggableManager(UpstreamTaggableManager):
    # Use our own field/widget pair based using Select2 and a MultipleChoiceField
    def formfield(self, form_class=TagField, **kwargs):
        kwargs.setdefault('queryset', Tag.objects.all())
        kwargs.setdefault('to_field_name', 'name')
        return super().formfield(form_class=form_class, **kwargs)
