# -*- coding: UTF-8 -*-
import json
import datetime

from django.utils.dateparse import parse_datetime
from django.db.models import F
from django.db import transaction

from gm_dataquery.dataquery import DataBuilder, DataSQLQuery
from gm_dataquery.db import DB
from gm_types.error import ERROR
from gm_dataquery.dict_mixin import to_dict
from rpc.exceptions import GaiaRPCFaultException

from api.models import (
    VarietyActivity,
    Invite,
    VarietyIdol,
    InvoteStatistics,
    UserInviteCode,
    VarietyTotalInvite
)


class VarietyActivityDB(DataBuilder):

    def getval_rule(self, obj):
        return obj.rule or ''

    def getval_banner_config(self, obj, type):
        others_banner_config = obj.others_banner_config
        if others_banner_config:
            banner_config = json.loads(others_banner_config)
            return banner_config[type]
        return ''

    def getval_second_banner(self, obj):
        return self.getval_banner_config(obj, 'second_banner')

    def getval_second_url(self, obj):

        return self.getval_banner_config(obj, 'second_url')

    def getval_third_banner(self, obj):
        return self.getval_banner_config(obj, 'third_banner')

    def getval_third_url(self, obj):
        return self.getval_banner_config(obj, 'third_url')


@DB
class VarietyActivityDQ(DataSQLQuery):
    model = VarietyActivity
    data_model = VarietyActivityDB

    @classmethod
    def create(cls, **kwargs):
        others_banner_config = {
            'second_banner': kwargs.pop('second_banner', ''),
            'second_url': kwargs.pop('second_url', ''),
            'third_banner': kwargs.pop('third_banner', ''),
            'third_url': kwargs.pop('third_url', ''),
        }
        kwargs.update({'others_banner_config': json.dumps(others_banner_config)})
        if parse_datetime(kwargs["start_time"]) < datetime.datetime.now():
            raise GaiaRPCFaultException(error=ERROR.UNIVERSAL, message='开始时间不能小于当前时间', data=None)
        if parse_datetime(kwargs["end_time"]) < parse_datetime(kwargs["start_time"]):
            raise GaiaRPCFaultException(error=ERROR.UNIVERSAL, message='结束时间不能小于开始时间', data=None)
        obj = VarietyActivity.objects.create(**kwargs)
        return to_dict(obj)

    def update(self, updates, **kwargs):
        obj = self.model.objects.get(**kwargs)
        config = {}
        if obj.others_banner_config:
            config = json.loads(obj.others_banner_config)
            if 'second_banner' in updates:
                config['second_banner'] = updates['second_banner']
            if 'second_url' in updates:
                config['second_url'] = updates['second_url']
            if 'third_banner' in updates:
                config['third_banner'] = updates['third_banner']
            if 'third_url' in updates:
                config['third_url'] = updates['third_url']
            obj.others_banner_config = json.dumps(config)
            obj.save()
        else:
            config = {
                'second_banner': updates.get('second_banner', ''),
                'second_url': updates.get('second_url', ''),
                'third_banner': updates.get('third_banner', ''),
                'third_url': updates.get('third_url', ''),
            }
            updates.update({'others_banner_config': json.dumps(config)})
        return super(VarietyActivityDQ.sqlquery, self).update(updates, **kwargs)


class InviteDB(DataBuilder):

    def getval_userinvitecode(self, obj):
        invitecode = UserInviteCode.objects.filter(user_id=obj.inviter).first()
        if invitecode:
            return invitecode.code
        else:
            return ''


@DB
class InviteDQ(DataSQLQuery):
    model = Invite
    data_model = InviteDB

    def update(self, updates, **kwargs):

        super(InviteDQ.sqlquery, self).update(updates, **kwargs)

        if updates:
            if updates.get("is_online"):
                count = 1
            else:
                count = -1
            info = Invite.objects.get(id=kwargs["id"])
            return InvoteStatistics.objects.filter(create_time=info.create_time.date(),
                                                   activity=info.activity_id,
                                                   inviter=info.inviter_id).\
                    update(real_invite_cnt=F('real_invite_cnt') + count)


class VarietyIdolDB(DataBuilder):

    def getval_total_vote(self, obj):
        return obj.hera_vote_num + obj.real_vote


@DB
class VarietyIdolDQ(DataSQLQuery):
    model = VarietyIdol
    data_model = VarietyIdolDB

    def order_total_vote(self, qs, field):
        qs = qs.annotate(f_rate=F("hera_vote_num") + F("real_vote"))
        return qs, 'f_rate'

    @classmethod
    def create(cls, **kwargs):
        exist_user = VarietyIdol.objects.all().values_list("user", "activity")
        if (int(kwargs["user_id"]), int(kwargs["activity_id"])) in exist_user:
            raise GaiaRPCFaultException(error=ERROR.USER_ALREADY_EXIST, message='该账号已存在，请使用其他账号', data=None)
        obj = VarietyIdol.objects.create(**kwargs)
        return to_dict(obj)


class InvoteStatisticsDB(DataBuilder):

    def getval_total_invite_cnt(self, obj):
        return obj.hera_invite_cnt + obj.real_invite_cnt


@DB
class InvoteStatisticsDQ(DataSQLQuery):
    model = InvoteStatistics
    data_model = InvoteStatisticsDB

    def order_total_invite_cnt(self, qs, field):
        qs = qs.annotate(f_rate=F("hera_invite_cnt") + F("real_invite_cnt"))
        return qs, 'f_rate'

    @classmethod
    def create(cls, **kwargs):
        exist_user = InvoteStatistics.objects.filter(activity=kwargs["activity_id"]).values_list("inviter",
                                                                                                 "activity")
        if (int(kwargs["inviter_id"]), int(kwargs["activity_id"])) in exist_user:
            raise GaiaRPCFaultException(error=ERROR.USER_ALREADY_EXIST, message='该账号已存在，请使用其他账号', data=None)
        obj = InvoteStatistics.objects.create(**kwargs)
        return to_dict(obj)


@DB
class VarietyTotalInviteDQ(DataSQLQuery):
    model = VarietyTotalInvite
