# coding=utf-8
# author:gao ming ming
# modify date:2019.05.16

from __future__ import unicode_literals, absolute_import, print_function

import datetime
import random
import re

from django.utils import timezone
from django.db import transaction

from api.models import (
    YoungDoctorRegistrationer,
    YoungDocVote,
    Doctor,
)


from api.tool.user_tool import get_user_from_context, filter_user_nick_name, get_portrait_by_user
from api.tool.verification_code import anti_brute, VerifiedCode
from doctor.models import DoctorRegister
from rpc.cache import yd_vote
from gm_types.gaia import DOCTOR_TYPE


from rpc.context import get_rpc_remote_invoker
from rpc.decorators import bind, bind_context
from rpc.tool.error_code import gen, CODES as ERROR_CODES
from rpc.tool.log_tool import info_logger
from api.tool.datetime_tool import get_seconds_left_to_end_of_day, get_timestamp_or_none


url_prefix = 'activity/young_doc/'

DAY_TOTAL_LIMIT = 10     # 总共票数/人/天
DAY_REG_LIMIT = 3        # 一个医生的一个奖项, 投票限制 /人/天

@bind_context(url_prefix + 'user_vote')
def user_vote(ctx, user_id, user_type, reg_ids):
    '''
        用户投票接口
    param user_id: str 用户id
    param user_type: int 用户类型
    param reg_ids: list 报名表中id
    
    '''

    result = {
        'error': 0,
        'message': '',
    }
    if not reg_ids:
        return result

    reg_ids = list(set(reg_ids))
    votes = YoungDocVote.objects.filter(user_id=user_id, user_type=user_type, day=datetime.date.today())
    day_total_count = votes.count()
    reach_hold = (day_total_count + len(reg_ids)) > DAY_TOTAL_LIMIT
    if not reach_hold:
        for r_id in reg_ids:
            reg_count = votes.filter(registrationer_id=r_id).count()
            if reg_count >= DAY_REG_LIMIT:
                reach_hold = True
                break

    if reach_hold:
        result['error'] = 1
    	result['message'] = '已达投票上线明天再来!'
    	return result

    # 投票并更新总票数
    try:
        for reg_id in reg_ids:
            YoungDocVote.do_vote(user_id, user_type, reg_id)	
    except Exception as e:
        raise e
    return result


@bind_context(url_prefix + 'enter')
def doctor_registration(ctx,doctor_id,award_ids,doctor_type):
	'''医生报名'''
        user = get_user_from_context(ctx)
        if not user:
            gen(ERROR_CODES.LOGIN_REQUIRED)
        u_d_id = user.doctor.id
        if u_d_id != doctor_id:
            gen(ERROR_CODES.ACCOUNT_SESSION_INCON)
	result={
	    'error': 0,
	    'message': '报名成功',
	    'data': {}
	}
        is_enter = YoungDoctorRegistrationer.is_entered_by_doc_id(doctor_id)
        if is_enter:
            return {
                'error': 1,
                'message': '已报名, 不可重复报名'
            }
        res, reason = YoungDoctorRegistrationer.enter_at_award_ids(doctor_id, doctor_type, award_ids)
        if not res:
            return {
                'error': 1,
                'message': reason
            }

	return result


def fmt_rank_show(award_id, doctor_ids):
    '''
    格式化排行榜信息
    '''
    result = []
    if not doctor_ids:
        return result

    qs = YoungDoctorRegistrationer.objects.filter(award_id=award_id, doctor_id__in=doctor_ids).select_related()
    for item in qs:
        tem = {}
        item_doctor = item.doctor
        tem['doctor_id'] = item_doctor.id
        tem['doctor_name'] = item_doctor.name
        tem['reg_id'] = item.id
        tem['portrait'] = item_doctor.portrait
        tem['vote_count'] = item.final_count
        tem['doc_hospital_id'] = item_doctor.hospital_id
        tem['doctor_type'] = item_doctor.doctor_type
        if item_doctor.doctor_type == DOCTOR_TYPE.OFFICER:
            doc_hos = item_doctor.hospital
            if doc_hos:
                tem.update({
                    'doctor_name': doc_hos.name
                })
        result.append(tem)
    result.sort(key=lambda x:doctor_ids.index(x['doctor_id']))
    return result


@bind_context(url_prefix + 'rank_list')
def rank_list(ctx, award_id=None, offset=None, limit=None):
	'''
	排行榜
        award_id: 奖项id
        offset: 偏移量
        limit: page_size

        @return: {
            '0': [{}, {}],
        }
	'''
        result = {}
        rank_map = YoungDoctorRegistrationer.get_rank_info(award_id, offset, limit)
        for k, v in rank_map.items():
           result[k] = fmt_rank_show(k, v)

	return result


@bind_context(url_prefix + 'info_show')
def compete_info_show(ctx, doctor_id):
    '''
    医生拉票页面, 数据接口
    '''
    try:
        doc_obj = Doctor.objects.get(id=doctor_id)
    except:
        gen(ERROR_CODES.DOCTOR_NOT_FOUND)

    doc_info = {
        'doctor_id': doc_obj.id,
        'doctor_name': doc_obj.name,
        'portrait': doc_obj.portrait,
        'introduction': doc_obj.introduction,
        'doctor_type': doc_obj.doctor_type,
        'doc_hospital_id': doc_obj.hospital_id,
    }
    if doc_obj.doctor_type == DOCTOR_TYPE.OFFICER:
        doc_hos = doc_obj.hospital
        if doc_hos:
            doc_info.update({
                'doctor_name': doc_hos.name,
                'introduction': doc_hos.description
            })
    award_list = []
    doc_awards = YoungDoctorRegistrationer.objects.filter(doctor_id=doctor_id)
    for da in doc_awards:
        rank, gap = YoungDoctorRegistrationer.rank_and_gap(da.doctor_id, da.award_id)
        awa_item = {}
        awa_item['reg_id'] = da.id
        awa_item['id'] = da.award_id
        awa_item['rank'] = rank
        awa_item['gap'] = gap
        award_list.append(awa_item)
    result = {
        'doctor_info': doc_info,
        'award_list': award_list,
    }
    return result
