# coding: utf-8
import datetime
import json
from celery import shared_task
from django.db import transaction
from gm_types.gaia import GROUPBUY_STATUS, ORDER_STATUS
from api.util.wechat_util import wechat_template_push
from api.manager.order_manager import apply_refund_order_by_user
from api.models import (GroupBuyTeam, Order, GroupBuyTeamOrder, OrderExtra, ServiceItemPrice,
                        SKUPriceRule, Person, UserExtra, Special)
from doris.models.service import Promotion
from api.models import UserExtraWechatInfo
from rpc.tool.log_tool import info_logger, order_logger
from pay.tasks.groupbuy_msg_tool import GroupbuyMsgList, groupbuy_push_message, push_msg_groupbuy_msg
from api.tool.service_tool import _get_activity_info


@shared_task
def system_op_groupbuy_fail_order_refund():
    # 先将拼团状态和订单的拼团状态改变成拼团失败， 再通过order ids 一个个进行退款
    now = datetime.datetime.now()
    find_time = now - datetime.timedelta(days=3)
    gbt_ids = GroupBuyTeam.objects.filter(
        end_time__gte=find_time, end_time__lte=now, status=GROUPBUY_STATUS.GROUPBUY_STARTED
    ).values_list('id', flat=True)

    for gbt_id in gbt_ids:
        with transaction.atomic():
            gbt = GroupBuyTeam.objects.select_for_update().get(id=gbt_id)
            if gbt.status != GROUPBUY_STATUS.GROUPBUY_STARTED:
                continue
            gbt.status = GROUPBUY_STATUS.GROUPBUY_FAIL
            gbt.save(update_fields=['status'])

            order_ids = GroupBuyTeamOrder.objects.filter(
                groupbuy_team_id=gbt.id
            ).values_list('order_id', flat=True)
            bulk_number = 10
            for start in range(0, len(order_ids), bulk_number):
                Order.objects.filter(
                    id__in=list(order_ids[start: start + bulk_number])
                ).update(groupbuy_status=GROUPBUY_STATUS.GROUPBUY_FAIL)

            need_refund_order_ids = GroupBuyTeamOrder.objects.filter(
                groupbuy_team_id=gbt.id, paid=True
            ).values_list('order_id', flat=True)
            for order_id in need_refund_order_ids:
                apply_refund_order_by_user(order_id, u"拼团失败, 自动退款")


@shared_task
def system_op_after_groupbuy_fail_order_refund():
    """处理拼团结束后， 用户才支付这部分的订单进行退款"""
    now = datetime.datetime.now()
    find_time = now - datetime.timedelta(days=3)
    order_ids = list(GroupBuyTeamOrder.objects.filter(
        groupbuy_team__end_time__gte=find_time,
        groupbuy_team__end_time__lte=now,
        groupbuy_team__status=GROUPBUY_STATUS.GROUPBUY_FAIL,
        paid=True
    ).values_list('order_id', flat=True))
    need_refund_order_ids = list(Order.objects.filter(
        id__in=order_ids, status=ORDER_STATUS.PAID
    ).values_list('id', flat=True))
    for order_id in need_refund_order_ids:
        apply_refund_order_by_user(order_id, u"拼团失败, 自动退款")


def get_robot_and_is_puppet(activity_id, has_portrait=True, end_time=0):
    """ 获取可用马甲用户 存在极端情况马甲用户id用完!!! """
    offset, per = 0, 100
    obj = GroupbuyMsgList(activity_id, end_time)

    user_ids = obj.gets_user_ids(only_puppet=True)
    qs = Person.objects.filter(is_puppet=True).exclude(user_id__in=user_ids)

    def filter_robots_ids(offset, per):
        """ 获取机器人 马甲账号 """
        robot_ids = list(qs[offset: per].values_list('user_id', flat=True))
        while not robot_ids:
            offset = per
            per += 100
            robot_ids = list(qs[offset: per].values_list('user_id', flat=True))
            if per > qs.count():
                break

        return robot_ids, per

    def filter_has_portrait_user_ids(robot_ids, per):
        """ 获取有头像的用户 """
        has_portrait_user_ids = list(UserExtra.objects.filter(user_id__in=robot_ids
                                    ).exclude(portrait='').values_list('user_id', flat=True))

        while not list(has_portrait_user_ids):
            robot_ids, per = filter_robots_ids(per, per+100)
            has_portrait_user_ids = list(UserExtra.objects.filter(user_id__in=robot_ids
                                        ).exclude(portrait='').values_list('user_id', flat=True))
        return has_portrait_user_ids

    robot_ids, de_per = filter_robots_ids(offset, per)
    
    if not has_portrait:
        return robot_ids[0] if robot_ids else None

    has_portrait_user_ids = filter_has_portrait_user_ids(robot_ids, de_per)
    return has_portrait_user_ids[0] if has_portrait_user_ids else None


