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

import json
import datetime
import time

from django.db.models import Max, Q
from django.db import transaction

from gm_types.gaia import DRAFT_TYPE
from gm_rpcd.all import bind

from talos.decorators import list_interface
from talos.rpc import CODES, gen
from talos.rpc import bind_context
from talos.models.diary import Diary
from talos.models.draft import Draft
from talos.services import get_user_from_context
from talos.rpc import logging_exception
from talos.libs.diary import common_func_for_create_diary

from utils.rpc import get_current_user

@bind('diary/draft/create')
def draft_create(draft_type=None, diary_id=None, tag_ids=None, content=None,
                 zone_tag_id=None, images=None, cover=None, video_url=None, operation_date=None):
    user = get_current_user()
    if not user:
        return gen(CODES.LOGIN_REQUIRED)

    diary = None
    if diary_id and draft_type == DRAFT_TYPE.DIARY:
        try:
            diary = Diary.objects.get(pk=diary_id, user_id=user.id)
        except Diary.DoesNotExist:
            return gen(CODES.DIARY_NOT_FOUND)

    if video_url:
        video_url = Draft.cleaned_video_url(video_url)

    if operation_date:
        operation_date = datetime.date.fromtimestamp(float(operation_date))
    else:
        operation_date = None

    draft = Draft.objects.create(
        is_show=True, diary=diary, content=content,
        tags=tag_ids, images=images, zone_tag=zone_tag_id,
        cover=cover, person_id=user.person_id, video=video_url,
        operation_date=operation_date
    )

    return {'create_status': True, 'draft_id': draft.id}


@bind('diary/draft/update')
def draft_update(draft_id, tag_ids=None, content=None, images=None, cover=None, video_url=None, operation_date=None):
    user = get_current_user()
    if not user:
        return gen(CODES.LOGIN_REQUIRED)

    try:
        draft = Draft.objects.get(pk=draft_id, person_id=user.person_id)

    except Draft.DoesNotExist:
        return gen(CODES.DRAFT_NOT_FOUND)

    if tag_ids:
        get_tags = json.loads(tag_ids)
    else:
        get_tags = None

    get_images = json.loads(images) if images else None
    if not (get_tags or get_images or content):
        draft.is_show = False
    else:
        draft.tags = tag_ids
        draft.content = content
        draft.images = images
        draft.cover = cover
        draft.video = Draft.cleaned_video_url(video_url) if video_url else ''
        draft.operation_date = datetime.date.fromtimestamp(float(operation_date)) if operation_date else None
        draft.update_time = datetime.datetime.now()
    draft.save()

    return {'update_status': True}


@bind('diary/draft/list')
@list_interface(offset_name='start_num', limit_name='count')
def draft_list(start_num=0, count=10, simple=True):
    user = get_current_user()
    if not user:
        return gen(CODES.LOGIN_REQUIRED)
    #以下为老代码，目的是为了下线所有日记本下线状态的日记贴，这次在搜索条件过滤掉不在线的日记本的日记贴
    # diary_drafts = Draft.objects.filter(
    #     is_show=True,
    #     person_id=user.person_id,
    #     diary__isnull=False,
    # )
    #
    # if diary_drafts:
    #     for draft in diary_drafts:
    #         if not draft.diary.is_online:
    #             draft.is_show = False
    #             draft.save()

    drafts = Draft.objects.filter(
        is_show=True,
        person_id=user.person_id,
        diary__is_online=True,
    ).order_by('-update_time')[start_num:start_num + count]

    drafts_info = [draft.info(simple) for draft in drafts]

    return {'drafts': drafts_info}


@bind('diary/draft/detail')
def draft_detail(draft_id):
    user = get_current_user()
    if not user:
        return gen(CODES.LOGIN_REQUIRED)

    try:
        draft = Draft.objects.get(pk=draft_id, person_id=user.person_id)
    except Draft.DoesNotExist:
        return gen(CODES.DRAFT_NOT_FOUND)

    return {
        'draft': draft.info(simple=False)
    }


@bind('diary/draft/delete')
def draft_delete(draft_id):
    user = get_current_user()
    if not user:
        return gen(CODES.LOGIN_REQUIRED)

    try:
        draft = Draft.objects.get(pk=draft_id, person_id=user.person_id)
    except Draft.DoesNotExist:
        return gen(CODES.DRAFT_NOT_FOUND)

    draft.delete()

    return {'delete_status': True}


@bind('diary/draft/has_draft')
def get_draft_has_draft(is_diary=True, diary_id=None):
    user = get_current_user()
    if not user:
        return gen(CODES.LOGIN_REQUIRED)

    result = {"has_draft": False}
    person_id = user.person_id
    if is_diary:
        draft_count = Draft.objects.filter(person_id=person_id, diary__isnull=is_diary).count()
    else:
        draft_count = Draft.objects.filter(person_id=person_id, diary__id=diary_id).count()

    if draft_count:
        result["has_draft"] = True

    return result


