# coding=utf-8
import datetime
import tablib

from django.core.management import BaseCommand
from api.models import (
    Service,
    Order,
)

map_validate_order_w = {
    1: 9,
    2: 6,
    3: 6,
    4: 3,
    5: 3,
    6: 3,
    7: 21,
    8: 14,
    9: 14,
    10: 7,
    11: 7,
    12: 7,
}

map_day_num = {
    1: 1,
    2: 1,
    3: 1,
    4: 4,
    5: 23,
    6: 60,
    7: 1,
    8: 1,
    9: 1,
    10: 4,
    11: 23,
    12: 60,
}

TOTAL_DAY = 30
W_GAP = 6
M_GAP = W_GAP * 2 + 1

table = (
    "美购id",
    "美购名称",
    "smart_rank值",
    "美购第1天验证订单的更美价总和相对值price1_r",
    "美购第1天验证订单的抽成总和相对值choucheng1_r",
    "美购第2天验证订单的更美价总和相对值price2_r",
    "美购第2天验证订单的抽成总和相对值choucheng2_r",
    "美购第3天验证订单的更美价总和相对值price3_r",
    "美购第3天验证订单的抽成总和相对值choucheng3_r",
    "美购第4~7天验证订单的更美价总和相对值price4_r",
    "美购第4~7天验证订单的抽成总和相对值choucheng4_r",
    "美购第8~30天验证订单的更美价总和相对值price5_r",
    "美购第8~30天验证订单的抽成总和相对值choucheng5_r",
    "美购第31~90天验证订单的更美价总和相对值price6_r",
    "美购第31~90天验证订单的抽成总和相对值choucheng6_r",
)

def get_all_weight():
    total_w = 0
    for _, val in map_validate_order_w.items():
        total_w = total_w + val

    return total_w


def tran_day_to_num(today, order_day):
    diff_day = (today - order_day).days + 1
    if 0 < diff_day <= 1:
        return 1
    elif diff_day <= 2:
        return 2
    elif diff_day <= 3:
        return 3
    elif 4 <= diff_day <= 7:
        return 4
    elif 8 <= diff_day <= 30:
        return 5
    elif 31 <= diff_day <= 90:
        return 6
    else:
        return None


def get_day_smart_rank(day):
    services = Service.objects.all()
    total_w = get_all_weight()

    filename = "./smart_rank/smart_rank" + day.strftime('%y.%m.%d') + ".xls"
    fp = open(filename, "wb")
    result = []

    max_price_dict = {}
    for service in services:
        tmp_price_dict = {}
        orders = service.order_set.filter(validated=True)
        for order in orders:
            order_day = order.validate_time
            if not order_day:
                continue

            map_w_key = tran_day_to_num(day, order_day)
            if map_w_key in map_validate_order_w:
                if map_w_key in tmp_price_dict:
                    tmp_price_dict[map_w_key] = tmp_price_dict[map_w_key] + float(order.service_price)
                else:
                    tmp_price_dict[map_w_key] = float(order.service_price)

                map_w_key = map_w_key + W_GAP
                if map_w_key in tmp_price_dict:
                    tmp_price_dict[map_w_key] = tmp_price_dict[map_w_key] + float(order.discount)
                else:
                    tmp_price_dict[map_w_key] = float(order.discount)

        for key, val in tmp_price_dict.items():
            if key in max_price_dict:
                if tmp_price_dict[key] > max_price_dict[key]:
                    max_price_dict[key] = tmp_price_dict[key]
            else:
                max_price_dict[key] = tmp_price_dict[key]

    for service in services:
        orders = service.order_set.filter(validated=True)
        order_price_dict = {}
        for order in orders:
            order_day = order.validate_time
            if not order_day:
                continue

            map_w_key = tran_day_to_num(day, order_day)
            if map_w_key in map_validate_order_w:
                if map_w_key in order_price_dict:
                    order_price_dict[map_w_key] = order_price_dict[map_w_key] + float(order.service_price)
                else:
                    order_price_dict[map_w_key] = float(order.service_price)

                map_w_key = map_w_key + W_GAP
                if map_w_key in order_price_dict:
                    order_price_dict[map_w_key] = order_price_dict[map_w_key] + float(order.discount)
                else:
                    order_price_dict[map_w_key] = float(order.discount)

        if not order_price_dict:
            continue

        F_r = {}
        total_rank = 0
        for i in range(1, M_GAP):
            if i in order_price_dict:
                service_price_total = order_price_dict.get(i, 0)
                max_price = max_price_dict.get(i, 0)
                if max_price:
                    F_r[i] = service_price_total / max_price
                else:
                    F_r[i] = 0
            else:
                F_r[i] = 0

            total_rank = total_rank + F_r[i] * map_validate_order_w[i]

        smart_rank = total_rank / total_w
        if order_price_dict and smart_rank:
            data = [service.id, service.name.encode('utf8'), smart_rank]
            for i in range(1, W_GAP + 1):
                data.append(F_r[i])
                data.append(F_r[i + W_GAP])
            result.append(data)

    Data = tablib.Dataset(*result, headers=table)
    fp.write(Data.xls)
    fp.close()


class Command(BaseCommand):

    def handle(self, *args, **options):
        today = datetime.datetime.today()
        today = datetime.datetime(today.year, today.month, today.day, 0, 0, 0)
        for i in range(1, TOTAL_DAY + 1):
            get_day_smart_rank(today)
            today = today - datetime.timedelta(days=1)