# coding=utf-8
from __future__ import absolute_import
import datetime
import hashlib
import requests
import json
from urlparse import urljoin

from gm_upload import set_video_watermark
from gm_upload.utils.qiniu_tool import QiniuTool
from django.db.models import Q
from django.conf import settings
from gm_types.gaia import VIDEO_CODE_STATUS,BD_SERVICE_TYPE
from api.models import Service, ServiceMonitor, ServiceRegisterVideo, ServiceVideo, Merchant, ServiceRegister,BDTransferVisitRecord
from api.models import SKUPriceRule, ServiceItemPrice, ServiceItem, Special, SpecialItem, CouponSpecialRestrict
from api.models.types import REFUND_STATUS, ORDER_STATUS, SERVICE_MONITOR_STATUS, PAYMENT_TYPE
from celery import shared_task
from rpc.tool.log_tool import logging_exception,info_logger
from api.manager.service_info_manager import get_toc_sku_info_list_mapping_by_sku_ids, get_toc_spu_info_list_mapping_by_spu_ids
from api.tool.user_tool import get_doctor_from_context
from rpc.tool.error_code import gen, CODES


settled_status = [ORDER_STATUS.USED, ORDER_STATUS.SETTLED, ORDER_STATUS.AUDITING, ORDER_STATUS.SETTLING, ]


@shared_task
def judge_services():
    init_q = Q(payment_type__in=[PAYMENT_TYPE.FULL_PAYMENT, PAYMENT_TYPE.PREPAYMENT])
    for service in Service.objects.filter(init_q):
        try:
            service.monitor
        except ServiceMonitor.DoesNotExist:
            ServiceMonitor.objects.create(service=service)
        q = Q(last_modified__gt=service.monitor.handle_at)
        q &= Q(last_modified__gt=datetime.datetime.now() - datetime.timedelta(days=180))
        orders = service.order_set.filter(q)
        refund_num = orders.filter(refund__status=REFUND_STATUS.REFUNDED).count()
        settled_num = orders.filter(status__in=settled_status).count()
        service.monitor.refund_num = refund_num
        service.monitor.settled_num = settled_num
        service.monitor.save()
        if service.monitor.status == SERVICE_MONITOR_STATUS.BLACK:
            continue
        else:

            if refund_num < 4:
                continue
            if refund_num > settled_num:
                if refund_num > 2 * settled_num:
                    service.monitor.set_black()
                    continue
                service.monitor.set_alert()
                continue
            service.monitor.cancel_alert()
    return {
        'success': True,
    }


@shared_task
def set_water_mark_to_video_service(id):
    video = ServiceRegisterVideo.objects.get(id=id)
    video.persistent_status = VIDEO_CODE_STATUS.WAITING
    pid = set_video_watermark(
        video.video_url,
        hashlib.md5(video.video_url).hexdigest() + '.mp4',
        water_mark_url=settings.WATER_MARK_URL_FOR_VIDEO
    )
    video.persistentId = pid
    video.save(update_fields=['persistentId', 'persistent_status'])


@shared_task
def check_water_mark_video_is_finish_service():
    videos = ServiceRegisterVideo.objects.filter(~Q(persistent_status=VIDEO_CODE_STATUS.SUCCESS))
    for video in videos:
        try:
            if video.persistentId:
                result = json.loads(requests.get('http://api.qiniu.com/status/get/prefop?id=' +
                                                 video.persistentId).text)
                if result.get('code', 4) != 0:
                    continue

                if result['items'][0]['code'] == 0:
                    water_url = result['items'][0]['key']
                    # 刷新cdn缓存
                    QiniuTool.refresh_qiniu_resource_cache([urljoin(settings.VIDEO_HOST, water_url)])

                    video.water_url = water_url
                    video.persistent_status = VIDEO_CODE_STATUS.SUCCESS
                    video.save(update_fields=['persistent_status', 'water_url'])
                    if ServiceVideo.objects.filter(service_id=video.serviceregister.service_id).exists():
                        svideo = ServiceVideo.objects.get(service_id=video.serviceregister.service_id)
                        svideo.persistent_status = VIDEO_CODE_STATUS.SUCCESS
                        svideo.water_url = water_url
                        svideo.persistentId = video.persistentId
                        svideo.save(update_fields=['persistent_status', 'water_url', 'persistentId'])
                else:
                    video.persistent_status = result['items'][0]['code']
                    video.save(update_fields=['persistent_status'])
        except:
            logging_exception()
            continue


@shared_task
def refresh_service_cache_info(service_ids=[], service_item_ids=[]):
    # 美购缓存动态刷新
    pass


def _refresh_service_cache_info(service_ids=[], service_item_ids=[]):
    # 美购缓存动态刷新
    pass


@shared_task
def refresh_service_cache_with_special_ids(special_ids):
    # 依据专题id 进行美购缓存信息更新
    ids = list(set(Special.objects.filter(id__in=special_ids, is_online=True, end_time__gte=datetime.datetime.now()).values_list('id', flat=True)))

    qs = SpecialItem.objects.filter(special_id__in=ids)
    service_ids = list(set(qs.values_list('service_id', flat=True)))
    service_item_ids = list(set(qs.values_list('serviceitem_id', flat=True)))

    def list_block_cache():
        start = 0
        length = 100
        if service_ids:
            while length < len(service_ids):
                _refresh_service_cache_info(service_ids=service_ids[start: length])
            start = length
            length += 100
            if length > len(service_ids):
                length = len(service_ids)
        if service_item_ids:
            while length < len(service_item_ids):
                _refresh_service_cache_info(service_item_ids=service_item_ids[start: length])
                start = length
                length += 100
                if length > len(service_item_ids):
                    length = len(service_item_ids)

    list_block_cache()


@shared_task
def refresh_service_cache_with_coupon(coupon_ids):
    # 依据美券id 进行美购缓存信息更新
    specials = CouponSpecialRestrict.objects.filter(coupon__id__in=coupon_ids)
    if not specials:
        specials = Special.objects.filter(is_onlien=True, end_time__gte=datetime.datetime.now())
    special_ids = [item.id for item in specials]
    refresh_service_cache_with_special_ids(special_ids)

@shared_task
def service_auto_down():

    merchant_list = Merchant.objects.filter(is_online=False,is_freeze=True).values_list('id',flat=True)
    q1 = Q(doctor__is_online=False, is_online=True)
    update1 = Service.objects.filter(q1).update(is_online=False,offline_reason='医生下线')
    q2 = Q(merchant_id__in=merchant_list, is_online=True)
    update2 = Service.objects.filter(q2).update(is_online=False,offline_reason='商户下线')
    q3 = Q(end_time__lte=datetime.datetime.now(), is_online=True)
    update3 = Service.objects.filter(q3).update(is_online=False,offline_reason='售卖时间过期')

    info_logger.info('service-auto-down-美购医生下线：{}个, 美购商户下线：{}个, 美购售卖时间超时：{}个'.format(str(update1),str(update2),str(update3)))


@shared_task
def auto_over_visit_task():
    """
    自动修改回访状态，每10min一次，超过当前时间算逾期
    :param to_user_email:
    :return:
    """
    info_logger.info('auto_over_visit_task -------------- begin')
    count = BDTransferVisitRecord.objects.filter(status=BD_SERVICE_TYPE.TOBEDONE,
                                         plan_at__lte=datetime.datetime.now()).update(status=BD_SERVICE_TYPE.OVERDUE)
    info_logger.info(
        'auto_over_visit_task-自动逾期回访任务: {}个'.format(str(count)))












