# coding=utf-8
import random
import string
import threading

from django.conf import settings
from django.contrib.auth.models import User
from django.utils import timezone
from gm_types.gaia import APP_CONFIG_TYPE, RED_PACKET, TRANS_STATUS, TRANS_ACTION, TRANS_EVENT

from api.tool.user_tool import get_user_from_context
from rpc.decorators import bind, bind_context
from rpc.tool.error_code import gen, CODES

from cashback.models import Dialog, DialogAction, TransactionLog, TransactionRemark, CashbackManager, Registration


@bind('api/packet/amount')
def get_packet_amount(packet_type=RED_PACKET.CASH):
    """
    获取当前红包金额
    :param packet_type:
    :return:
    """
    packet = Dialog.objects.get(type=packet_type).packet
    if packet:
        return packet.amount
    return 0.0


@bind('api/packet/dialog')
def get_cash_packet(device_id):
    """
    获取红包弹窗类型
    :param device_id:
    :return:
    """
    Dialog.initialize()
    accepted = DialogAction.objects.filter(dialog__type=RED_PACKET.CASH,
                                           action=DialogAction.OPENED, device_id=device_id).exists()
    rejected = DialogAction.objects.filter(dialog__type=RED_PACKET.CASH,
                                           action=DialogAction.CANCELED, device_id=device_id).count() > 3

    cash_packet = Dialog.objects.get(type=RED_PACKET.CASH).packet
    invite_packet = Dialog.objects.get(type=RED_PACKET.INVITE).packet

    if not accepted and not rejected and cash_packet is not None:
        return APP_CONFIG_TYPE.CASH_PACKET
    elif invite_packet is not None:
        return APP_CONFIG_TYPE.INVITE_PACKET
    else:
        return None


@bind_context('api/packet/callback')
def cashback_packet_callback(ctx, device_id, packet_type, action):
    """

    :param ctx:
    :param device_id:
    :param packet_type:
    :param action:
    :return:
    """
    user = get_user_from_context(ctx)
    dialog = Dialog.objects.get(type=packet_type)
    packet = dialog.packet

    """
    没有红包在线的时候
    """
    if not packet:
        return {
            "id": -1,
            "amount": 0.0
        }

    DialogAction.objects.create(dialog=dialog, action=action, device_id=device_id)

    """
    红包弹窗被关闭，或用户未登录
    """
    if action == DialogAction.CANCELED:
        return None

    if action == DialogAction.OPENED:

        if user is None:
            return gen(CODES.LOGIN_REQUIRED)

        """
        用户打开邀请红包
        """
        if packet_type == RED_PACKET.INVITE:
            return dialog.packet.data

        # 用户打开现金红包
        elif packet_type == RED_PACKET.CASH:
            # 检查是否已领取现金红包
            if TransactionLog.objects.filter(user=user, remark__event_type=TRANS_EVENT.CASH_PACKET).exists():
                # todo： 现金红包已领取
                return gen(CODES.CASH_PACKET_ALREADY_RECEIVED)

            else:
                # 红包领取成功
                remark = TransactionRemark.objects.create(event_type=TRANS_EVENT.CASH_PACKET, packet_id=packet.id)
                TransactionLog.objects.create(user=user,
                                              amount=packet.amount,
                                              type=TRANS_ACTION.DEPOSIT,
                                              state=TRANS_STATUS.PASS,
                                              remark=remark)
                return packet.data


@bind_context('api/packet/withdraw', login_required=True)
def cashback_withdraw(ctx):
    """

    :param ctx:
    :return:
    """
    user = get_user_from_context(ctx)

    with threading.Lock():
        balance = CashbackManager.getUserBalance(user)
        if balance < settings.CASHBACK_WITHDRAW_UNIT:
            # 余额不足，无法提现
            return gen(CODES.NOT_SUFFICIENT_FUNDS)

        cdkey = ''.join(random.SystemRandom().choice(string.ascii_letters + string.digits) for _ in range(32))
        remark = TransactionRemark.objects.create(event_type=TRANS_EVENT.WITHDRAW, cdkey=cdkey)
        transaction = TransactionLog.objects.create(user=user,
                                                    amount=settings.CASHBACK_WITHDRAW_UNIT * -1,
                                                    type=TRANS_ACTION.WITHDRAW,
                                                    state=TRANS_STATUS.WAIT,
                                                    remark=remark)

        # 提现已提交
        return transaction.data


@bind_context('api/packet/transaction', login_required=True)
def cashback_translation_log(ctx, type=None):
    """
    流水记录
    :param ctx:
    :param type:
    :return:
    """
    user = get_user_from_context(ctx)
    queryset = TransactionLog.objects.filter(user=user)
    if type is not None:
        queryset = queryset.filter(type=type)

    balance = CashbackManager.getUserBalance(user)
    return {
        "balance": balance,
        "can_withdraw": balance >= settings.CASHBACK_WITHDRAW_UNIT,
        "transaction": [ts.data for ts in queryset]
    }


@bind('api/packet/registration')
def cashback_registration(inviter_id, invitee_id, device_id="", device_type=""):
    """

    :param inviter_id:
    :param invitee_id:
    :param device_id:
    :param device_type:
    :return:
    """
    inviter = User.objects.get(pk=inviter_id)
    invitee = User.objects.get(pk=invitee_id)
    Registration.objects.create(inviter=inviter, invitee=invitee,
                                device_id=device_id, device_type=device_type,
                                register_time=timezone.now())