# coding=utf-8
from __future__ import absolute_import, unicode_literals
from django.core.management.base import BaseCommand, CommandError
from api.models import Conversation, ConversationUserStatus
from message.utils.es_abstract import get_esop, table_conversation
from message.signal_handlers import sync_conversation
from message.utils.es import tzlc
from gm_types.msg.enum import CONVERSATION_TYPE
from message.utils.conversation import get_conversation_head_bulk_action


class Command(BaseCommand):
    args = ''
    help = 'conversation head sync to es'

    from optparse import make_option
    option_list = BaseCommand.option_list + (
        make_option('--all', dest='sync_all', action='store_true', default=False,
                    help='sync all conversation'),)

    def __init__(self, *args, **kwargs):
        super(Command, self).__init__(*args, **kwargs)
        self.esop = get_esop()

    def handle(self, *args, **options):
        if options['sync_all']:
            self.sync_all()
        else:
            self.sync_missing()

    def sync_missing(self):
        query={
            'query':{
                'filtered':{
                    'filter':{
                        'missing':{'field':'last_reply_time'}
                    }
                }
            }
        }
        broken_convs = self.esop.helper_scan(
            table=table_conversation,
            query=query,
            size=500)
        for conv in broken_convs:
            try:
                conv_id = conv['_source']['id']
                conv = Conversation.objects.get(pk=conv_id)
                sync_conversation(conversation=conv)
            except Exception as e:
                print(e)

    def sync_all(self):
        last_conv_id = Conversation.objects.all().order_by('-id')[0].id
        while last_conv_id > 0:
            convs = Conversation.objects.filter(pk__lte=last_conv_id).order_by('-id')[0:100]
            try:
                self.msync_conversation_head(conversations=convs)
            except Exception as e:
                print(e)
            print('conversations between %d and %d are done' % (convs[0].id, convs[len(convs)-1].id))
            last_conv_id = convs[len(convs)-1].id-1

    def msync_conversation_head(self, conversations):
        def get_user_last_name(conv_status):
            try:
                return conv_status.user.last_name
            except Exception:
                return ''

        def is_kefu(conv_status):
            return conv_status.user_id==23899734

        conv_ids = list(conversations.values_list('id', flat=True))
        conv_status_list = ConversationUserStatus.objects.select_related('user').filter(conversation_id__in=conv_ids)
        conv_headers = {}
        is_star_by_doctor = False
        for conv_status in conv_status_list:
            conv_id = int(conv_status.conversation_id)
            if conv_id not in conv_headers:
                conv_headers[conv_id] = {
                    'id': conv_id,
                    'users':[{
                        'id':conv_status.user_id,
                        'last_name':get_user_last_name(conv_status),
                        'is_unread':conv_status.read_status,
                    }],
                    'last_reply_time':tzlc(conv_status.last_reply_time),
                    'is_star_by_doctor':conv_status.is_star,
                }
            else:
                conv_headers[conv_id]['users'].append({
                    'id':conv_status.user_id,
                    'last_name':get_user_last_name(conv_status),
                    'is_unread':conv_status.read_status,
                })
                if conv_status.is_star:
                    conv_headers[conv_id]['is_star_by_doctor'] = True
            if is_kefu(conv_status):
                conv_headers[conv_id]['conversation_type'] = CONVERSATION_TYPE.CUSTOMER_SRV
        conv_headers = conv_headers.values()
        actions = map(get_conversation_head_bulk_action, conv_headers)
        print self.esop.helper_bulk(actions)