# coding=utf-8
from django.db import IntegrityError
from django.db.models import Q

from rpc.decorators import bind_context, bind
from rpc.exceptions import RPCIntegrityError, RPCNotFoundException, \
    GaiaRPCFaultException
from rpc.tool.dict_mixin import to_dict
from rpc.tool.error_code import gen
from rpc.tool.log_tool import info_logger
from ..models import Team, User
from hippo.models import Doctor
from gm_types.gaia import TEAM_TYPE
from gm_types.error import ERROR

uri_pre = 'gaia/themis/team'


@bind_context(uri_pre + '/get')
def team_get(ctx, team_id):
    try:
        team = Team.objects.get(id=team_id)
    except:
        raise RPCNotFoundException
    team_data = to_dict(team)
    team_data['parent_team_id'] = team.parent_team_id
    team_data['child_team'] = [
        {
            'id': obj.id,
            'name': obj.name,
        } for obj in team.subteams.all()
    ]
    team_data['all_parent_team'] = [
        {
            'id': obj.id,
            'name': obj.name,
        } for obj in team.parents
    ]
    return team_data


@bind(uri_pre + '/rteams')
def recursive_teams(user_id):
    teams = User.objects.get(id=user_id).teams.all()
    children = sum([list(x.all_children_team) + [x] for x in teams], [])
    return list(set([x.id for x in children]))


@bind(uri_pre + '/rusers')
def recursive_users(user_id):
    teams = User.objects.get(id=user_id).teams.all()
    users = sum([list(x.all_children_user) for x in teams], [])
    return list(set([x.id for x in users] + [user_id]))


@bind_context(uri_pre + '/delete')
def team_delete(ctx, team_id):
    team = Team.objects.get(id=team_id)
    delete_team = team.all_children_team
    delete_team.append(team)
    if Doctor.objects.filter(business_group__in=[x.id for x in delete_team]).exists():
        return gen(ERROR.UNIVERSAL)
    for obj in delete_team:
        obj.delete()


@bind_context(uri_pre + '/edit')
def team_edit(ctx, team_id, team_info):
    team_user = map(int, team_info.pop('team_user'))
    if team_id:
        try:
            team = Team.objects.get(id=team_id)
        except:
            info_logger.info(__import__('traceback').format_exc())
            raise RPCNotFoundException
    else:
        team = None

    if not team or team.name != team_info['name']:
        if Team.objects.filter(name=team_info['name']).exists():
            return {
                'error': 1,
                'team_id': team_id,
            }

    line_team = []
    parent_id = int(team_info['parent_team_id'] or 0)
    if parent_id:
        parent_team = Team.objects.get(id=parent_id)
        parents = parent_team.parents
        parents.append(parent_team)
        line_team += parents

    if team:
        line_team += team.all_children_team
        children_team_ids = [obj.id for obj in team.all_children_team]
        if parent_id == team.id or parent_id in children_team_ids:
            return {
                'error': 3,
                'team_id': team_id
            }

    if team is None:
        try:
            team = Team.objects.create(**team_info)
        except IntegrityError:
            raise RPCIntegrityError
    else:
        old_users = [x.id for x in team.team_user.all()]
        deleted = set(old_users) - set(team_user)
        if deleted:
            doctors = Doctor.objects.filter(business_partener__in=deleted)
            if team.id in [x.business_group for x in doctors]:
                return {
                    'error': 2,
                    'deleted': list(deleted),
                }
        for k, v in team_info.iteritems():
            setattr(team, k, v)
        team.save()

    team.team_user = team_user

    for children in team.all_children_team:
        if children.team_type != team.team_type:
            children.team_type = team.team_type
            children.save()

    return {
        'error': 0,
        'team_id': team.id,
    }


@bind(uri_pre + '/info')
def get_bd_team_info(user_id):
    user = User.objects.get(id=user_id)
    teams = user.teams.all()
    children = sum([list(x.all_leaf_children) for x in teams], [])
    return {
        'is_bdm': bool(children),
        'username': user.username,
        'teams': [{
            'name': x.name,
            'id': x.id
        } for x in children],
    }


@bind(uri_pre + '/choices')
def team_choices(q='', page=1, num=30, initial=None):
    """
    商务group的choice
    :return:
    """
    page = int(page)
    num = int(num)

    if initial is not None:
        if isinstance(initial, (list, tuple)):
            qry = Q(id__in=initial)
        else:
            qry = Q(id=initial)
    else:
        qry = Q(id__contains=q) | Q(name__contains=q)

    query = Team.objects.filter(qry)
    total_count = query.count()
    start_pos = (page - 1) * num
    start_pos = start_pos if start_pos >= 0 else 0
    results = [
        {
            'id': obj.id,
            'text': u'{}:{}'.format(
                obj.id,
                obj.name, )
        } for obj in query[start_pos: start_pos + num]
        ]
    return {'total_count': total_count, 'results': results, 'page': page, 'num': num}