@bind('diary/draft/detail_v2')
def draft_detail_v2(diary_id, simple=True):
    """
    点击草稿卡片，跳转页面丢回数据接口
    用于从草稿箱列表中点击草稿卡片返回，草稿箱列表中展示的是草稿，既传到这个接口的日记本都是有草稿的
    :param diary_id:
    :return:
    """
    user = get_current_user()
    if not user:
        return gen(CODES.LOGIN_REQUIRED)

    draft_list = Draft.objects.filter(diary=diary_id, is_show=True).order_by('-update_time', '-id')
    if not draft_list:
        raise gen(CODES.DRAFT_NOT_FOUND)
    drafts_info = [draft.info(simple=False) for draft in draft_list]

    diary_info = Diary.objects.filter(id=diary_id)
    service_name = diary_info.first().related_service_name
    diary_info = diary_info.extra(
        select={'doctor_name': 'raw_doctor', 'hospital_name': 'raw_hospital', 'diary_title': 'title'}).values(
        "id", "hospital_id", "doctor_id", "order_id", "hospital_name",
        "doctor_name", "diary_title", "operation_time", "is_online").first()
    diary_info["service_name"] = service_name if service_name else ""
    if diary_info.get("operation_time"):
        diary_info["operation_time"] = diary_info["operation_time"].timestamp()

    if diary_info.get("is_online"):
        diary_info["is_online"] = 1
    else:
        diary_info["is_online"] = 0

    diary_info["tags"] = drafts_info[0]["tags"]
    diary_info["polymer_ids"] = drafts_info[0]["deliver_polymer"]
    return {'status': True, "drafts_info": drafts_info, "diary_info": diary_info}


@bind_context('diary/draft/create_v2')
def draft_create_v2(
        ctx,
        diary_id=None,
        title="",
        tag_ids=None,
        polymer_ids=[],
        operation_timestamp=0,
        order_id=None,
        hospital_id=None,
        hospital_name='',
        service_id=0,
        doctor_id=None,
        doctor_name='',
        topic_list=[]
):
    """

    :param diary_id: 日记本ID，如果传值过来则是更新日记本草稿，如果没有传值则是创建新的日记本草稿
    :param title: 日记本标题，
    :param tag_ids:
    :param polymer_ids:
    :param operation_timestamp:
    :param order_id:
    :param hospital_id:
    :param hospital_name:
    :param service_id:
    :param doctor_id:
    :param doctor_name:
    :param pre_operation_images:
    :param diary_pre_cover:
    :param topic_list:
    :return:
    """
    """
    草稿更新接口，包含对新创建日记本数据的更新 以及 已有日记本批量发帖数据的更新
    """
    user = get_user_from_context(ctx)
    if not user:
        return gen(CODES.LOGIN_REQUIRED)
    if diary_id:
        try:
            diary = Diary.objects.get(pk=diary_id, user_id=user.id)
        except Diary.DoesNotExist:
            return gen(CODES.DIARY_NOT_FOUND)
        if diary.is_online == False:
            diary.order_id = order_id
            diary.raw_doctor = doctor_name
            diary.doctor_id = doctor_id
            diary.raw_hospital = hospital_name
            diary.hospital_id = hospital_id
            diary.service_id = service_id
            diary.save()
    else:
        diary_params = {
            "user": user,
            "title": title,
            "operation_timestamp": operation_timestamp,
            "order_id": order_id,
            "doctor_id": doctor_id,
            "doctor_name": doctor_name,
            "hospital_id": hospital_id,
            "hospital_name": hospital_name,
            "service_id": service_id,
            "create_for_draft": True,
            "new_version_create": True,
        }
        diary = common_func_for_create_diary(**diary_params)
        diary_id = diary.id
    draft_list = Draft.objects.filter(
        id__in=[draft_id["draft_id"] for draft_id in topic_list if draft_id.get("draft_id")])
    draft_dict = {draft.id: draft for draft in draft_list}
    result = []

    tag_list = []
    for item in set(tag_ids):
        # 数据库中tag_ids字段长度为128,包含'[]'两个字符
        if len(str(tag_list)) > 126:
            break
        tag_list.append(item)

    with transaction.atomic():
        for item in topic_list:
            draft_id = item.get("draft_id")

            if draft_id and diary_id:  # 防止因为数据问题，传入了草稿ID但是没有传入日记本ID，覆盖数据
                draft = draft_dict[int(draft_id)]
            else:
                draft = Draft()
            draft.diary_id = diary_id
            draft.images = json.dumps([img["image"] for img in item.get("images", [])])
            draft.video = item.get("video")
            draft.content = item.get("content")
            draft.cover = item.get("cover")
            draft.tags = json.dumps(tag_list)
            draft.deliver_polymer = polymer_ids
            draft.person_id = user.person_id
            draft.operation_date = datetime.date.fromtimestamp(float(item.get("operation_timestamp", time.time())))
            draft.is_show = True
            try:
                draft.save()
            except:
                logging_exception()
                raise gen(CODES.UPDATE_FAIL)

            result.append(draft.id)

    return {'update_status': True, "draft_id": result, "diary_id": diary_id}


@bind('diary/draft/list/v2')
@list_interface(offset_name='start_num', limit_name='count')
def draft_list_V2(start_num=0, count=10, simple=True):
    user = get_current_user()
    if not user:
        return gen(CODES.LOGIN_REQUIRED)

    drafts = Draft.objects.filter(
        is_show=True,
        person_id=user.person_id,
        diary__isnull=False
    ).values("diary_id").annotate(draft_update_time=Max("update_time")).order_by("-draft_update_time")[
             start_num:start_num + count]
    if not drafts:
        return {'drafts': ""}

    query = Q()
    for item in drafts:
        query |= Q(diary_id=item["diary_id"]) & Q(update_time=item["draft_update_time"])

    result = Draft.objects.values("diary_id", "update_time").annotate(draft_id=Max('id')).filter(query)
    _data = Draft.objects.filter(id__in=[item["draft_id"] for item in result]).order_by("-update_time")
    drafts_info = [draft.info(simple) for draft in _data]

    return {'drafts': drafts_info}
