#!/usr/bin/env python
# -*- coding: utf-8 -*-

from django.conf import settings
from django.db.models import Q

from gm_types.gaia import (
    YOUNG_HIT_TASK_TYPE,
)

from agile.services import TagV3Service

from rpc.decorators import bind
from rpc.tool.error_code import gen, CODES

from variety_show.models import InviteCode, InviteRecord
from variety_show.services import (
    YoungActivityService,
    YoungIdolsService,
    YoungVotedService,
    YoungInviteService,
    YoungTaskService,
    YoungCacheService,
)
from api.models import UserExtra


@bind("api/variety_show/get_user_today_voted_idols")
def variety_show_get_user_today_voted_idols(user_id):
    """
    获取用户今天投票选手的状态(是否可投票的状态)
    :param user_id:
    :return: {"voted_idols_status": {idol_id: True, idol_id: False}}  # True 标识可以继续投票，False 标识加票
    """
    result = {
        "voted_idols_status": {},
        "can_voted_idol_nums": YoungVotedService.can_voted_idol_nums,
        "has_voted_nums": 0,
    }

    if not user_id:
        return result

    cache_name = YoungVotedService.get_variety_show_young_user_cache_name(user_id)

    # 用户今日完成的任务记录
    user_today_has_completed_tasks = YoungTaskService.get_today_user_has_completed_tasks(user_id, cache_name)

    # 若每日打开的加票任务未完成，则先加每日票
    if not user_today_has_completed_tasks.get(YoungTaskService.YOUNG_TASK_TYPE_DAILY_LOGIN):
        YoungTaskService.set_today_user_completed_task(user_id, YOUNG_HIT_TASK_TYPE.DAILY_LOGIN)

    # 用户投票记录
    cache_info = YoungVotedService.get_today_user_has_voted_idols_info(user_id, cache_name)
    vote_records = cache_info.get(YoungVotedService.cache_key_vote_records, {})
    total_vote_nums = cache_info.get(YoungVotedService.cache_key_total_vote_nums, 0)

    _data = {}
    for idol_id in cache_info.get(YoungVotedService.cache_key_voted_idol_ids, []) or []:
        _idol_voted_num = int(vote_records.get(str(idol_id)) or 0)
        _data[idol_id] = bool(_idol_voted_num < total_vote_nums)

    result["has_voted_nums"] = total_vote_nums
    result["voted_idols_status"] = _data

    return result


@bind("api/variety_show/get_young_user_invite_code")
def variety_show_get_young_user_invite_code(user_id):
    """
    获取用户邀请码
    :param user_id:
    :return:
    """
    if not user_id:
        return gen(CODES.PARAMS_INVALID)
    return YoungInviteService.get_code(user_id)


@bind("api/variety_show/get_young_user_today_tasks")
def variety_show_get_young_user_today_tasks(user_id):
    """
    获取用户任务
    :param user_id:
    :return:
    """
    if not user_id:
        return gen(CODES.PARAMS_INVALID)

    return {
        "tasks": YoungTaskService.get_today_user_tasks(user_id),
    }


@bind("api/variety_show/get_young_activity_info")
def variety_show_get_young_activity_info():
    """
    获取选秀节目 少年之名 活动信息
    :return:
    """

    return YoungActivityService.get_valid_young_activity_info()


@bind("api/variety_show/get_young_simple_info")
def variety_show_get_young_simple_info(young_fame_id):
    """
    获取选秀节目 少年之名 活动关联数据
    :param young_fame_id:
    :return:
    """
    YoungActivityService.safe_get(young_fame_id)
    tag_v3_ids = YoungActivityService.get_young_activity_rel_tag_ids(young_fame_id)
    tag_v3_dic = TagV3Service.get_tags_v3_by_ids(tag_v3_ids)

    return {
        "rel_tags_v3": list(tag_v3_dic.values())
    }


@bind("api/variety_show/get_young_idol_list")
def variety_show_get_young_idol_list(start_num=0, count=10, *args, **kwargs):
    """
    获取选秀节目 少年之名 学员列表
    :param start_num:
    :param count:
    :return:
    """
    return YoungIdolsService.get_young_idols(
        start_num=start_num,
        count=count
    )


@bind("api/variety_show/get_young_idol_info_by_group_id")
def variety_show_get_young_idol_info_by_group_id(group_id):
    """
    选秀节目 少年之名 通过小组ID获取学员信息
    :param group_id:
    :return:
    """
    return YoungIdolsService.get_young_idol_info_by_group_id(group_id)


