# encoding=utf-8
import math
from datetime import date, timedelta

from django.db import transaction
from rpc.decorators import bind_context
from api.models import Service, ManualIndex
from api.tool.smart_rank import WeightCache, SmartRankCalculate
from statistic.models import StatisticServiceSmartRankV3


uri_pre = 'hera/smart_rank'


@bind_context(uri_pre + '/get_weight')
def get_smart_rank_weigt(ctx):
    weight = WeightCache()
    return weight.get()


@bind_context(uri_pre + '/set_weight')
def get_smart_rank_weigt(ctx, deploy_info):
    weight = WeightCache()
    return weight.set(value=deploy_info)


@transaction.atomic
@bind_context(uri_pre + '/set_manual_index')
def set_manual_index(ctx, hospital, doctor, service, manual_index):
    if hospital is not None:
        servcie_ids = list(Service.objects.filter(doctor__hospital_id=hospital).values_list('id', flat=True))

    elif doctor is not None:
        servcie_ids = list(Service.objects.filter(doctor_id=doctor).values_list('id', flat=True))
    else:
        servcie_ids = map(int, service)
    change_data = []

    has_services = ManualIndex.objects.filter(service_id__in=servcie_ids)
    has_service_ids = has_services.values_list('service_id', flat=True)
    has_services.update(index=manual_index)
    for service_id in set(servcie_ids) - set(has_service_ids):
        m = ManualIndex.objects.create(service_id=service_id, index=manual_index)
        change_data.append(m.id)
    change_data.extend(has_service_ids)
    return {
        'change_data': change_data,
    }


@bind_context(uri_pre + '/get_smart_rank')
def get_smart_rank_detail(ctx, service_id):
    service = Service.objects.get(id=service_id)
    s = SmartRankCalculate(service=service, from_cache=False)
    return s.get_detail_value()

@bind_context(uri_pre + '/smartrank_detail')
def smartrank_detail(ctx, smartrankv3_id, service__doctor__hospital__city__id):
    service_v3 = StatisticServiceSmartRankV3.objects.get(id=smartrankv3_id)

    yesterday = date.today() - timedelta(days=2)
    service_v3_datas = StatisticServiceSmartRankV3.objects.filter(
        stat_date=yesterday, service__doctor__hospital__city__id=service__doctor__hospital__city__id).order_by('-service_detail_pv_30')
    count = service_v3_datas.count()
    pos_top5 = int(math.ceil(count * 0.2))
    datas = service_v3_datas[:pos_top5]
    consult_value_data, ctr_value_data = [], []
    for data in datas:
        consult_value_data.append(data.get_consult_value())
        ctr_value_data.append(data.get_ctr_value())
    if consult_value_data:
        consult_median_value = get_median(consult_value_data)
    else:
        consult_median_value = 0
    if ctr_value_data:
        ctr_median_value = get_median(ctr_value_data)
    else:
        ctr_median_value = 0

    return {
        'service_id': service_v3.service.id,
        'consult_value': service_v3.get_consult_value(),
        'ctr_value': service_v3.get_ctr_value(),
        'discount_value': service_v3.get_discount_value(),
        'cpt_value': service_v3.get_cpt_value(),
        'cpc_price': service_v3.get_cpc_price(),
        'consult_median_value': consult_median_value,
        'ctr_median_value': ctr_median_value
    }

def get_median(data):
    data.sort()
    half = len(data) // 2
    return (data[half] + data[~half]) / 2
