#!/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 django.db.models import F

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

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)
    username = serializers.CharField(max_length=64)
    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):
        validated_data['username'] = validated_data['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', 'file', 'is_admin')


class UsersCommonSerializer(serializers.ModelSerializer):
    class Meta:
        model = Users
        fields = ('id', 'nickname')


class UsersLCSerializer(serializers.ModelSerializer):
    account = AccountSerializer()
    id = serializers.IntegerField(read_only=True)
    role_ids = serializers.ListField(required=False, help_text="角色id列表")
    tag_ids = serializers.ListField(required=False, help_text="标签id列表")
    organization_ids = serializers.ListField(required=False,
                                             help_text="组织id列表")

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

    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):
        username = attrs["account"].get("username", name_maker(prefix='usr'))
        email = attrs.get("email")
        phone = attrs.get("phone")
        user_service.user_info_validate(username, email, phone)
        if attrs.get("role_ids"):
            del attrs["role_ids"]
        if attrs.get("tag_ids"):
            del attrs["tag_ids"]
        if attrs.get("organization_ids"):
            del attrs["organization_ids"]
        return attrs


class UsersUSerializer(serializers.ModelSerializer):
    account = AccountSerializer()
    id = serializers.IntegerField(read_only=True)
    role_ids = serializers.ListField(required=False, help_text="角色id列表")
    tag_ids = serializers.ListField(required=False, help_text="标签id列表")
    organization_ids = serializers.ListField(required=False,
                                             help_text="组织id列表")

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

    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(UsersUSerializer, 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("用户名重复")
        if attrs.get("role_ids"):
            del attrs["role_ids"]
        if attrs.get("tag_ids"):
            del attrs["tag_ids"]
        if attrs.get("organization_ids"):
            del attrs["organization_ids"]
        return attrs


class UsersRSerializer(serializers.ModelSerializer):
    account = AccountSerializer()
    id = serializers.IntegerField(read_only=True)
    roles = serializers.SerializerMethodField(required=False, help_text="角色列表")
    tags = serializers.SerializerMethodField(required=False, help_text="标签列表")
    organizations = serializers.SerializerMethodField(required=False,
                                                      help_text="组织列表")

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

    def get_roles(self, instance):
        dt = UserRoles.objects.filter(user_id=instance.id).values(
            "role_id", name=F("role__name"))
        return dt

    def get_tags(self, instance):
        return UserTags.objects.filter(user_id=instance.id).values(
            "tag_id", name=F("tag__name"))

    def get_organizations(self, instance):
        return UserOrganizations.objects.filter(user_id=instance.id).values(
            "organization_id", name=F("organization__name"))


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="",
                                     allow_blank=True,
                                     allow_null=True,
                                     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")


class SimpleUserSerializer(serializers.Serializer):
    id = serializers.IntegerField(help_text="用户id")
    name = serializers.CharField(max_length=64, help_text=u'用户名称')


class TagUsersLSerializer(serializers.Serializer):
    id = serializers.IntegerField(help_text="标签id")
    name = serializers.CharField(max_length=64, help_text=u'标签名称')
    users = SimpleUserSerializer(many=True, required=False)


class RolePermsSerializer(serializers.Serializer):
    perms_codes = serializers.ListField(required=True)


class UserCSerializer(serializers.Serializer):
    username = serializers.CharField(max_length=150, help_text="账号")
    password = serializers.CharField(max_length=64, help_text="密码")
    nickname = serializers.CharField(max_length=64, help_text="名字")
    email = serializers.EmailField(max_length=64, help_text="邮箱")
    phone = PhoneField(required=False, help_text="手机号")
    wechat = serializers.CharField(max_length=64, required=False, allow_null=True, allow_blank=True, help_text="微信")
    gender = serializers.ChoiceField(choices=(0, 1, None), help_text="性别")
    head_img = serializers.CharField(max_length=256, required=False, allow_null=True, allow_blank=True, help_text="头像")
    cert = serializers.ChoiceField(choices=(1, 2, 3, 4, 5, 6, None), help_text="证件类型")
    cert_number = serializers.CharField(required=False, max_length=64, allow_null=True,
                                        allow_blank=True, help_text="证件号码")
    join_date = serializers.DateField(required=False, allow_null=True, help_text="入职日期")
    role_ids = serializers.ListField(required=False, allow_null=True, help_text="角色id列表")
    tag_ids = serializers.ListField(required=False, allow_null=True, help_text="标签id列表")
    organization_ids = serializers.ListField(required=False, allow_null=True, help_text="组织id列表")
    type = serializers.CharField(required=False, allow_null=True, allow_blank=True, help_text="创建类型")


class UserUSerializer(serializers.Serializer):
    username = serializers.CharField(max_length=150, help_text="账号")
    nickname = serializers.CharField(max_length=64, help_text="名字")
    email = serializers.EmailField(required=False, allow_null=True, allow_blank=True, max_length=64, help_text="邮箱")
    phone = PhoneField(required=False, allow_null=True, allow_blank=True, help_text="手机号")
    wechat = serializers.CharField(max_length=64, required=False, allow_null=True, allow_blank=True, help_text="微信")
    gender = serializers.ChoiceField(choices=(0, 1, None), help_text="性别")
    head_img = serializers.CharField(max_length=256, required=False, allow_null=True, allow_blank=True, help_text="头像")
    cert = serializers.ChoiceField(choices=(1, 2, 3, 4, 5, 6, None), help_text="证件类型")
    cert_number = serializers.CharField(required=False, max_length=64, allow_null=True,
                                        allow_blank=True, help_text="证件号码")
    join_date = serializers.DateField(allow_null=True, help_text="入职日期")
    role_ids = serializers.ListField(required=False, allow_null=True, help_text="角色id列表")
    tag_ids = serializers.ListField(required=False, allow_null=True, help_text="标签id列表")
    organization_ids = serializers.ListField(required=False, allow_null=True, help_text="组织id列表")
    status = serializers.ChoiceField(default=1, choices=(1, 2), help_text="用户状态")


class UserCenterUSerializer(serializers.Serializer):
    username = serializers.CharField(max_length=150, help_text="账号")
    nickname = serializers.CharField(max_length=64, help_text="名字")
    email = serializers.EmailField(required=False, allow_null=True, allow_blank=True, max_length=64, help_text="邮箱")
    phone = PhoneField(required=False, allow_null=True, allow_blank=True, help_text="手机号")
    wechat = serializers.CharField(max_length=64, required=False, allow_null=True, allow_blank=True, help_text="微信")
    gender = serializers.ChoiceField(choices=(0, 1, None), help_text="性别")
    head_img = serializers.CharField(max_length=256, required=False, allow_null=True, allow_blank=True, help_text="头像")


class UserPasswordSerializer(serializers.Serializer):
    password = serializers.CharField(max_length=64, help_text="密码")
