# coding:utf-8

import json
from celery import shared_task

from api.models.service import Service
from api.models.smart_rank import SmartRank, SmartRankCompare
from api.tool.smart_rank import service_rerank, smart_rank_compare, service_rerank_v4
from utils.decorators import TimeIt
from django.conf import settings
import datetime
from rpc.cache import smark_rank_cache
from rpc.tool.log_tool import smart_rank_logger
from dingtalkchatbot.chatbot import DingtalkChatbot
from api.tool.log_tool import logging_exception


@TimeIt
@shared_task
def update_smart_rank():
    slave_db = settings.SLAVE_DB_NAME
    queryset = Service.objects.using(slave_db).filter(start_time__isnull=False)

    cursor = 0
    batch_ids = []
    for service in queryset:
        cursor += 1
        batch_ids.append(service.id)
        if cursor % 1000 == 0:
            service_rerank(batch_ids)

            smart_rank_logger.info(json.dumps({
                "version": "SMART_RANK",
                "op": "batch update",
                "service_ids": [str(x) for x in batch_ids]
            }))
            batch_ids = []
    service_rerank(batch_ids)
    service_ids = check_smart_rank()
    if service_ids:
        service_rerank(service_ids)

    smart_rank_logger.info(json.dumps({
        "version": "SMART_RANK",
        "op": "batch update",
        "service_ids": [str(x) for x in batch_ids]
    }))

    smart_rank_logger.info(json.dumps({
        "version": "SMART_RANK",
        "status": "update finished"
    }))

    return 'done!'

@TimeIt
@shared_task
def update_smart_rank_v4():
    slave_db = settings.SLAVE_DB_NAME
    queryset = Service.objects.using(slave_db).filter(start_time__isnull=False)

    cursor = 0
    batch_ids = []
    for service in queryset:
        cursor += 1
        batch_ids.append(service.id)
        if cursor % 1000 == 0:
            service_rerank_v4(batch_ids)

            smart_rank_logger.info(json.dumps({
                "version": "SMART_RANK_V4",
                "op": "batch update",
                "service_ids": [str(x) for x in batch_ids]
            }))
            batch_ids = []
    service_rerank_v4(batch_ids)
    service_ids = check_smart_rank()
    if service_ids:
        service_rerank_v4(service_ids)

    smart_rank_logger.info(json.dumps({
        "version": "SMART_RANK_V4",
        "op": "batch update",
        "service_ids": [str(x) for x in batch_ids]
    }))

    smart_rank_logger.info(json.dumps({
        "version": "SMART_RANK_V4",
        "status": "update finished"
    }))

    return 'done!'

def check_smart_rank():
    """
    定时任务update_smart_rank 有一部分数据漏掉没有处理
    该函数用于将new_smart_rank=0的数据重新运行一遍
    :return:
    """
    service_ids = list(SmartRank.objects.filter(new_smart_rank=0).values_list('service_id', flat=True))
    if service_ids:
        return service_ids
    return []

@shared_task
def fix_error_smart_rank():
    service_ids = check_smart_rank()
    if service_ids:
        service_rerank(service_ids)

@TimeIt
@shared_task
def smark_rank_check():
    try:
        slave_db = settings.SLAVE_DB_NAME

        last_success_time = smark_rank_cache.get("last_success_time")

        check_time = datetime.datetime.now()

        if last_success_time:
            last_check_time = datetime.datetime.strptime(last_success_time, '%Y-%m-%d %H:%M:%S') - datetime.timedelta(
                minutes=10)
            queryset = SmartRank.objects.using(slave_db).filter(update_time__gte=last_check_time).values_list(
                "service_id", flat=True)
        else:
            queryset = SmartRank.objects.using(slave_db).all().values_list("service_id", flat=True)

        batch_size = 1000  # es最大查询是1000， 最好不要超过1000

        cursor = 0
        batch_ids = []

        re_count = queryset.count()

        all_diff_sids = []

        for service_id in queryset:
            if service_id:
                cursor += 1
                batch_ids.append(service_id)
                if cursor % batch_size == 0 and batch_ids:
                    diff_sids = smart_rank_compare(batch_ids, check_time)
                    all_diff_sids += diff_sids

                    batch_ids = []

        if batch_ids:
            diff_sids = smart_rank_compare(batch_ids, check_time)
            all_diff_sids += diff_sids

        last_success_time = check_time

        smark_rank_cache.setex("last_success_time", 86400, check_time.strftime('%Y-%m-%d %H:%M:%S'))

        count = SmartRankCompare.objects.using(slave_db).filter(check_time=last_success_time).exclude(sr_delta=0).count()
        new_count = SmartRankCompare.objects.using(slave_db).filter(check_time=last_success_time).exclude(srn_delta=0).count()

        msg = 'smark_rank检查时间：{} \n' \
              '本次对比数据量：{} \n' \
              'smark_rank错误：{} \n' \
              'new_smark_rank错误：{} \n' \
              'service_ids: {}'.format(check_time.strftime('%Y-%m-%d %H:%M:%S'),
                                       re_count,
                                       count,
                                       new_count,
                                       str(all_diff_sids)
                                       )

        print(msg)

        if settings.SMARK_RANK_CHECK_DINGTALK_ACCESS_TOKEN and settings.SMARK_RANK_CHECK_DINGTALK_MOBILES:
            webhook = 'https://oapi.dingtalk.com/robot/send?access_token={}'.format(settings.SMARK_RANK_CHECK_DINGTALK_ACCESS_TOKEN)
            xiaoding = DingtalkChatbot(webhook)
            at_mobiles = list(settings.SMARK_RANK_CHECK_DINGTALK_MOBILES)

            xiaoding.send_text(msg=msg, at_mobiles=at_mobiles)

        return 'done!'

    except:
        logging_exception()
