# coding=utf-8
from __future__ import unicode_literals, absolute_import, print_function

import datetime
import json
from django.db import transaction
from django.db.models import Sum

from gm_types.error import ERROR
from gm_types.gaia import (
    POINTS_TYPE,
    POINTS_OPERATION
)
from gm_types.hera import CONFIG
from gm_types.gaia import SPECIAL_MODULE
from api.models import User
from api.models import Order
from api.models import Special, SpecialLayout, SpecialStorey
from api.tool.push_tool import share_push
from api.tool.user_tool import filter_user_nick_name, get_user_by_id
from api.tool.user_tool import get_user_from_context

from point.models import PointsInfo, Points
from point.point_tool import get_points_by_user_type
from point.consts import points_reason_rule
from point.manager import exchange_manager, lottery_manager, point_activity_manager

from rpc.tool.error_code import gen, CODES
from rpc.decorators import bind_context, bind
from rpc.tool.log_tool import logging_exception

from point import data_query


@bind_context('api/points/user_point', login_required=True)
def get_user_point(ctx):
    user = get_user_from_context(ctx)
    import point
    point = point.get_point_for(user)
    return point


@bind_context('api/points/user_points', login_required=True)
def get_user_points(ctx, points_type, start_num=0, count=10):
    user = get_user_from_context(ctx)
    points = get_points_by_user_type(user, points_type, start_num, count)
    result = []
    for point in points:
        result.append({
            'id': point.id,
            'user_id': point.user_id,
            'operation': point.operation,
            'reason': point.reason,
            'number': point.number,
        })
    return result


