#!/usr/bin/env python
# coding=utf-8


from rpc.decorators import bind_context
from django.db.models import Q
from api.models import Service, ServiceItemKey, ServiceItemPrice, ServiceRegisterItem, Doctor, Tag, User, PeriodHospital, ServiceRegister, ServiceRegisterTag, ServiceRegisterVideo, add_reviewrecord, ServiceTag, Person
from rpc.tool.error_code import gen, CODES
from gm_types.gaia import TAG_TYPE, SERVICE_SELL_TYPE, SERVICE_REVIEW_TYPE,OPERTOR_REVIEW_TYPE, VIDEO_CODE_STATUS
from gm_types.gaia import SERVICE_REVIEW_STATUS as REVIEW
from api.tool.datetime_tool import get_timestamp_epoch
from gm_upload.upload import get_video_upload_token
from django.db import transaction
from api.tool.user_tool import get_user_from_context
from datetime import datetime
from doctor.views.service import html_cleaner
from django.conf import settings
from ..tool.service_tool import count_pre_payment
from api.tasks.service_task import set_water_mark_to_video_service
import math
from hippo.tool.user_tool import get_doctor_from_context


def add_item_data(items, register):
    # 区别 纷享购 取不同的配置
    if register.service_type == SERVICE_SELL_TYPE.FENGXIANGGOU:
        s_setting = settings.SERVICE_FENGXIANGGOU_SETTING.copy()
    else:
        s_setting = settings.SERVICE_SETTING.copy()
    discount = s_setting['discount']
    pre_payment_price = s_setting['pre_payment_price']
    flag = False
    for item in items:
        if item.get('id'):
            ritem = ServiceRegisterItem.objects.get(id=item.get('id'))
            if ritem.serviceitem:
                info = ritem.serviceitem.get_current_price_info()
                if ritem.serviceitem.can_modify_price:
                    if not info.get('selling_rule', None):
                        if info['gengmei_price'] < item['gengmei_price']:
                            flag = True
                    # 任何情况改小需要审核
                    if info['gengmei_price'] > item['gengmei_price']:
                        flag = True
                if ritem.gengmei_price == item['gengmei_price']:
                    # 更美价相同则不对这条数据操作
                    continue
        else:
            item['key'] = ''
            item['service_register_id'] = register.id
            item['stock_add_num'] = 99999

        if register.service_type == SERVICE_SELL_TYPE.FENGXIANGGOU:
            item['discount'] = int(math.ceil(item['gengmei_price'] * discount / 100.00))
            item['pre_payment_price'] = pre_payment_price
            # 产品确认过 向下取整
            pre_price = int(item['gengmei_price'] * pre_payment_price / 100)
            item['pre_payment_price_int'] = pre_price
        else:
            price_data = count_pre_payment(item['gengmei_price'])
            item['discount'] = price_data['discount']
            item['pre_payment_price'] = price_data['pre_payment_price']
            item['pre_payment_price_int'] = price_data['pre_payment_price_int']
    return items, flag


