# coding:utf-8
from gm_dataquery.dataquery import DataSQLQuery, DataBuilder
from gm_dataquery.db import DB
from gm_dataquery.dict_mixin import to_dict

from rpc.exceptions import GaiaRPCFaultException
from variety_show.models import Idol, YoungBaseInfo
from variety_show.models.young_models import TaskConfig, YoungTag, IdolTag


class IdolDB(DataBuilder):

    def getval_total_votes(self, obj):
        return obj.real_votes + obj.fake_votes + obj.hera_votes

    def getval_tag_v3_ids(self, obj):
        return list(IdolTag.objects.filter(
            idol_id=obj.id,
            is_online=True
        ).values_list("tag_id", flat=True))


@DB
class IdolDQ(DataSQLQuery):
    model = Idol
    data_model = IdolDB

    def create(self, **kwargs):
        kwargs.pop("total_votes", None)
        tag_v3_ids = kwargs.pop("tag_v3_ids", [])
        group_id = kwargs.get('group_id', None)
        kwargs['group_id'] = group_id or 0
        if group_id:
            has_other_idol = self.model.objects.filter(group_id=group_id).exists()
            if has_other_idol:
                raise GaiaRPCFaultException(
                    error=-1,
                    message='小组id: {group_id} 已经被其他学员关联'.format(group_id=group_id),
                    data=None,
                )
        idol_obj = self.model.objects.create(**kwargs)
        if tag_v3_ids:
            IdolTag.objects.bulk_create([
                IdolTag(idol_id=idol_obj.id, tag_id=tag_id)
                for tag_id in tag_v3_ids
            ])

        return to_dict(idol_obj)

    def update(self, updates, **kwargs):
        tag_v3_ids = updates.pop("tag_v3_ids", None)

        idol_obj = self.model.objects.get(**kwargs)

        group_id = updates.get('group_id', None)
        if group_id:
            has_other_idol = self.model.objects.filter(group_id=group_id).exclude(id=idol_obj.id).exists()
            if has_other_idol:
                raise GaiaRPCFaultException(
                    error=-1,
                    message='小组id: {group_id} 已经被其他学员关联'.format(group_id=group_id),
                    data=None,
                )
        updates['group_id'] = updates.pop('group_id', None) or 0
        self.model.objects.filter(**kwargs).update(**updates)

        self._update_tag_v3(idol_obj.id, tag_v3_ids)

        return 1

    def _update_tag_v3(self, idol_id, tags):
        if tags == [] or tags:
            IdolTag.objects.filter(idol_id=idol_id).delete()

        if tags:
            IdolTag.objects.bulk_create([
                IdolTag(idol_id=idol_id, tag_id=tag_id)
                for tag_id in tags
            ])


class YoungBaseInfoDB(DataBuilder):

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

    def getval_tag_v3_ids(self, obj):
        return list(YoungTag.objects.filter(
            young_id=obj.id,
            is_online=True
        ).values_list("tag_id", flat=True))


@DB
class YoungBaseInfoDQ(DataSQLQuery):
    model = YoungBaseInfo
    data_model = YoungBaseInfoDB

    def create(self, **kwargs):
        tag_v3_ids = kwargs.pop("tag_v3_ids", [])
        base_info = self.model.objects.create(**kwargs)
        if tag_v3_ids:
            YoungTag.objects.bulk_create([
                YoungTag(young_id=base_info.id, tag_id=tag_id)
                for tag_id in tag_v3_ids
            ])
        return to_dict(base_info)

    def _update_tag_v3(self, group_id, tags):
        if tags == [] or tags:
            YoungTag.objects.filter(young_id=group_id).delete()

        if tags:
            YoungTag.objects.bulk_create([
                YoungTag(young_id=group_id, tag_id=tag_id)
                for tag_id in tags
            ])

    def update(self, updates, **kwargs):
        tag_v3_ids = updates.pop("tag_v3_ids", None)

        base_info = self.model.objects.get(**kwargs)

        self.model.objects.filter(**kwargs).update(**updates)

        self._update_tag_v3(base_info.id, tag_v3_ids)

        return 1

class YoungTaskConfigDB(DataBuilder):
    pass


@DB
class YoungTaskConfigDQ(DataSQLQuery):
    model = TaskConfig
    data_model = YoungTaskConfigDB
