import datetime
import random

from celery import shared_task
from gm_types.mimas import VOTE_TASK_TYPE

from qa.utils.statistic import get_countdown
from talos.logger import info_logger
from talos.models.topic import Problem
from talos.models.tractate import Tractate
from talos.tasks.vote import fake_vote
from talos.tools.fake_vote_tool import (
    VoteTaskTool,
    REPEAT_TIMES_RANGE,
    format_timestamp,
    is_special_user,
    SU_REPEAT_TIMES_RANGE,
    need_push,
)
from .tractate import tractate_fake_vote


def special_user_content_level(business_id, business_type):
    # 获取（日记本，日记帖，问题等）的作者 类型
    special_user, content_level = False, '0'
    if business_type == VOTE_TASK_TYPE.TRACTATE:
        try:
            tractate = Tractate.objects.get(id=business_id)
            special_user = is_special_user(user_id=tractate.user_id)
            content_level = tractate.content_level
        except Tractate.DoesNotExist:
            special_user = False
    elif business_type == VOTE_TASK_TYPE.TOPIC:
        try:
            problem = Problem.objects.get(id=business_id)
            special_user = is_special_user(user_id=problem.user_id)
            content_level = problem.diary.content_level
        except Problem.DoesNotExist:
            special_user = False

    return special_user, content_level


def get_tasks_cds(repeat_times_range):
    """
    获取tasks计时
    :param repeat_times_range: 任务执行次数取值区间[10, 122]
    :return:
    """
    now_date = datetime.datetime.now()
    repeat_times = random.randint(
        repeat_times_range[0], repeat_times_range[1]
    )
    start_time = format_timestamp(now_date, hour=9)
    end_time = format_timestamp(now_date, hour=22)
    time_range = (start_time, end_time)
    cds = get_countdown(repeat_times, time_range=time_range)

    return cds


@shared_task
def fake_vote_task():
    """
    每天定时获取任务
    :return:
    """
    # 后期可能会加入除帖子以外的任务，（日记本，日记帖，问题等）是否需要拆成多个celery beat？
    for _type, _value in VOTE_TASK_TYPE:
        tool = VoteTaskTool(task_type=_type)
        all_tasks = tool.get_all_valid_tasks()
        if not all_tasks:
            continue

        for _id, _times in all_tasks.items():
            tool.update_repeat_times(_id)
            special_user, content_level = special_user_content_level(_id, _type)
            info_logger.info('开始执行{}灌水,id:{}'.format(VOTE_TASK_TYPE.getDesc(key=str(_type)), _id))

            # 达人、医生、机构的点赞次数与普通用户有区别
            if special_user:
                repeat_times_range = SU_REPEAT_TIMES_RANGE.get((int(_times),), {}).get(str(content_level))
            else:
                repeat_times_range = REPEAT_TIMES_RANGE.get((int(_times),), {}).get(str(content_level))  # dict_item
            if not repeat_times_range:
                tool.check_key_is_valid(_id)
                continue
            cds = get_tasks_cds(repeat_times_range)
            info_logger.info('{}id:{}'.format(VOTE_TASK_TYPE.getDesc(key=_type), _id))
            if _type == VOTE_TASK_TYPE.TRACTATE:
                for cd in cds:
                    force_push = need_push()
                    result = tractate_fake_vote.apply_async(
                        args=(1, int(_id)),
                        kwargs={'incr_range': [3, 11], "force_push": force_push},
                        eta=datetime.datetime.fromtimestamp(cd - 8*3600)
                    )
                    info_logger.info(
                        "帖子点赞第{}天任务,id:{}, task_id:{},开始执行时间：{}".format(
                            int(_times)+1, _id, result.task_id, datetime.datetime.fromtimestamp(cd)
                        )
                    )
                info_logger.info("帖子点赞定时任务，第{}天,id:{}, 任务个数：{}".format(
                    int(_times)+1, _id,  len(cds))
                )

            elif _type == VOTE_TASK_TYPE.TOPIC:
                for cd in cds:
                    force_push = need_push()
                    result = fake_vote.apply_async(
                        args=(1, int(_id)),
                        kwargs={'incr_range': [2, 20], 'force_push': force_push},
                        eta=datetime.datetime.fromtimestamp(cd - 8*3600)
                    )
                    info_logger.info(
                        "日记帖点赞第{}天任务,id:{}, task_id:{},开始执行时间：{}".format(
                            int(_times)+1, _id, result.task_id, datetime.datetime.fromtimestamp(cd)
                        )
                    )
                info_logger.info("日记帖点赞定时任务，第{}天,id:{}, 任务个数：{}".format(
                    int(_times)+1, _id,  len(cds))
                )

            # 任务天数检查，执行七次后删除任务
            tool.check_key_is_valid(_id)