@bind_context('doctor/upgrade/servicedetail', login_required=True)
def get_upgrade_service_detail(ctx, service_id, doctor_ids=None):

    def get_old_items(service, service_register):
        items = []
        online_items = service.items.filter(is_delete=False)
        for item in online_items:
            price_info = item.get_current_price_info()
            opt = ServiceItemKey.objects.filter(serviceitem=item, serviceattroption__is_online=True).first()
            item_price = ServiceItemPrice.objects.filter(service_item=item, is_enable=True).first()
            service_register_item = ServiceRegisterItem.objects.filter(serviceitem=item).first()
            # TODO serviceattroption__is_online is deprecated
            if opt is None:
                opt_name = ""
            else:
                opt_name =  opt.serviceattroption.name if getattr(opt, "serviceattroption") else ''
            items.append(
                {
                    'name': opt_name,
                    'id': service_register_item.id,
                    'sort': item.sort,
                    'original_price': item_price.original_price,
                    'gengmei_price': item_price.gengmei_price,
                    'is_online': True,
                    'sku_description': item.sku_description,
                    'discount': item_price.discount,
                    'now_pre_payment': price_info['pre_payment_price'],
                    'serviceitem_id': item.id,
                    'pre_payment_price': item_price.pre_payment_price
                }
            )
        r_q_i = Q(service_register=service_register, is_delete=False) & Q(serviceitem__is_delete=True)
        offline_items = ServiceRegisterItem.objects.filter(r_q_i)
        for service_register_item in offline_items:
            item = service_register_item.serviceitem
            price_info = item.get_current_price_info()
            opt = ServiceItemKey.objects.filter(serviceitem=item, serviceattroption__is_online=True).first()
            item_price = ServiceItemPrice.objects.filter(service_item=item, is_enable=True).first()
            # TODO serviceattroption__is_online is deprecated
            if opt is None:
                opt_name = ""
            else:
                opt_name =  opt.serviceattroption.name if getattr(opt, "serviceattroption") else ''

            items.append({
                'name': opt_name,
                'id': service_register_item.id,
                'sort': item.sort,
                'original_price': item_price.original_price,
                'gengmei_price': item_price.gengmei_price,
                'is_online': False,
                'sku_description': item.sku_description,
                'discount': item_price.discount,
                'now_pre_payment': price_info['pre_payment_price'],
                'serviceitem_id': item.id,
                'pre_payment_price': item_price.pre_payment_price
            })
        return items

    def get_items(service, service_register):
        items = []
        online_items = service.items.filter(is_delete=False)
        for item in online_items:
            price_info = item.get_current_price_info()
            item_price = ServiceItemPrice.objects.filter(service_item=item, is_enable=True).first()
            service_register_item = ServiceRegisterItem.objects.filter(serviceitem=item).first()
            items.append(
                {
                    'id': service_register_item.id,
                    'sort': item.sort,
                    'original_price': item_price.original_price,
                    'gengmei_price': item_price.gengmei_price,
                    'is_online': True,
                    'sku_description': item.sku_description,
                    'discount': item_price.discount,
                    'image_header': item.image_header,
                    'property_id': item.property_id,
                    'now_pre_payment': price_info['pre_payment_price'],
                    'serviceitem_id': item.id,
                    'pre_payment_price': item_price.pre_payment_price
                }
            )
        r_q_i = Q(service_register=service_register, is_delete=False) & Q(serviceitem__is_delete=True)
        offline_items = ServiceRegisterItem.objects.filter(r_q_i)
        for service_register_item in offline_items:
            item = service_register_item.serviceitem
            price_info = item.get_current_price_info()
            item_price = ServiceItemPrice.objects.filter(service_item=item, is_enable=True).first()
            items.append({
                'id': service_register_item.id,
                'sort': item.sort,
                'original_price': item_price.original_price,
                'gengmei_price': item_price.gengmei_price,
                'is_online': False,
                'sku_description': item.sku_description,
                'discount': item_price.discount,
                'image_header': item.image_header,
                'property_id': item.property_id,
                'now_pre_payment': price_info['pre_payment_price'],
                'serviceitem_id': item.id,
                'pre_payment_price': item_price.pre_payment_price
            })
        return items

    doctor = get_doctor_from_context(ctx)
    q = Q(id=service_id)
    if doctor_ids:
        q &= Q(doctor__in=doctor_ids)
    else:
        q &= Q(doctor=doctor)
    try:
        service = Service.objects.get(q)
    except Service.DoesNotExist:
        gen(CODES.SERVICE_NOT_EXSIT)
    project_type = []
    if service.upgrade:
        tags = [item.tag for item in ServiceTag.objects.filter(~Q(tag__tag_type=TAG_TYPE.YUNYING)&Q(service=service))]
        for tag in tags:
            project_type.append({
                'id':tag.id,
                'name':tag.name
            })
    else:
        project_type.append({
            'id':service.project_type.id,
            'name':service.project_type.name
        })

    service_register = service.servicereg.first()
    doctor = service.doctor
    service_tags_info = ctx.rpc_remote['pims/catalog/services/move_check'](services=[service.id]).unwrap()
    service_detail = {
        'id':service.id,
        'name': service.name,
        'project_type': project_type,
        'serviceregister_id': service_register.id,
        'upgrade': service.upgrade,
        'short_description': service.short_description,
        'doctor_id': doctor.id,
        'doctor_name': doctor.name,
        'start_time':get_timestamp_epoch(service.start_time),
        'end_time': get_timestamp_epoch(service.end_time),
        'photo_details': service.photo_details_doctor,
        'reject_reason': service.servicereg.first().servicereviewrecord_set.order_by('-created_time')[0].reason if service.servicereg.first().servicereviewrecord_set.order_by('-created_time') else None,
        'review_status': service_register.review_status,
        'supplement_images': service.get_supplement_images(),
        'video_pic': service.video.get_video_info()['video_pic'] if getattr(service,'video',None) else '',
        'video_token': get_video_upload_token(),
        'video_url': service.video.get_video_info()['video_url'] if getattr(service,'video',None) else '',
        'turn_down_reason': '',
        'image_header': service.image_header,
        'service_type': service.service_type,
        'is_specialreview': service_register.is_specialreview,
        'reservation': service.reservation,
        'have_extra_pay': service.have_extra_pay,
        'extra_pay_info': service.extra_pay_info,
        'recommend_services':service.get_recommend_services(),
        'old_items': get_old_items(service, service_register) if not service.upgrade else [],
        'items': get_items(service, service_register) if service.upgrade else [],
        'is_move': service_tags_info['result'].get(str(service.id), False)
    }
    return service_detail


