# coding:utf-8
"""名医大赏"""

import random

from gm_types.error import ERROR as ERROR_CODES
from gm_types.gaia import LOGIN_AUTH_TYPE
from gm_types.gaia import FAMOUS_DOCTOR_JOIN_TYPE
from gm_types.gaia import PLATFORM_CHOICES

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

from api.tool.user_tool import get_user_from_context
from api.services.activities.famous_doctors_conf import list_items
from api.services.activities.famous_doctors import FamousDoctorService
from api.tasks.famous_doctors import add_virtual_vote


@bind('api/famous_doctors/items')
def famous_doctors_items():
    """名医大赏项目列表"""

    famous_doctors_items = list_items()

    return famous_doctors_items


@bind_context('api/famous_doctors/join')
def famous_doctors_join(ctx, doc_type, doc_id, item_ids):
    """报名"""

    is_join = FamousDoctorService.is_joined(doc_type, doc_id)
    if is_join:
        if doc_type == FAMOUS_DOCTOR_JOIN_TYPE.DOCTOR:
            gen(ERROR_CODES.DOCTOR_HAS_JOIN)
        else:
            gen(ERROR_CODES.HOSPITAL_HAS_JOIN)

    FamousDoctorService.join(doc_type, doc_id, item_ids)


@bind_context('api/famous_doctors/vote')
def famous_doctors_vote(ctx, doc_type, doc_id, item_id, platform):
    """投票"""

    user = get_user_from_context(ctx)
    if not user:
        gen(ERROR_CODES.LOGIN_REQUIRED)

    registrationer = FamousDoctorService.get_registrationer_by_doc_id(doc_type, doc_id)
    if not registrationer:
        if doc_type == FAMOUS_DOCTOR_JOIN_TYPE.DOCTOR:
            gen(ERROR_CODES.DOCTOR_NOT_JOIN)
        else:
            gen(ERROR_CODES.HOSPITAL_NOT_JOIN)

    if platform in [PLATFORM_CHOICES.ANDROID, PLATFORM_CHOICES.IPHONE]:
        is_app = True
    else:
        is_app = False

    vote_info = FamousDoctorService.user_vote_info(user.id, doc_type, doc_id, item_id, is_app)
    vote_sum = vote_info["vote_sum"]
    used_vote_cnt = vote_info["used_vote_cnt"]
    vote_item_sum = vote_info["vote_item_sum"]
    used_vote_item_cnt = vote_info["used_vote_item_cnt"]

    if vote_sum - used_vote_cnt <= 0:
        gen(ERROR_CODES.FD_EXCEED_VOTE_LIMIT)

    if vote_item_sum - used_vote_item_cnt <= 0:
        gen(ERROR_CODES.FD_EXCEED_VOTE_LIMIT)

    FamousDoctorService.vote(user.id, item_id, registrationer.id, platform)
    FamousDoctorService.update_rank(doc_type, doc_id, [item_id])

    FamousDoctorService.incr_used_vote_cnt(doc_type, doc_id, user.id, item_id, is_app)
    vote_cnt, rank, last_vote = FamousDoctorService.vote_rank_and_gap(doc_type, doc_id, item_id)

    # 添加虚拟投票
    cds = [i for i in range(1, 30*60)]
    random.shuffle(cds)
    for cd in cds[:12]:
        add_virtual_vote.apply_async(
            args=(doc_type, doc_id, item_id, registrationer.id),
            countdown=cd
        )

    return {
        "rank": rank,
        "vote_cnt": vote_cnt,
        "last_vote": last_vote,

        "vote_sum": vote_sum,
        "used_vote_cnt": used_vote_cnt + 1,

        "vote_item_sum": vote_item_sum,
        "used_vote_item_cnt": used_vote_item_cnt + 1,
    }


@bind('api/famous_doctors/info')
def famous_doctors_info(doc_type, reg_id=None, doc_id=None):
    """跟人当前参选排名信息"""

    registrationer = None
    if reg_id:
        registrationer = FamousDoctorService.get_registrationer_by_id(reg_id)
    elif doc_id:
        registrationer = FamousDoctorService.get_registrationer_by_doc_id(doc_type, doc_id)

    if not registrationer:
        if doc_type == FAMOUS_DOCTOR_JOIN_TYPE.DOCTOR:
            gen(ERROR_CODES.DOCTOR_NOT_JOIN)
        else:
            gen(ERROR_CODES.HOSPITAL_NOT_JOIN)

    doc_id = registrationer.doctor_id
    item_ids = FamousDoctorService.list_doctor_item_ids(doc_type, doc_id)
    items_conf = FamousDoctorService.get_items_dict_info()
    docs_info = FamousDoctorService.list_docs_info(doc_type, [doc_id])

    items = []
    for item_id in item_ids:
        items.append(items_conf[item_id])

    wx_qr = FamousDoctorService.create_wx_qr(doc_type, doc_id, registrationer.id)

    result = {
        "items": items,
        "doc_info": docs_info.get(doc_id, {}),
        "wx_qr": wx_qr,
        "reg_id": registrationer.id,
    }

    return result


@bind('api/famous_doctors/rank_info')
def famous_doctors_rank_info(doc_type, reg_id):
    """跟人当前参选排名信息"""

    registrationer = FamousDoctorService.get_registrationer_by_id(reg_id)
    if not registrationer:
        if doc_type == FAMOUS_DOCTOR_JOIN_TYPE.DOCTOR:
            gen(ERROR_CODES.DOCTOR_NOT_JOIN)
        else:
            gen(ERROR_CODES.HOSPITAL_NOT_JOIN)

    doc_id = registrationer.doctor_id
    item_ids = FamousDoctorService.list_doctor_item_ids(doc_type, doc_id)
    docs_info = FamousDoctorService.list_docs_info(doc_type, [doc_id])

    rank_info = {}
    for item_id in item_ids:
        rank_info[str(item_id)] = FamousDoctorService.vote_rank_and_gap(doc_type, doc_id, item_id)

    result = {
        "rank_info": rank_info,
        "doc_info": docs_info.get(doc_id, {})
    }

    return result


@bind('api/famous_doctors/join_list')
def famous_doctors_join_list(doc_type, item_id, offset=0):
    """投票列表"""

    rank_info_list = FamousDoctorService.list_rank_info_by_item_id(doc_type, item_id, offset)
    doc_ids = [item["doc_id"] for item in rank_info_list]

    docs_info = FamousDoctorService.list_docs_info(doc_type, doc_ids)

    res = []
    for rank_info in rank_info_list:
        doc_info = docs_info.get(rank_info["doc_id"])
        if not doc_info:
            continue
        rank_info.update(doc_info)
        res.append(rank_info)

    res.sort(key=lambda item: -item["vote_cnt"])

    return res
