# coding: utf-8


from django.db.models import F
from django.db.models.constants import LOOKUP_SEP

from idm.users.constants.user import USER_TYPES
from idm.users.models import User


class OrderingField(object):
    def __init__(self, lookup, name=None, descending=False):
        self.lookup = lookup
        self.name = name or lookup
        self.descending = descending

    def __str__(self):
        prefix = '-' if self.descending else ''
        return "{prefix}{lookup}".format(prefix=prefix, lookup=self.lookup)

    def __invert__(self):
        return self.__class__(
            lookup=self.lookup,
            name=self.name,
            descending=not self.descending,
        )

    def __repr__(self):
        args = [repr(self.lookup)]

        if self.lookup != self.name:
            args.append("name={}".format(repr(self.name)))

        if self.descending:
            args.append("descending={}".format(repr(self.descending)))

        return "SortingField({})".format(", ".join(args))

    def as_lookup(self):
        lookup = self.lookup
        if self.descending:
            lookup = lookup.desc()
        return lookup

    @classmethod
    def from_string(cls, value):
        descending = False
        if value[:1] == '-':
            descending = True
            lookup = value[1:]
        else:
            lookup = value

        parts = lookup.split(LOOKUP_SEP, 1)
        if len(parts) > 1:
            name = parts[0]
        else:
            name = lookup

        return cls(F(lookup), name=name, descending=descending)


class OrderingAlias(object):
    def __init__(self, *fields):
        self.fields = []
        for field in fields:
            if isinstance(field, OrderingField):
                self.fields.append(field)
            elif isinstance(field, str):
                self.fields.append(OrderingField.from_string(field))
            else:
                raise TypeError

    def __invert__(self):
        inverted_fields = [~f for f in self.fields]
        return self.__class__(*inverted_fields)

    def __repr__(self):
        return "SortingAlias({})".format(", ".join(map(repr, self.fields)))


def fix_user_field_filters(filters, user_fields):
    if filters and filters.get('user_type') in USER_TYPES.ALL_TYPES:
        user_type = filters['user_type']
        for user_field in user_fields:
            if filters.get(user_field):
                users = filters[user_field].split(',')
                fixed_users = [str(user) for user in users]
                filters[user_field] = ','.join(fixed_users)
