# coding: utf-8
import math
import time
import re
from rpc.tool.log_tool import user_transfer_logger
from multiprocessing import Manager
from django.core.management.base import BaseCommand
from django.contrib.auth.models import User
from django.db.models import Q, Max
from gm_types.gaia import LOGIN_AUTH_TYPE, USER_ACCOUNT_TYPE
from threadpool import ThreadPool, makeRequests
from api.models.user import UserExtra, PlatformUser
from api.models.person import Person


task_pool = ThreadPool(num_workers=4, poll_timeout=2)

queue = Manager().Queue(maxsize=4)
queue.put(1)  # 触发程序开始
args_list = []


def judge_third_user_id(auth_user_id):
    try:
        if re.match(r'^\d{11}$', str(auth_user_id)):            #手机号
            return None

        if re.search(r'^\d{11}_phone_([a-zA-Z0-9])*$', str(auth_user_id)):    #特殊格式
            return None

        # if str(auth_user_id).startswith('wechat'):              #微信私信
        #     return USER_ACCOUNT_TYPE.WECHAT_PUB

        if str(auth_user_id).startswith('onhoFt'):              #微信
            return USER_ACCOUNT_TYPE.WECHAT

        if str(auth_user_id).startswith('owncIu'):              #微信小程序
            return USER_ACCOUNT_TYPE.WECHAT

        if re.match(r'^([A-Z0-9]){32}$', str(auth_user_id)):    #QQ
            return USER_ACCOUNT_TYPE.QQ

        else:
            user_transfer_logger.info(msg='auth_user_id=={auth_user_id} is not Distinguish'.format(auth_user_id=auth_user_id))
            return 16
    except:
        user_transfer_logger.info(msg='auth_user_id=={auth_user_id} is failed'.format(auth_user_id=str(auth_user_id)))
        return 16


def generate(t_args):
    queue = t_args.get("queue")
    extra_id = t_args.get("id")

    start_id = queue.get()
    limit = 200
    extra = UserExtra.objects.filter(Q(pk__gt=start_id, id__gt=extra_id))[: limit].\
                                        values('user_id', 'auth_type')
    max_id = extra.aggregate(max_id=Max('id'))

    queue.put(max_id["max_id"])

    user_ids, p_users = [], {}
    for extra_item in extra:
        user_ids.append(extra_item.get('user_id'))
        e_type = extra_item.get('auth_type')
        if e_type == LOGIN_AUTH_TYPE.COUPON:
            e_type = LOGIN_AUTH_TYPE.phone

        if e_type == LOGIN_AUTH_TYPE.WechatSmall:
            e_type = LOGIN_AUTH_TYPE.Wechat
        p_users[extra_item.get('user_id')] = {'user_id': extra_item.get('user_id'), 'platform_type': e_type}
    user_ids = Person.objects.filter(user_id__in=user_ids, is_puppet=False).values_list('user_id', flat=True)
    users = User.objects.filter(id__in=user_ids, is_staff=False, is_superuser=False).values('id', 'username')

    for user in users:
        if user.get("is_staff") or user.get("is_superuser"):
            continue

        _temp = p_users.get(user.get('id'))

        if _temp:
            p_users[user.get('id')].update({'platform_id': user.get('username')})

        if str(user.get('username')).startswith('wechat'):  # 微信私信去掉wechat
            user['username'] = str(user.get('username')).replace('wechat', '')
            _temp['platform_type'] = USER_ACCOUNT_TYPE.WECHAT_PUB

        if not _temp.get('platform_type'):
            user_name = judge_third_user_id(user.get('username'))

            if re.search(r'^\w+@(\w+.)+(com|cn|net)$', str(user.get('username'))):   #邮箱暂不迁移 会更改person email字段
                try:
                    email_person = Person.objects.get(user_id=user.get('id'))
                    if not email_person.email:
                        email_person.email = str(user.get('username'))
                        email_person.save()
                    else:
                        user_transfer_logger.info(msg='auth_user_id=={auth_user_id} has email'.format(
                                                  auth_user_id=str(user.get('username'))))
                    continue
                except:
                    user_transfer_logger.info(
                        msg='auth_user_id=={auth_user_id} modify email failed'.format(auth_user_id=str(user.get('username'))))
                    continue

            if not user_name:
                continue

            elif user_name == 16:
                continue
            else:
                _temp['platform_type'] = user_name

    platform_users = []
    for p_user in p_users:
        if p_users[p_user].get('platform_type') == LOGIN_AUTH_TYPE.phone:
            continue
        if not p_users[p_user].get('platform_type'):
            continue
        platform_users.append(PlatformUser(user_id=p_user, platform_id=p_users[p_user].get('platform_id'),
                                           platform_type=p_users[p_user].get('platform_type')))

    PlatformUser.objects.bulk_create(platform_users)
    print("this thread max_id=", max_id.get('max_id'))


class Command(BaseCommand):

    def add_arguments(self, parser):
        parser.add_argument('user_id', nargs='?', type=int)

    def handle(self, *args, **options):
        extra_id = options.get('user_id') or 1

        print('------ starting -----')
        start_time = time.time()
        print("start at: ", start_time)
        per_num = 200
        count = UserExtra.objects.filter(id__gt=extra_id).count()
        cnt = int(math.ceil(count / per_num))
        for _ in range(cnt):
            #generate({"queue": queue, "id": extra_id})
            args_list.append({"queue": queue, "id": extra_id})

        print("len====", len(args_list))
        temp = makeRequests(generate, args_list=args_list)
        [task_pool.putRequest(req) for req in temp]
        task_pool.wait()

        end_time = time.time()
        last_user_id = queue.get()
        print("last_user_id", last_user_id)
        user_transfer_logger.info(msg='end:last_user_id=={last_user_id}'.format(last_user_id=last_user_id))
        print("end at: ", end_time)
        print('total use {} s.'.format(end_time - start_time))
        print('Done!')