@bind("api/variety_show/get_young_idol_info_by_idol_ids")
def variety_show_get_young_idol_info_by_idol_ids(idol_ids):
    """
    选秀节目 青年之名 通过选手ID获取选手信息
    :param idol_ids:
    :return:
    """
    result = {}
    if not idol_ids:
        return result

    idols_info_dic = YoungIdolsService.get_young_idol_by_ids(idol_ids)

    for idol_id, idol_data in idols_info_dic.items():
        result[str(idol_id)] = idol_data

    return result


@bind("api/variety_show/get_young_voted_idols")
def get_voted_idols(user_id, *args, **kwargs):
    """
    获取选秀节目 少年之名 我支持的学员
    :return:
    """
    result = []

    if not user_id:
        return result

    idol_ids = YoungCacheService.get_user_voted_idol_ids(user_id)
    idol_infos = YoungIdolsService.get_young_idol_by_ids(idol_ids)

    for idol_id in idol_ids:
        idol_info = idol_infos.get(int(idol_id))
        if not idol_info:
            continue

        result.append(idol_info)

    return result


@bind("api/variety_show/completed_invite_register_task")
def completed_invite_register_task(user_id, invite_code):
    """
    完成邀请注册任务
    :param user_id: 被邀请人
    :param invite_code: 邀请码
    :return:
    """

    # 判断邀请码是否有效
    try:
        code_info = InviteCode.objects.using(settings.SLAVE_DB_NAME).get(invite_code=invite_code)
    except:
        gen(CODES.INVITE_CODE_NOT_EXIST)

    # 判断是不是自己邀请自己
    if code_info.user_id == user_id:
        gen(CODES.INVITE_CODE_IS_YOURS)

    # 判断被邀请用户，是否被邀请过 或邀请过别人
    is_invited = InviteRecord.objects.filter(invited_user_id=user_id).exists()
    if is_invited:
        gen(CODES.HAS_INVITED)

    # 判断被邀请用户，邀请过别人
    is_invited_other = InviteRecord.objects.filter(user_id=user_id).exists()
    if is_invited_other:
        gen(CODES.ACTIVITY_VOTE_OLD_USER)

    # 判断被邀请人是有手机号
    phones = list(UserExtra.objects.using(settings.SLAVE_DB_NAME).filter(user_id=user_id).values_list('phone', flat=True))
    if not phones:
        gen(CODES.PHONE_NEEDED_FOR_THIRD_REG)

    # 记录完成任务(被邀请者、邀请者)
    _ = YoungTaskService.set_today_user_completed_task(
        user_id=user_id,
        task_type=YOUNG_HIT_TASK_TYPE.INVITE_USER_REGISTER
    )

    task_record_data = YoungTaskService.set_today_user_completed_task(
        user_id=code_info.user_id,
        task_type=YOUNG_HIT_TASK_TYPE.INVITE_USER_REGISTER
    )

    # 创建邀请记录
    InviteRecord.objects.create(
        user_id=code_info.user_id,
        invited_user_id=user_id,
        task_record_id=task_record_data["task_record_id"]
    )

    gen(CODES.SUCCESS)


@bind("api/variety_show/idol_info")
def variety_show_idol_info(idol_id):

    idol_obj = YoungIdolsService.safe_get(idol_id)
    if idol_obj.is_out:
        return gen(CODES.ACTIVITY_IDOL_IS_OUT)

    return YoungIdolsService.get_young_idol_by_id(idol_obj.id, with_tags=True)


@bind("api/variety_show/young_user_voted_idol")
def variety_show_young_user_voted_idol(user_id, idol_id):
    """
    用户为选手投票
    :param user_id:
    :param idol_id:
    :return:
    """
    if not all([user_id, idol_id]):
        return gen(CODES.PARAMS_INVALID)

    idol_obj = YoungIdolsService.safe_get(idol_id)
    if idol_obj.is_out:
        return gen(CODES.ACTIVITY_IDOL_IS_OUT)

    return YoungVotedService.set_today_user_vote_for_contestants(user_id, idol_id)


@bind("api/variety_show/young_add_ticket_after_task_completed")
def variety_show_young_add_ticket_after_task_completed(user_id, task_type):
    """
    选秀节目 少年之名 完成任务
    :param user_id:
    :param task_type:  task_type 只支持 每日进入、浏览、拼团。邀请有单独的接口处理
    :return:
    """
    if not all([
        user_id,
        task_type in [YOUNG_HIT_TASK_TYPE.GROUP_BY, YOUNG_HIT_TASK_TYPE.DAILY_LOGIN, YOUNG_HIT_TASK_TYPE.NEW_SPECIAL]
    ]):
        return gen(CODES.PARAMS_INVALID)

    return YoungTaskService.set_today_user_completed_task(user_id, task_type)