@bind_context('doctor/upgrade/serviceregister/create', login_required=True)
@transaction.atomic
def create_upgrade_serviceregister(ctx, serviceregisterdetail, applier=None):

    explanation = serviceregisterdetail.pop('explanation')
    if applier:
        user = User.objects.get(id=applier)
    else:
        user = get_user_from_context(ctx)

    doctor = Doctor.objects.get(id=serviceregisterdetail.pop('doctor_id'))
    if doctor.is_online == False:
        raise gen(CODES.CONSElLOR_DOCTOR_IS_OFFLINE)
    project_type_list = serviceregisterdetail.pop('project_type')
    if not project_type_list:
        raise gen(CODES.PARAMS_INVALID)
    tags = Tag.objects.filter(id__in=project_type_list)
    tags_obj_list = []
    for tag in tags:
        if tag.tag_type != TAG_TYPE.ITEM_WIKI:
            return -1
        tags_obj_list.append(tag)
    is_draft = serviceregisterdetail.get('is_draft', False)
    is_specialreview = True if serviceregisterdetail.get('is_specialreview') else False
    if is_draft:
        review_status = REVIEW.DRAFT
    elif is_specialreview:
        review_status = REVIEW.SPECIAL_UNDER_REVIEW
    else:
        review_status = REVIEW.UNDER_REVIEW
    name = u'【{}】{}'.format(serviceregisterdetail.get('name'), serviceregisterdetail['short_description'])
    kwargs = {
        'name': name,
        'user': user,
        'doctor': doctor,
        'reservation': serviceregisterdetail.get('reservation'),
        'start_time': datetime.fromtimestamp(serviceregisterdetail['start_time']),
        'end_time': datetime.fromtimestamp(serviceregisterdetail['end_time']),
        'photo_details': html_cleaner.clean_html(serviceregisterdetail['photo_details']) if serviceregisterdetail['photo_details'] else '',
        'project_type': tags_obj_list[0],
        'short_description': serviceregisterdetail['short_description'],
        'image_header': serviceregisterdetail['image_header'],
        'is_specialreview': is_specialreview,
        'review_status': review_status,
        'last_submit_time': datetime.now(),
        'total_num': 0,
        'is_draft': is_draft,
        'is_stage': PeriodHospital.objects.filter(hospital=doctor.hospital, default_online=True).exists(),
        'have_extra_pay': serviceregisterdetail.get('have_extra_pay', False),
        'extra_pay_info': serviceregisterdetail.get('extra_pay_info'),
        'image_bigpic': serviceregisterdetail.get('image_bigpic'),
        'service_type': serviceregisterdetail.get('service_type', SERVICE_SELL_TYPE.NORMAL),
        'merchant_id': serviceregisterdetail.get('merchant_id')
    }
    register = ServiceRegister.objects.create(**kwargs)
    service_register_tags = []
    for single_tag in tags_obj_list:
        service_register_tags.append(ServiceRegisterTag(serviceregister=register, tag=single_tag))
    ServiceRegisterTag.objects.bulk_create(service_register_tags)
    # 保存关联图片和推荐美购
    register.update_supplement_images(serviceregisterdetail.pop('supplement_images', []))
    register.update_recommend_services(serviceregisterdetail.pop('recommend_services', []))

    items,_ = add_item_data(serviceregisterdetail['items'], register)
    for item in items:
        ServiceRegisterItem.objects.create(**item)
    video_url = serviceregisterdetail['video_url'] if serviceregisterdetail.get('video_url') else ''
    video_pic = serviceregisterdetail['video_pic'] if serviceregisterdetail.get('video_pic') else ''
    if video_url != '' or video_pic != '':
        if video_url != '':
            video_url = ServiceRegisterVideo.cleaned_video_url(video_url)
        video = ServiceRegisterVideo()
        video.serviceregister_id = register.id
        video.video_url = video_url
        video.video_pic = video_pic
        video.save()
        set_water_mark_to_video_service.delay(video.id)
    review_type = SERVICE_REVIEW_TYPE.ORDINARY
    if serviceregisterdetail['is_specialreview']:
        review_type = SERVICE_REVIEW_TYPE.SPECIAL
    add_reviewrecord(register, user.person.id, review_type=review_type, explanation=explanation)
    return {'id': register.id}