@bind_context('api/user/points_info', login_required=True)
def user_points_info(ctx):
    user = get_user_from_context(ctx)
    data = {'history': [],
            'points_amount': 0,
            'has_verified': Points.objects.filter(user=user, reason=POINTS_TYPE.WAS_INVITE).exists()}
    my_points_history = Points.objects.filter(user=user)

    # 统计积分总数
    add_points = my_points_history.filter(operation=POINTS_OPERATION.ADD)
    remove_points = my_points_history.filter(operation=POINTS_OPERATION.REMOVE)
    add_points_amount = add_points.aggregate(points_amount=Sum('number'))['points_amount'] or 0
    remove_points_amount = remove_points.aggregate(points_amount=Sum('number'))['points_amount'] or 0
    data['points_amount'] = add_points_amount - remove_points_amount

    # 积分详情
    # history_dict = {u'0': [{}, {}, u'1': [{}, {}]]
    history_dict = {}
    for points_record in my_points_history:
        history_dict.setdefault(points_record.reason, [])
        history_dict[points_record.reason].append(points_record)

    for reason, points_records in history_dict.iteritems():
        if reason == POINTS_TYPE.INVITE:
            for points_record in points_records:
                data['history'].append({'img_url': 'http://pic.igengmei.com/2014/06/05/38f3a8ab02-thumb',
                                        'reason': u'邀请[{}]加入'.format(filter_user_nick_name(points_record.link_user)),
                                        'result': "+{}".format(points_record.number),
                                        'operation': POINTS_OPERATION.ADD})
        elif reason == POINTS_TYPE.WAS_INVITE:
            for points_record in points_records:
                data['history'].append({'img_url': 'http://pic.igengmei.com/2014/06/05/38f3a8ab02-thumb',
                                        'reason': u'被[{}]邀请加入'.format(filter_user_nick_name(points_record.link_user)),
                                        'result': "+{}".format(points_record.number),
                                        'operation': POINTS_OPERATION.ADD})
        elif reason == POINTS_TYPE.SHARE:
            for points_record in points_records:
                reason = points_record.link_topic.ask[:6] if points_record.link_topic else u''
                data['history'].append({
                    'img_url': 'http://pic.igengmei.com/2014/06/09/2653f9b52c-thumb',
                    'reason': u'发表经验帖[{}...]'.format(reason),
                    'result': u'+{}'.format(points_record.number),
                    'operation': POINTS_OPERATION.ADD})
        elif reason == POINTS_TYPE.BUY_SERVICE:
            for points_record in points_records:
                reason = points_record.link_order.service.name[:6] if points_record.link_order else u''
                data['history'].append({
                    'img_url': 'http://pic.igengmei.com/2014/06/25/22b1b35910-thumb',
                    'reason': u'购买美购[{}...]'.format(reason),
                    'result': u'-{}'.format(points_record.number),
                    'operation': POINTS_OPERATION.REMOVE})
        elif reason == POINTS_TYPE.CANCEL_ORDER:
            for points_record in points_records:
                reason = points_record.link_order.service.name[:6] if points_record.link_order else u''
                data['history'].append({
                    'img_url': 'http://pic.igengmei.com/2014/06/25/22b1b35910-thumb',
                    'reason': u'取消订单[{}...]'.format(reason),
                    'result': u'+{}'.format(points_record.number),
                    'operation': POINTS_OPERATION.ADD})
        elif reason == POINTS_TYPE.STAR:
            for points_record in points_records:
                reason = points_record.link_topic.ask[:6] if points_record.link_topic else u''
                data['history'].append({
                    'img_url': 'http://pic.igengmei.com/2014/06/09/2653f9b52c-thumb',
                    'reason': u'[{}...]加精华'.format(reason),
                    'result': u'+{}'.format(points_record.number),
                    'operation': POINTS_OPERATION.ADD})
        elif reason == POINTS_TYPE.HOT:
            for points_record in points_records:
                reason = points_record.link_topic.ask[:6] if points_record.link_topic else u''
                data['history'].append({
                    'img_url': 'http://pic.igengmei.com/2014/06/09/2653f9b52c-thumb',
                    'reason': u'[{}...]加热门'.format(reason),
                    'result': u'+{}'.format(points_record.number),
                    'operation': POINTS_OPERATION.ADD})
        elif reason == POINTS_TYPE.REGISTER:
            for points_record in points_records:
                data['history'].append({'img_url': 'http://pic.igengmei.com/2014/06/05/38f3a8ab02-thumb',
                                        'reason': u'注册送积分',
                                        'result': u'+{}'.format(points_record.number),
                                        'operation': POINTS_OPERATION.ADD})
        elif reason == POINTS_TYPE.RATING:
            for points_record in points_records:
                data['history'].append({'img_url': 'http://pic.igengmei.com/2014/06/09/2653f9b52c-thumb',
                                        'reason': u'去给所长好评',
                                        'result': u'+{}'.format(points_record.number),
                                        'operation': POINTS_OPERATION.ADD})
        elif reason == POINTS_TYPE.VOTE_OTHER:
            data['history'].append({'img_url': 'http://pic.igengmei.com/2014/06/09/f485c87700-thumb',
                                    'reason': u'累计赞别人{}次'.format(len(points_records)),
                                    'result': u'+{}'.format(sum(record.number for record in points_records)),
                                    'operation': POINTS_OPERATION.ADD})
        elif reason == POINTS_TYPE.VOTE:
            data['history'].append({'img_url': 'http://pic.igengmei.com/2014/06/09/f485c87700-thumb',
                                    'reason': u'累计被赞{}次'.format(len(points_records)),
                                    'result': u'+{}'.format(sum(record.number for record in points_records)),
                                    'operation': POINTS_OPERATION.ADD})
        elif reason == POINTS_TYPE.REPLY_OTHER:
            data['history'].append({'img_url': 'http://pic.igengmei.com/2014/06/09/2653f9b52c-thumb',
                                    'reason': u'累计回复别人{}次'.format(len(points_records)),
                                    'result': u'+{}'.format(sum(record.number for record in points_records)),
                                    'operation': POINTS_OPERATION.ADD})
        elif reason == POINTS_TYPE.LOGIN:
            data['history'].append({'img_url': 'http://pic.igengmei.com/2014/06/24/6e59068855-thumb',
                                    'reason': u'累计登录{}天'.format(len(points_records)),
                                    'result': u'+{}'.format(sum(record.number for record in points_records)),
                                    'operation': POINTS_OPERATION.ADD})
        elif reason == POINTS_TYPE.REPLIED:
            data['history'].append({'img_url': 'http://pic.igengmei.com/2014/06/09/2653f9b52c-thumb',
                                    'reason': u'累计被回复{}次'.format(len(points_records)),
                                    'result': u'+{}'.format(sum(record.number for record in points_records)),
                                    'operation': POINTS_OPERATION.ADD})
        elif reason == POINTS_TYPE.APP:
            data['history'].append({'img_url': 'http://pic.igengmei.com/2014/06/09/6f5c44b8cc-thumb',
                                    'reason': u'下载精品应用',
                                    'result': u'+{}'.format(sum(record.number for record in points_records)),
                                    'operation': POINTS_OPERATION.ADD})
        elif reason == POINTS_TYPE.JOIN_ACTIVITY:
            data['history'].append({'img_url': 'http://pic.igengmei.com/2014/06/09/6f5c44b8cc-thumb',
                                    'reason': u'参加免费活动',
                                    'result': u'-{}'.format(sum(record.number for record in points_records)),
                                    'operation': POINTS_OPERATION.REMOVE})

    return data