def _cover_groupbuy(groupbuyteam):
    """ 修改成团组状态 """
    order_logger.info({'msg': '[GROUPBUY_COVER] try to cover groupbuyteam(%s)' % (groupbuyteam.id)})

    activity_info = _get_activity_info(groupbuyteam)
    activity_id = activity_info.get("activity_id", 0)
    end_time = activity_info.get("end_time", 0)

    if not activity_id:
        order_logger.info({'msg': '[GROUPBUY_COVER] try to cover groupbuyteam(%s) FAILD!!!' % (groupbuyteam.id)})
        return

    left_user_number = groupbuyteam.left_user_number

    groupbuyteam.current_user_number += left_user_number
    groupbuyteam.left_user_number = 0
    groupbuyteam.status = GROUPBUY_STATUS.GROUPBUY_SUCCESSED
    groupbuyteam.success_time = datetime.datetime.now()
    groupbuyteam.save()

    # 更新发起用户订单状态
    groupbuyteam_order_list = groupbuyteam.groupbuyteamorder_set.all()

    for groupbuyteam_order in groupbuyteam_order_list:
        if groupbuyteam_order.order_id:
            Order.objects.filter(id=groupbuyteam_order.order_id,
                                 status=ORDER_STATUS.PAID
                                ).update(groupbuy_status=GROUPBUY_STATUS.GROUPBUY_SUCCESSED)

    # 补位小组订单 仅支持2人团
    for _ in range(left_user_number):
        # 获取机器人id
        robot_id = get_robot_and_is_puppet(activity_id, end_time=end_time)
        if not robot_id:
            robot_id = get_robot_and_is_puppet(activity_id, has_portrait=False, end_time=end_time)

        push_msg_groupbuy_msg(activity_id=activity_id, end_time=end_time, creator_user_id=groupbuyteam.creator_user_id,
                              user_id=robot_id, message=u'拼团成功')
        from django.conf import settings
        groupbuy_push_message(groupbuyteam.creator_user_id, settings.GENGMEI_MATCH)
        GroupBuyTeamOrder.objects.create(user_id=robot_id, groupbuy_team=groupbuyteam, order_id=0, paid=True)

    # 打榜任务触发
    from gm_types.gaia import YOUNG_HIT_TASK_TYPE
    from variety_show.services import YoungTaskService
    YoungTaskService.set_today_user_completed_task(user_id=groupbuyteam.creator_user_id, task_type=YOUNG_HIT_TASK_TYPE.GROUP_BY)
    order_logger.info({'msg': '[GROUPBUY_COVER] cover groupbuyteam(%s) finished' % (groupbuyteam.id)})


def groupbuy_robot_join():
    ''' 拼团剩余时间小于2小时未成团，加入机器人成团 '''
    order_logger.info({'msg':"[GROUPBUY_COVER] groupbuy cover starting !!!"})
    groupbuyteam_list = GroupBuyTeam.objects.filter(status=GROUPBUY_STATUS.GROUPBUY_STARTED)

    for groupbuyteam in groupbuyteam_list:
        span_time = groupbuyteam.end_time - datetime.datetime.now()
        total_seconds = span_time.total_seconds()

        # 处理距离拼团结束不足2小时的，逾期的不处理
        if total_seconds < 2*60*60 and total_seconds > 0:

            order_logger.info({'msg': "[GROUPBUY_COVER] trigger cover groupbuyteam(%s)" % (groupbuyteam.id)})
            _cover_groupbuy(groupbuyteam)

    order_logger.info("[GROUPBUY_COVER] groupbuy cover finished !!!")
