# -*- 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 (RPCIntegrityError,
                            RPCNotFoundException)
from rpc.tool.dict_mixin import to_dict
from api.tool.user_tool import filter_user_nick_name, get_user_extra_by_user_id, get_user_from_context
from api.models import Feedback, FeedbackCategory
from ..datatables import FeedbackDT, FeedbackCategoryDT
from rpc.tool.log_tool import info_logger
from api.models.feedback import FeedbackMessage, FEEDBACK_MESSAGE_TYPE
from api.models.person import Person
from api.tool.image_utils import get_full_path
from api.tool.datetime_tool import get_timestamp
from api.models.feedback import FeedbackImage
from ..queries.feedback import FeedBackCategoryDQ, FeedBackDQ


feedback_pre = 'hera/feedback'
category_pre = 'hera/feedbackcategory'


@bind_context(feedback_pre + '/query')
def feedback_query(ctx, options):
    dqobj = FeedBackDQ()
    return dqobj.process(**options)


@bind_context(feedback_pre + '/list')
def feedback_datatable(ctx, req_data):
    dtobj = FeedbackDT(Feedback)
    return dtobj.process(req_data, ['user__last_name', 'content', 'phone', 'qq'])


@bind_context(feedback_pre + '/get')
def feedback_detail(ctx, feedback_id, options=None):
    try:
        feedback = Feedback.objects.get(id=feedback_id)
    except:
        raise RPCNotFoundException
    if options is None:
        options = {
            'fields': None,
            'excludes': None,
            'expands': None,
        }

    feedback_data = to_dict(feedback, **options)
    feedback_data['feedbackcategory_name'] = feedback.feedbackcategory.title if feedback.feedbackcategory else ''
    feedback_data['user_name'] = feedback.user.last_name if feedback.user else ''
    feedback_data['who_name'] = filter_user_nick_name(feedback.who)

    images = []
    for i in feedback.images.all():
        if i.image_url:
            images.append(i.image_url)
    feedback_data['images'] = [i.image_link for i in feedback.images.all()]
    return feedback_data


@bind_context(feedback_pre + '/edit')
def feedback_edit(ctx, feedback_id, feedback_info=None):
    try:
        feedback = Feedback.objects.get(id=feedback_id)
    except:
        info_logger.info(__import__('traceback').format_exc())
        raise RPCNotFoundException

    feedback_info['feedbackcategory_id'] = feedback_info.pop('feedbackcategory')
    for k, v in feedback_info.iteritems():
        setattr(feedback, k, v)
    feedback.save()
    return feedback.id


@bind_context(category_pre + '/choices')
def category_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(title__contains=q)
    query = FeedbackCategory.objects.using(settings.SLAVE_DB_NAME).filter(qry).order_by('position')
    # total_count = query.count()
    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.title),
        } for obj in query[start_pos: start_pos + num]
    ]
    return {'total_count': total_count, 'results': results, 'page': page, 'num': num}


@bind_context(category_pre + '/query')
def category_query(ctx, options):
    dqobj = FeedBackCategoryDQ()
    return dqobj.process(**options)


@bind_context(category_pre + '/list')
def category_list(ctx, req_data):
    dtobj = FeedbackCategoryDT(FeedbackCategory)
    return dtobj.process(req_data)


@bind_context(category_pre + '/get')
def category_detail(ctx, category_id, options=None):
    try:
        category = FeedbackCategory.objects.get(id=category_id)
    except:
        raise RPCNotFoundException
    if options is None:
        options = {
            'fields': None,
            'excludes': None,
            'expands': None,
        }
    category_data = to_dict(category, **options)
    return category_data


@bind_context(category_pre + '/edit')
def category_edit(ctx, category_id=None, category_info=None):
    if category_info is None:
        return None

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


@bind_context(feedback_pre + '/message/list')
def feedback_message_list(ctx, feedback_id):
    try:
        feedback = Feedback.objects.get(id=feedback_id)
    except:
        info_logger.info(__import__('traceback').format_exc())
        raise RPCNotFoundException

    user_extra = get_user_extra_by_user_id(feedback.user.id)
    user_portrait = get_full_path(user_extra.portrait or u'img%2Fuser_portrait.png')
    msgs = [
        {
            'is_customer_service': False,
            'id': feedback.id,
            'nick_name': filter_user_nick_name(feedback.user),
            'portrait': user_portrait,
            'message_type': FEEDBACK_MESSAGE_TYPE.TXT,
            'message': feedback.content,
            'created_time': get_timestamp(feedback.created_time)
        }]

    feedback_images = FeedbackImage.objects.filter(feedback=feedback)
    if feedback_images:
        for image in feedback_images:
            msgs.append(
                {
                    'is_customer_service': False,
                    'id': feedback.id,
                    'nick_name': filter_user_nick_name(feedback.user),
                    'portrait': user_portrait,
                    'message_type': FEEDBACK_MESSAGE_TYPE.IMAGE,
                    'message': get_full_path(image.image_url),
                    'created_time': get_timestamp(feedback.created_time)
                })

    feedback_messages = FeedbackMessage.objects.filter(feedback_id=feedback.id).order_by(
        'created_time')
    for msg in feedback_messages:
        user = msg.person.user if msg.person else msg.servant.user
        user_extra = get_user_extra_by_user_id(user.id)
        message_type = msg.message_type
        message = msg.message
        if message_type == FEEDBACK_MESSAGE_TYPE.IMAGE:
            message = get_full_path(message)
        msgs.append({
            'is_customer_service': True if msg.servant else False,
            'id': msg.id,
            'nick_name': filter_user_nick_name(user),
            'portrait': get_full_path(user_extra.portrait) or get_full_path(u'img%2Fuser_portrait.png'),
            'message_type': message_type,
            'message': message,
            'created_time': get_timestamp(msg.created_time)
        })

    return msgs


@bind_context(feedback_pre + '/message/reply')
def feedback_message_reply(ctx, feedback_id, message_type, message):
    try:
        feedback = Feedback.objects.get(id=feedback_id)
    except:
        info_logger.info(__import__('traceback').format_exc())
        raise RPCNotFoundException

    feedback.has_more_asks = False
    feedback.save()

    user = get_user_from_context(ctx)
    person = Person.objects.get(user=user)
    feedback_message = FeedbackMessage.objects.create(feedback=feedback, servant=person, message_type=message_type,
                                                      message=message)
    return feedback_message.id