@bind_context("api/user/task/points", login_required=True)
def task_points(ctx, platform):
    # todo 旧版美分页面 , 低于7.6.20版本
    result = {'error': 0, 'message': u''}
    user = get_user_from_context(ctx)

    point_info = PointsInfo(user)
    point_task = point_info.get_task_list()

    result['tasks'] = []
    task_point_string = '<em>+{number}</em>美分'

    for task in point_task:

        if platform == 'android' and task['point_type'] == POINTS_TYPE.RATING:
            continue

        # Todo gengmei协议确定
        task = {
            'name': task['title'],
            'points': task_point_string.format(number=task['number']),
            'desc': task['description'],
            'detail': task['detail'],
            'status': task['status'],
            'url': task['url'],
        }
        result['tasks'].append(task)

    return result


@bind_context("api/user/task/points_detail", login_required=True)
def points_detail(ctx, start_num, count):
    result = {'error': 0, 'message': u''}
    user = get_user_from_context(ctx)

    point_info = PointsInfo(user)
    point_list = point_info.get_points_list(start_num, count)

    result['points_list'] = []
    point_add_string = '<em>+{number}</em>美分'
    point_plus_string = '<em>-{number}</em>美分'

    for point in point_list:
        title = POINTS_TYPE.getDesc(point['reason'])
        if point['reason'] == POINTS_TYPE.PAY:
            order = Order.objects.get(id=point['link_order_id'])
            title = '{}美分返还'.format(order.servicesnapshot.name)
        if point['operation'] == 'add':
            show_string = point_add_string
        else:
            show_string = point_plus_string
            # ugly hack
            if point['link_order_id'] and Order.objects.get(id=point['link_order_id']).points:
                title = u'兑换礼品支出'

        point = {
            'date': point['add_time'],
            'title': title,
            'point': show_string.format(number=point['number']),
        }
        result['points_list'].append(point)

    return result


@bind('api/points/change')
def add_points(user_id, reason_type, operation, link_user=None, number=0):
    try:
        user = User.objects.get(pk=user_id)
    except User.DoesNotExist:
        return gen(ERROR.USER_NOT_FOUND)

    if not number:
        try:
            number = points_reason_rule[reason_type]
        except KeyError:
            return gen(ERROR.VALID_POINT_TYPE)

    if link_user:
        try:
            link_user = User.objects.get(pk=link_user)
        except User.DoesNotExist:
            link_user = None

    if operation not in POINTS_OPERATION:
        return gen(ERROR.VALID_POINT_OPERATION)

    with transaction.atomic():
        p = Points(
            user=user,
            operation=operation,
            reason=reason_type,
            number=number,
            link_user=link_user,
        )
        p.save()

        if operation == POINTS_OPERATION.ADD:
            user.person.points += number
        elif operation == POINTS_OPERATION.REMOVE:
            user.person.points -= number
        user.person.save()

    return number


@bind('api/points/share/bonus')
def bonus_share_points(user_id, msg):
    """
    分享有礼获得美分, 这段代码在双十一大促后应被废弃
    :param ctx:
    :param user_id:
    :return:
    """
    user = User.objects.get(pk=int(user_id))
    number = points_reason_rule[POINTS_TYPE.SHARE_DOUBLE_11]
    num = 0
    with transaction.atomic():
        p = Points(
            user=user,
            operation=POINTS_OPERATION.ADD,
            reason=POINTS_TYPE.SHARE_DOUBLE_11,
            number=number,
            link_user=user,
        )
        p.save()

        user.person.points += number
        user.person.save()
        num = p.number

    share_push(user_id, msg)
    return {
        'number': num
    }


@bind_context('api/pointsinfo/add', login_required=True)
def pointsinfo_operate(ctx, reason_type):
    user = get_user_from_context(ctx)

    if reason_type not in POINTS_TYPE:
        return gen(CODES.OPERATION_NOT_SUPPORTED)

    pi = PointsInfo(user)
    points = pi.points_operate(operation=POINTS_OPERATION.ADD, reason=reason_type)
    return {'points': points}


@bind_context('api/point/history')
def get_point_history(ctx, reason):
    user = get_user_from_context(ctx)
    point_history = Points.objects.filter(user=user, reason=reason)
    point_history = [item.to_dict() for item in point_history]
    return list(point_history)


@bind_context('api/pointsinfo/get_daily_value', login_required=True)
def get_point_daily_value(ctx):
    user = get_user_from_context(ctx)
    point_today = Points.objects.filter(user=user, add_time__gte=datetime.date.today())
    current_v = 0
    for point_i in point_today:
        if point_i.operation == POINTS_OPERATION.ADD:
            current_v += point_i.number
        else:
            current_v -= point_i.number
    return current_v


