# coding=utf-8
from __future__ import unicode_literals, print_function, absolute_import


import itertools


from django.conf import settings
from api.models.message import Conversation
from message.utils.es_abstract import ESBulkAction, table_conversation
from .common import get_default_es_index_for_write, get_update_retry_on_conflict
from .es import tzlc
from utils.table_scan import FiniteTableScanner
from datetime import datetime
from django.core.exceptions import ObjectDoesNotExist


def get_conversation_head_bulk_action(
    conversation_head,
    clear_messages=False,
    retry_on_conflict=None,
):
    retry_on_conflict = get_update_retry_on_conflict(retry_on_conflict)

    if clear_messages:
        data = {
            'messages': []
        }.update(conversation_head)
    else:
        data = conversation_head

    return ESBulkAction(
        table=table_conversation,
        params={
            '_op_type': 'update',
            '_id': data['id'],
            '_retry_on_conflict': retry_on_conflict,
            '_source': {
                'doc': data,
                'doc_as_upsert': True,
            }
        }
    )


def _message_data_to_conversation_message_data(
    message_data
):
    """
    message_data should in this form: {
        "id": message_id,
        "conversation_id": conversation_id,
        "send_user": {
            "id": send_user_id,
        },
        "type": message_type,
        "content": {
            "text": text,
            "audio": audio,
            "image": image,
        }
    }
    """
    return {
        'id': message_data['id'],
        'send_user': {
            'id': message_data['send_user']['id'],
        },
        'send_time': message_data['send_time'],
        'type': message_data['type'],
        'content': message_data['content'],
    }


def get_conversation_add_one_message_bulk_action(
    message_data,
    conversation_head=None,
    retry_on_conflict=None,
):
    retry_on_conflict = get_update_retry_on_conflict(retry_on_conflict)

    conversation_id = message_data['conversation_id']
    if conversation_head:
        assert conversation_head['id'] == conversation_id

    action = ESBulkAction(
        table=table_conversation,
        params={
            '_op_type': 'update',
            '_id': message_data['conversation_id'],
            '_retry_on_conflict': retry_on_conflict,
            '_source': {
                'script': {
                    'lang': settings.ES_SCRIPT_LANG,
                    'script_file': 'update_conversation-add-message',
                    'params': {
                        'MESSAGE': _message_data_to_conversation_message_data(message_data),
                        'CONVERSATION_HEAD': conversation_head,
                    }
                },
                'scripted_upsert': True,
                'upsert': {
                    'id': conversation_id,
                },
            }
        }
    )

    return action


def get_conversation_messages_addall_bulk_action(
    conversation_id,
    message_data_list,
    es_index=None,
    retry_on_conflict=None,
):
    es_index = get_default_es_index_for_write(es_index)
    retry_on_conflict = get_update_retry_on_conflict(retry_on_conflict)

    data_list = []
    for message_data in message_data_list:
        assert message_data['conversation_id'] == conversation_id
        data = _message_data_to_conversation_message_data(message_data)
        data_list.append(data)

    action = {
        '_op_type': 'update',
        '_index': es_index,
        '_type': 'conversation',
        '_id': conversation_id,
        '_retry_on_conflict': retry_on_conflict,
        '_source': {
            'script': {
                'lang': settings.ES_SCRIPT_LANG,
                'script_file': 'update_conversation-add-all-and-unique-messages',
                'params': {
                    'MESSAGE_LIST': data_list,
                }
            },
            'scripted_upsert': True,
            'upsert': {
                'id': conversation_id,
            },
        }
    }

    return action


def get_conversation_head_from_conversation(conversation, conversation_extra=None):
    conversation_extra = conversation_extra or {}
    conversation_id = conversation.id

    user_status_set = conversation.user_status_set.all()
    users = []
    is_star_by_doctor = False
    for user_status in user_status_set:
        users.append({
            'id': user_status.user_id,
            'last_name': get_user_last_name(user_status),
            'is_unread': user_status.read_status,
            'status': True if user_status.status =='1' else False,
            # 'tags': list(user_status.tags.values_list('id', flat=True)),
            'comment': user_status.comment,
        })

        if user_status.is_star:
            is_star_by_doctor = True

    res = {
        'id': conversation_id,
        'users': users,
    }

    res.update({
        'is_star_by_doctor': is_star_by_doctor,
    })

    if len(user_status_set)>0:
        res['last_reply_time'] = tzlc(user_status_set[0].last_reply_time)
    else:
        res['last_reply_time'] = tzlc(datetime.fromtimestamp(0))

    if 'conversation_type' in conversation_extra:
        res['conversation_type'] = conversation_extra['conversation_type']

    return res


def get_user_last_name(user_status):
    from api.models.user import User
    try:
        return User.objects.get(id=user_status.user_id).last_name
    except ObjectDoesNotExist:
        return ''


def conversation_data_remove_duplicated_messages(conversation_data):
    messages = conversation_data['messages']
    new_messages = []
    message_id_set = set()
    for m in messages:
        m_id = m['id']
        if m_id not in message_id_set:
            message_id_set.add(m_id)
            new_messages.append(messages)
    conversation_data['messages'] = new_messages
