# -*- coding: UTF-8 -*-

from django.db import IntegrityError
from django.db.models import Q
from django.conf import settings

from rpc.decorators import bind_context
from rpc.exceptions import (RPCPermissionDeniedException, RPCIntegrityError,
    RPCNotFoundException)
from rpc.tool.dict_mixin import to_dict
from api.models import BodyPart
from ..utils import remote_choices
from ..datatables import BodyPartDT
from ..queries.bodypart import BodyPartDQ

from rpc.tool.log_tool import info_logger


uri_pre = 'hera/bodypart'


@bind_context(uri_pre+'/choices')
def bodypart_choices(ctx, q='', page=1, num=30, initial=None):
    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 = BodyPart.objects.using(settings.SLAVE_DB_NAME).filter(qry)
    total_count = 0
    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}


@bind_context(uri_pre + '/query')
def bodypart_query(ctx, options):
    dqobj = BodyPartDQ()
    return dqobj.process(**options)


@bind_context(uri_pre+'/list')
def bodypart_datatable(ctx, req_data):
    dtobj = BodyPartDT(BodyPart)
    return dtobj.process(req_data)


@bind_context(uri_pre+'/get')
def bodypart_detail(ctx, bodypart_id, options=None):
    try:
        bodypart = BodyPart.objects.get(id=bodypart_id)
    except:
        raise RPCNotFoundException
    if options is None:
        options = {
            'fields': None,
            'excludes': None,
            'expands': None,
        }
    bodypart_data = to_dict(bodypart, **options)
    return bodypart_data


@bind_context(uri_pre+'/edit')
def bodypart_edit(ctx, bodypart_id=None, bodypart_info=None):
    if bodypart_info is None:
        return None

    bodypart_info['tag_id'] = bodypart_info.pop('tag')

    if bodypart_id is None:
        try:
            bodypart = BodyPart.objects.create(**bodypart_info)
        except IntegrityError:
            raise RPCIntegrityError
    else:
        try:
            bodypart = BodyPart.objects.get(id=bodypart_id)
        except:
            info_logger.info(__import__('traceback').format_exc())
            raise RPCNotFoundException
        for k, v in bodypart_info.iteritems():
            setattr(bodypart, k, v)
        bodypart.save()
    return bodypart.id