# coding: utf-8

import logging

from django.conf import settings
from django.utils.translation import get_language, gettext_lazy as _
from rest_framework.exceptions import ValidationError

from procu.api import models
from procu.api.common.fields import TrackerChoiceField
from procu.api.utils import maybe_fetch_users
from procu.rest import serializers

logger = logging.getLogger(__name__)


class Geo(serializers.Serializer):

    lat = serializers.FloatField(required=False, min_value=-90., max_value=90.)
    lon = serializers.FloatField(
        required=False, min_value=-180., max_value=180.
    )

    class Meta:
        fields = ('lat', 'lon')


class List(serializers.ModelSerializer):
    class Meta:
        model = models.Address
        fields = ('id', 'label', 'text', 'tracker_location')


class FullName(serializers.CharField):
    def to_representation(self, value):

        if isinstance(value, dict):
            return value.get(get_language(), '')
        else:
            return value

    def to_internal_value(self, value):
        return {'ru': value, 'en': value}


class StaffUser(serializers.CharField):
    def __init__(self, *args, **kwargs):
        self.user_fields = kwargs.pop('user_fields', [])
        kwargs['max_length'] = 255
        kwargs['allow_blank'] = True
        kwargs['allow_null'] = True
        super().__init__(*args, **kwargs)

    def to_internal_value(self, value):

        if not value:
            return None

        users = maybe_fetch_users([value], self.user_fields)

        if users is None:
            raise ValidationError(
                _('ADDRESS_CONTACT::ERROR_STAFF_LOOKUP_FAILED')
            )

        if not users:
            raise ValidationError(
                _('ADDRESS_CONTACT::ERROR_USERNAME_NOT_FOUND')
            )

        return users[0]


class ContactSerializer(serializers.Serializer):

    username = StaffUser(
        user_fields=('login', 'name', 'phones.number'),
        required=False,
        label=_('ADDRESS_CONTACT::YANDEX_USERNAME'),
    )
    name = FullName(
        max_length=255, required=False, label=_('ADDRESS_CONTACT::NAME')
    )
    is_staff_phone = serializers.BooleanField(
        required=False, label=_('ADDRESS_CONTACT::IS_STAFF_PHONE')
    )
    phone = serializers.CharField(
        max_length=255,
        required=False,
        allow_blank=True,
        label=_('ADDRESS_CONTACT::PHONE'),
    )

    class Meta:
        fields = ('username', 'name', 'is_staff_phone', 'phone')

    def validate(self, data):

        user = data.pop('username', None)

        if user is not None:
            data['is_staff_phone'] = data.get('is_staff_phone', True)

            data['name'] = {
                lang: '{} {}'.format(
                    user['name']['first'][lang], user['name']['last'][lang]
                )
                for lang in ('en', 'ru')
            }

            if data['is_staff_phone'] and user['phones']:
                data['phone'] = user['phones'][0]['number']

            data['username'] = user['login']

        else:
            if 'name' not in data:
                raise ValidationError(
                    {
                        'username': _(
                            'ADDRESS_CONTACT::ERROR_NAME_OR_USERNAME_REQUIRED'
                        )
                    }
                )

            data['is_staff_phone'] = False
            data['username'] = None

        data['phone'] = data.get('phone', '')

        return data


class CreateRetrieveUpdate(serializers.ModelSerializer):
    check_for_nested_writes = False

    label = serializers.CharField(max_length=255, allow_blank=False)
    contacts = ContactSerializer(many=True, required=False)
    tracker_location = TrackerChoiceField(
        max_length=31,
        allow_blank=True,
        required=False,
        field=settings.WAREHOUSE_LOC_FIELD,
    )
    tracker_components = serializers.ListField(
        child=serializers.CharField(), allow_empty=True, required=False
    )
    geo = Geo(allow_null=True)

    class Meta:
        model = models.Address
        fields = (
            'id',
            'text',
            'label',
            'tracker_location',
            'tracker_components',
            'contacts',
            'comment',
            'geo',
            'is_deleted',
        )
        extra_kwargs = {'is_deleted': {'label': _('ADDRESS::IS_DELETED')}}


# Legacy Version
class AddressSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Address
        fields = ('id', 'label', 'text', 'is_deleted')