@bind_context('doctor/upgrade/serviceregister/edit', login_required=True)
@transaction.atomic
def edit_upgrade_serviceregister(ctx, serviceregisterdetail, applier=None):
    doctor = Doctor.objects.get(id=serviceregisterdetail['doctor_id'])
    if doctor.is_online == False:
        raise gen(CODES.CONSElLOR_DOCTOR_IS_OFFLINE)
    register = ServiceRegister.objects.get(id=serviceregisterdetail['id'])
    if register.review_status == REVIEW.UNDER_REVIEW and register.is_specialreview:
        raise gen(CODES.NO_EDIT)
    project_type_list = serviceregisterdetail.pop('project_type')
    if not project_type_list:
        raise gen(CODES.PARAMS_INVALID)
    tags = Tag.objects.filter(id__in=project_type_list)
    tags_obj_list = []
    for tag in tags:
        if tag.tag_type != TAG_TYPE.ITEM_WIKI:
            return -1
        tags_obj_list.append(tag)

    if applier:
        user = User.objects.get(id=applier)
    else:
        user = get_user_from_context(ctx)


    # 更改register 数值
    modify_items = [
        'short_description', 'start_time', 'end_time', 'reservation',
        'image_header', 'photo_details', 'is_specialreview', 'is_draft',
        'have_extra_pay', 'extra_pay_info', 'image_bigpic', 'doctor_id',
        'upgrade'
    ]

    for name in modify_items:
        pre = getattr(register, name)
        new = serviceregisterdetail.get(name)
        if name in {'start_time', 'end_time'}:
            new = datetime.fromtimestamp(new)
        elif name in {'photo_details'}:
            new = html_cleaner.clean_html(new) if new else ''
        if new != pre:
            setattr(register, name, new)

    name = u'【{}】{}'.format(serviceregisterdetail.get('name'), serviceregisterdetail.get('short_description'))
    register.name = name
    # 编辑后, 若不是保存草稿 状态是要改的
    if not serviceregisterdetail.get('is_draft'):
        if serviceregisterdetail['is_specialreview']:
            register.review_status = REVIEW.SPECIAL_UNDER_REVIEW
        else:
            register.review_status = REVIEW.UNDER_REVIEW
    else:
        if not register.is_register:
            register.review_status = REVIEW.PASS
        else:
            register.review_status = REVIEW.DRAFT

    register.last_submit_time = datetime.now()
    image_urls = serviceregisterdetail.pop('supplement_images', [])
    register.update_supplement_images(image_urls)
    register.update_supplement_images_order(image_urls)
    register.update_recommend_services(serviceregisterdetail.pop('recommend_services', []))
    register.user = user

    items, flag = add_item_data(serviceregisterdetail['items'], register)
    if flag:
        register.operator_review_type = OPERTOR_REVIEW_TYPE.WATI_REVIEW
    register.project_type = tags_obj_list[0]
    register.save()
    ServiceRegisterTag.objects.filter(serviceregister=register).delete()
    service_register_tags = []
    for single_tag in tags_obj_list:
        service_register_tags.append(ServiceRegisterTag(serviceregister=register, tag=single_tag))
    ServiceRegisterTag.objects.bulk_create(service_register_tags)

    saved_items = []
    for item in items:
        item_id = item.pop('id', None)
        if item_id is None:
            # 新增数据
            ritem = ServiceRegisterItem.objects.create(**item)
            saved_items.append(ritem)
        else:
            ritem = ServiceRegisterItem.objects.filter(id=item_id)
            ritem_obj = ritem.first()
            saved_items.append(ritem_obj)
            ritem.update(**item)
    ServiceRegisterItem.objects.filter(service_register=register) \
        .exclude(id__in=[x.id for x in saved_items]) \
        .update(is_delete=True)
    ServiceRegisterItem.objects.filter(id__in=[x.id for x in saved_items]).update(is_delete=False)
    video_url = serviceregisterdetail['video_url'] if serviceregisterdetail.get('video_url') else ''
    video_pic = serviceregisterdetail['video_pic'] if serviceregisterdetail.get('video_pic') else ''
    if video_url != '' or video_pic != '':
        if video_url != '':
            video_url = ServiceRegisterVideo.cleaned_video_url(video_url)
        if ServiceRegisterVideo.objects.filter(serviceregister_id=register.id).exists():
            video = ServiceRegisterVideo.objects.get(serviceregister_id=register.id)
            if video_url != video.get_url() or video_pic != video.video_pic:
                if video_url != video.get_url():
                    if video_url == '':
                        video.video_url = video_url
                        video.video_pic = video_pic
                        video.persistent_status = VIDEO_CODE_STATUS.NOSTART
                        video.water_url = ''
                        video.persistentId = ''
                        video.save()
                    else:
                        video.video_url = video_url
                        video.video_pic = video_pic
                        video.persistent_status = VIDEO_CODE_STATUS.NOSTART
                        video.water_url = ''
                        video.persistentId = ''
                        video.save()
                        set_water_mark_to_video_service.delay(video.id)
                else:
                    video.video_pic = video_pic
                    video.save()
        else:
            video = ServiceRegisterVideo()
            video.serviceregister_id = register.id
            video.video_url = video_url
            video.video_pic = video_pic
            video.save()
            set_water_mark_to_video_service.delay(video.id)
    else:
        if ServiceRegisterVideo.objects.filter(serviceregister_id=register.id).exists():
            ServiceRegisterVideo.objects.get(serviceregister_id=register.id).delete()
    review_type = SERVICE_REVIEW_TYPE.ORDINARY
    if serviceregisterdetail['is_specialreview']:
        review_type = SERVICE_REVIEW_TYPE.SPECIAL
    add_reviewrecord(register, user.person.id, review_type=review_type, explanation=serviceregisterdetail['explanation'])
    return {'id': register.id}











