#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging

from django.contrib import auth
from rest_framework import serializers
from rest_framework_jwt.settings import api_settings
from rest_framework_jwt.serializers import JSONWebTokenSerializer

from common.accounts.models import (Users, Accounts, Enterprise, Roles,
                                    UserRoles, Tags, UserTags)
from common.utils.str_utils import name_maker
from common.utils.exceptions import ValidationError

logger = logging.getLogger('')
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER


class CustomJWTSerializer(JSONWebTokenSerializer):
    username = serializers.CharField(max_length=64, required=True)
    password = serializers.CharField(max_length=128,
                                     required=True,
                                     style={'input_type': 'password'})

    def validate(self, attrs):
        account = auth.authenticate(username=attrs['username'],
                                    password=attrs['password'])
        if account is None:
            msg = 'Auth failed.'
            raise serializers.ValidationError(msg)
        payload = jwt_payload_handler(account)

        attrs['token'] = jwt_encode_handler(payload)
        attrs['user'] = account
        return attrs


class JWTSerializer(serializers.Serializer):
    token = serializers.CharField(max_length=255, help_text="token")


class LogoutSerializer(serializers.Serializer):
    pass


class AccountUpdateSerializer(serializers.ModelSerializer):
    old_password = serializers.CharField(write_only=True)
    password = serializers.CharField(write_only=True)

    class Meta:
        model = Accounts
        fields = ('old_password', 'password')

    def update(self, instance, validated_data):
        if not instance.check_password(validated_data['old_password']):
            raise ValidationError('旧密码不对！')
        instance.set_password(validated_data['password'])
        instance.save()
        return instance


class AccountSerializer(serializers.ModelSerializer):
    account_id = serializers.PrimaryKeyRelatedField(source='id',
                                                    read_only=True)
    password = serializers.CharField(write_only=True)
    certification_status = serializers.BooleanField()
    account_type = serializers.CharField(max_length=32)

    class Meta:
        model = Accounts
        fields = ('username', 'password', 'certification_status',
                  'account_type', 'account_id')

    def create(self, validated_data):
        logger.debug('users_roles validated_data: %s', validated_data)
        validated_data['username'] = self.get_username()
        account = super(AccountSerializer, self).create(validated_data)
        account.set_password(validated_data['password'])
        account.save()
        return account

    @staticmethod
    def get_username():
        return name_maker(prefix='usr')


class EnterpriseSerializer(serializers.ModelSerializer):
    class Meta:
        model = Enterprise
        fields = ('name', 'enterprise_id', 'logo', 'address', 'adcode',
                  'longitude', 'latitude', 'is_admin')


class UsersLCSerializer(serializers.ModelSerializer):
    account = AccountSerializer()
    id = serializers.IntegerField(read_only=True)

    class Meta:
        model = Users
        fields = ('id', 'nickname', 'wechat', 'phone', 'email', 'account')

    def create(self, validated_data):
        logger.debug('account validated_data: %s', validated_data)
        account_data = validated_data.pop('account')
        user_serializer = AccountSerializer(data=account_data)
        account = user_serializer.create(account_data)
        validated_data['account'] = account
        account = super(UsersLCSerializer, self).create(validated_data)
        return account

    def validate(self, attrs):
        exit_nickname = Users.objects.filter(
            nickname=attrs.get("nickname")).first()
        if exit_nickname is not None:
            raise ValidationError("用户名重复")
        return attrs


class UsersRUDSerializer(serializers.ModelSerializer):
    user = AccountSerializer(read_only=True)
    user_role = serializers.IntegerField()

    class Meta:
        model = Users
        fields = ('user', 'nickname', 'user_role')


class RoleLCSerializer(serializers.ModelSerializer):
    id = serializers.IntegerField(read_only=True, help_text="角色id")
    name = serializers.CharField(help_text="角色名称")
    kind = serializers.CharField(read_only=True, help_text="角色类型")
    kind_id = serializers.CharField(read_only=True, help_text="角色类型id")
    comments = serializers.CharField(default="", help_text="角色描述")

    class Meta:
        model = Roles
        fields = ("id", "name", "kind", "kind_id", "comments")

    def validate(self, attrs):
        view = self.context.get("view")
        role_id = self.context.get("role_id")
        attrs["kind_id"] = view.enterprise_id
        attrs["kind"] = "enterprise"
        if len(attrs["comments"]) > 256:
            raise ValidationError("角色描述超过最大字符长度限制")
        validate_obj = view.get_queryset()
        name_validate = validate_obj.filter(name=attrs["name"])
        if role_id:
            name_validate = name_validate.exclude(id=role_id)
        if name_validate:
            raise ValidationError("角色名称重复")
        return attrs


class UserRolesLCSerializer(serializers.ModelSerializer):
    role_name = serializers.SerializerMethodField(read_only=True,
                                                  help_text="角色名称")
    kind_id = serializers.SerializerMethodField(read_only=True,
                                                help_text="角色范围id")
    kind = serializers.SerializerMethodField(read_only=True, help_text="角色范围")

    class Meta:
        model = UserRoles
        fields = ("user", "role", "role_name", "kind", "kind_id")

    def validate(self, attrs):
        exit_user_role_relate = UserRoles.objects.filter(
            user=attrs.get("user"), role=attrs.get("role"))
        if exit_user_role_relate:
            raise ValidationError("用户角色已存在")
        return attrs

    def get_role_name(self, instance):
        return instance.role.name

    def get_kind(self, instance):
        return instance.role.kind

    def get_kind_id(self, instance):
        return instance.role.kind_id


class UserRolesMultiCSerializer(serializers.Serializer):
    role_ids = serializers.ListField()

    def validate(self, attrs):
        return attrs


class TagsLCSerializer(serializers.ModelSerializer):
    name = serializers.CharField(max_length=64, help_text='用户标签')
    id = serializers.IntegerField(read_only=True, help_text='用户标签id')

    def validate(self, attrs):
        exist_tags = Tags.objects.filter(name=attrs["name"])
        if exist_tags:
            raise ValidationError("用户标签已存在")
        return attrs

    class Meta:
        model = Tags
        fields = ("name", "id")


class TagsRSerializer(serializers.ModelSerializer):
    name = serializers.CharField(max_length=64, help_text='用户标签')
    id = serializers.IntegerField(read_only=True, help_text='用户标签id')

    def validate(self, attrs):
        tag_id = self.context.get("tag_id")
        exist_tags = Tags.objects.filter(name=attrs["name"]).exclude(id=tag_id)
        if exist_tags:
            raise ValidationError("用户标签已存在")
        attrs["id"] = tag_id
        return attrs

    class Meta:
        model = Tags
        fields = ("name", "id")


class UserTagsLCSerializer(serializers.ModelSerializer):
    user_id = serializers.IntegerField(help_text='用户id')
    tag_id = serializers.IntegerField(help_text='标签id')
    tag_name = serializers.StringRelatedField(source='tag.name',
                                              help_text='标签名称',
                                              read_only=True)

    class Meta:
        model = UserTags
        fields = ("user_id", "tag_id", "tag_name")

    def validate(self, attrs):
        user_id = self.context.get("user_id")
        attrs["user_id"] = user_id
        if UserTags.objects.filter(user_id=user_id, tag_id=attrs["tag_id"]):
            raise ValidationError("关系已存在")
        return attrs


class UserTagsMultiCSerializer(serializers.Serializer):
    tag_ids = serializers.ListField()

    def validate(self, attrs):
        return attrs

    class Meta:
        fields = ("tag_ids")