@bind('api/point/add')
def update_point_add(user_id, point_type, point_v):
    if point_type not in POINTS_TYPE:
        return gen(CODES.OPERATION_NOT_SUPPORTED)
    user = get_user_by_id(user_id)
    pi = PointsInfo(user)
    points = pi.points_operate(reason=point_type, num=point_v)
    return {'points': points}


@bind_context('api/point/exchange/get_exchange_item_list')
def get_exchange_item_list(ctx, point_activity_id):
    item_list = exchange_manager.get_exchange_item_list(point_activity_id)

    return {
        'exchange_item_list': item_list
    }


@bind_context('api/point/exchange/get_exchange_item_detail', login_required=True)
def get_exchange_item_detail(ctx, point_activity_goods_id):
    user = get_user_from_context(ctx)

    item_detail = exchange_manager.get_exchange_item_detail(point_activity_goods_id, user.id)

    return {
        'exchange_item_detail': item_detail
    }


@bind_context('api/point/exchange/try_get_exchange_item', login_required=True)
def try_get_exchange_item(ctx, point_activity_goods_id):
    user = get_user_from_context(ctx)

    goods_claim_result, goods_type = exchange_manager.try_get_exchange_item(point_activity_goods_id, user)

    return {
        'claim_goods_type': goods_type,
        'goods_claim_result': goods_claim_result
    }


@bind_context('api/point/lottery/get_lottery_item_list')
def get_lottery_item_list(ctx, point_activity_id, special_id=None):
    result = {}
    if special_id:
        special = SpecialLayout.objects.filter(special_id=special_id, module=SPECIAL_MODULE.TURNTABLE).first()
        if special:
            related = json.loads(special.related)
            for img in related.get('image_data', []):
                result[img['str_name']] = img['img']
            point_activity_id = related.get('lottery_id')
            result['is_show'] = special.is_visible
    valid_point_activity_id, lottery_cost, item_list, lottery_record = lottery_manager.get_lottery_item_list(
        point_activity_id)
    result.update({
        'point_activity_id': valid_point_activity_id,
        'lottery_cost': lottery_cost,
        'lottery_item_list': item_list,
        'lottery_record': lottery_record,
    })
    return result


@bind_context('api/point/lottery/draw_lottery', login_required=True)
def draw_lottery(ctx, point_activity_id, special_id=None):
    user = get_user_from_context(ctx)
    result = lottery_manager.draw_lottery(point_activity_id, user, special_id=special_id)

    return {
        "lottery_result": result["lottery_result"],
        "selected_point_activity_goods_info": result["selected_point_activity_goods_info"]
    }


@bind_context('api/point/get_activity_record', login_required=True)
def draw_lottery(ctx, count=10, start=0):
    user = get_user_from_context(ctx)
    result = point_activity_manager.get_user_activity_record(user.id, start, count)

    return {
        "activity_record_result": result,
    }


@bind_context('api/point/get_point_mall_config')
def get_activity_ids(ctx):
    result = point_activity_manager.get_point_mall_config()

    return {
        "point_activity_key_to_id": result,
    }


@bind_context('api/point/lottery/new_get_lottery_item_list')
def get_lottery_item_list(ctx, special_id=None, _data=None):
    # 专题新增加配置多个转盘
    data = []

    special = SpecialLayout.objects.filter(special_id=special_id, module=SPECIAL_MODULE.TURNTABLE).first()

    if special_id and special and not _data:  # 非楼层里面的转盘数据
        related = json.loads(special.related)
        for each in related:
            result = {}
            for img in each.get('image_data', []):
                result[img['str_name']] = img['img']
            point_activity_id = each.get('lottery_id')
            result['is_show'] = special.is_visible

            valid_point_activity_id, lottery_cost, item_list, lottery_record = lottery_manager.get_lottery_item_list(
                point_activity_id)

            result.update({
                'point_activity_id': valid_point_activity_id,
                'lottery_cost': lottery_cost,
                'lottery_item_list': item_list,
                'lottery_record': lottery_record,
            })
            data.append(result)

    if special_id and _data:  # 楼层里面的数据
        result = {}

        for img in _data.get('data'):
            result[img['str_name']] = img['img']

        point_activity_id = _data.get('lottery_id')
        result['is_show'] = special.is_visible if special else True
        valid_point_activity_id, lottery_cost, item_list, lottery_record = lottery_manager.get_lottery_item_list(
            point_activity_id)
        result.update({
            'point_activity_id': valid_point_activity_id,
            'lottery_cost': lottery_cost,
            'lottery_item_list': item_list,
            'lottery_record': lottery_record,
        })
        data.append(result)

    return {
        'data': data
    }