#!/usr/bin/env python
# -*- coding:utf-8 -*-
#
#   Author  :   RobertDing
#   E-mail  :   robertdingx@gmail.com
#   Date    :   18/04/02 14:31:10
#   Desc    :   polymer query
#
from django.db.models import Q
from gm_dataquery.dict_mixin import to_dict
from gm_dataquery.dataquery import DataSQLQuery, DataBuilder
from gm_dataquery.db import DB

from gm_types.gaia import POLYMER_DETAIL_TAB_TYPE

from polymer.models import Polymer, PolymerTab, PolymerContent, DeliverPolymer, \
    PolymerTag, PolymerAgileTag, PolymerAiMasterTag, PolymerAiSlaveTag, PolymerSurgery, PolymerTagV3
from wiki.models.collect import TopItem
from api.models import City


class PolymerDB(DataBuilder):

    def getval_show_discuss(self, item):
        return POLYMER_DETAIL_TAB_TYPE.DISSCUSS in item.show_tab_list

    def getval_show_diary(self, item):
        return POLYMER_DETAIL_TAB_TYPE.DIARY in item.show_tab_list

    def getval_show_knowledge(self, item):
        return POLYMER_DETAIL_TAB_TYPE.KNOWLAGE in item.show_tab_list

    def getval_show_service(self, item):
        return POLYMER_DETAIL_TAB_TYPE.SERVICE in item.show_tab_list

    def getval_show_doctor(self, item):
        return POLYMER_DETAIL_TAB_TYPE.DOCTOR in item.show_tab_list

    def getval_show_hospital(self, item):
        return POLYMER_DETAIL_TAB_TYPE.HOSPITAL in item.show_tab_list

    def getval_show_tractate(self, item):
        return POLYMER_DETAIL_TAB_TYPE.TRACTATE in item.show_tab_list

    def getval_service_recommend(self, item):
        return item.tabs.filter(tab_type=POLYMER_DETAIL_TAB_TYPE.SERVICE, recommend=True).exists()

    def getval_description(self, item, need_escape=False):
        return item.description or ''

    def getval_show_video(self, item):
        return POLYMER_DETAIL_TAB_TYPE.VIDEO in item.show_tab_list

    def getval_first_title(self, obj):
        try:
            obj = TopItem.objects.get(polymer_id=obj.id, ordering=1)
        except TopItem.DoesNotExist:
            obj.first_title = ""
            return obj.first_title
        else:
            return obj.title

    def getval_first_url(self, obj):
        try:
            obj = TopItem.objects.get(polymer_id=obj.id, ordering=1)
        except TopItem.DoesNotExist:
            obj.first_url = ""
            return obj.first_url
        else:
            return obj.url

    def getval_second_title(self, obj):
        try:
            obj = TopItem.objects.get(polymer_id=obj.id, ordering=2)
        except TopItem.DoesNotExist:
            obj.second_title = ""
            return obj.second_title
        else:
            return obj.title

    def getval_second_url(self, obj):
        try:
            obj = TopItem.objects.get(polymer_id=obj.id, ordering=2)
        except TopItem.DoesNotExist:
            obj.second_url = ""
            return obj.second_url
        else:
            return obj.url

    def getval_third_title(self, obj):
        try:
            obj = TopItem.objects.get(polymer_id=obj.id, ordering=3)
        except TopItem.DoesNotExist:
            obj.third_title = ""
            return obj.third_title
        else:
            return obj.title

    def getval_third_url(self, obj):
        try:
            obj = TopItem.objects.get(polymer_id=obj.id, ordering=3)
        except TopItem.DoesNotExist:
            obj.third_url = ""
            return obj.third_url
        else:
            return obj.url

    def getval_tag(self, obj):
        return list(PolymerTag.objects.filter(polymer_id=obj.id, is_online=True).values_list("tag_id", flat=True))

    def getval_agiletag(self, obj):
        return list(PolymerAgileTag.objects.filter(polymer_id=obj.id, is_online=True).values_list("agile_tag_id", flat=True))

    def getval_ai_slave_tag(self, obj):
        return list(PolymerAiSlaveTag.objects.filter(polymer_id=obj.id, is_online=True).values_list("tag_id", flat=True))

    def getval_ai_master_tag(self, obj):
        return list(PolymerAiMasterTag.objects.filter(polymer_id=obj.id, is_online=True).values_list("tag_id", flat=True))

    def getval_is_surgery(self, obj):
        return PolymerSurgery.objects.filter(polymer_id=obj.id, is_surgery=True).exists()

    def getval_tag_v3_ids(self, obj):
        return list(PolymerTagV3.objects.filter(polymer_id=obj.id, is_online=True).values_list("tag_v3_id", flat=True))


@DB
class PolymerDQ(DataSQLQuery):
    model = Polymer
    data_model = PolymerDB

    def _show_tabs(self, kwargs):
        result = {}
        show_dict = {
            'show_discuss': POLYMER_DETAIL_TAB_TYPE.DISSCUSS,
            'show_video': POLYMER_DETAIL_TAB_TYPE.VIDEO,
            'show_diary': POLYMER_DETAIL_TAB_TYPE.DIARY,
            'show_knowledge': POLYMER_DETAIL_TAB_TYPE.KNOWLAGE,
            'show_service': POLYMER_DETAIL_TAB_TYPE.SERVICE,
            'show_doctor': POLYMER_DETAIL_TAB_TYPE.DOCTOR,
            'show_hospital': POLYMER_DETAIL_TAB_TYPE.HOSPITAL,
            'show_tractate': POLYMER_DETAIL_TAB_TYPE.TRACTATE,
            'service_recommend': 'service_recommend',
        }
        for key, value in kwargs.items():
            if key in show_dict:
                result[show_dict[key]] = kwargs.pop(key)
        return result

    def _update_tabs(self, polymer, tabs):
        service_recommend = tabs.pop('service_recommend', None)
        if service_recommend is not None:
            defaults = {'recommend': service_recommend}
            PolymerTab.objects.update_or_create(polymer=polymer, tab_type=POLYMER_DETAIL_TAB_TYPE.SERVICE, defaults=defaults)
        for tab, value in tabs.items():
            defaults = {'enable': value}
            PolymerTab.objects.update_or_create(polymer=polymer, tab_type=tab, defaults=defaults)

    def create(self, **kwargs):
        _tabs = self._show_tabs(kwargs)
        gadget = kwargs.pop('gadget')
        banner = kwargs.pop('banner')
        tag = kwargs.pop('tag')
        agiletag = kwargs.pop('agiletag')
        is_surgery = kwargs.pop('is_surgery')
        ai_master_tag = kwargs.pop('ai_master_tag')
        ai_slave_tag = kwargs.pop('ai_slave_tag')
        tag_v3_ids = kwargs.pop("tag_v3_ids")
        dic_temp = kwargs.copy()
        kwargs.pop('first_title')
        kwargs.pop('first_url')
        kwargs.pop('second_title')
        kwargs.pop('second_url')
        kwargs.pop('third_title')
        kwargs.pop('third_url')
        if 'external_display' in kwargs:
            kwargs.pop('external_display')
        polymer = Polymer.objects.create(**kwargs)
        list_temp = []
        if dic_temp['first_title']:
            top = TopItem(
                title=dic_temp['first_title'],
                url=dic_temp['first_url'],
                ordering=1,
                polymer_id=polymer.id
            )
            list_temp.append(top)
        if dic_temp.get('second_title'):
            top = TopItem(
                title=dic_temp['second_title'],
                url=dic_temp['second_url'],
                ordering=2,
                polymer_id=polymer.id
            )
            list_temp.append(top)
        if dic_temp.get('third_title'):
            top = TopItem(
                title=dic_temp['third_title'],
                url=dic_temp['third_url'],
                ordering=3,
                polymer_id=polymer.id
            )
            list_temp.append(top)
        TopItem.objects.bulk_create(list_temp)
        polymer.gadget = gadget
        polymer.banner = banner

        self._update_surgery(polymer.id, is_surgery)
        self._update_tag(polymer.id, tag, agiletag, ai_master_tag, ai_slave_tag, tag_v3_ids)
        self._update_tabs(polymer, _tabs)
        return to_dict(polymer)

    def _update_surgery(self, polymer_id, is_surgery):

        if is_surgery:
            if not PolymerSurgery.objects.filter(polymer_id=polymer_id, is_surgery=True).exists():
                PolymerSurgery.objects.create(polymer_id=polymer_id, is_surgery=True)
        else:
            PolymerSurgery.objects.filter(polymer_id=polymer_id).delete()

    def _update_tag(self, polymer_id, tags, agiletags, ai_master_tags, ai_slave_tags, tags_v3):

        if tags == [] or tags:
            PolymerTag.objects.filter(polymer_id=polymer_id).delete()
        if agiletags == [] or agiletags:
            PolymerAgileTag.objects.filter(polymer_id=polymer_id).delete()
        if ai_master_tags == [] or ai_master_tags:
            PolymerAiMasterTag.objects.filter(polymer_id=polymer_id).delete()
        if ai_slave_tags == [] or ai_slave_tags:
            PolymerAiSlaveTag.objects.filter(polymer_id=polymer_id).delete()
        if tags_v3 == [] or tags_v3:
            PolymerTagV3.objects.filter(polymer_id=polymer_id).delete()

        if tags:
            PolymerTag.objects.bulk_create([
                PolymerTag(polymer_id=polymer_id, tag_id=tag_id)
                for tag_id in tags
            ])
        if agiletags:
            PolymerAgileTag.objects.bulk_create([
                PolymerAgileTag(polymer_id=polymer_id, agile_tag_id=agile_tag_id)
                for agile_tag_id in agiletags
            ])

        if ai_master_tags:
            PolymerAiMasterTag.objects.bulk_create([
                PolymerAiMasterTag(polymer_id=polymer_id, tag_id=tag_id)
                for tag_id in ai_master_tags
            ])
        if ai_slave_tags:
            PolymerAiSlaveTag.objects.bulk_create([
                PolymerAiSlaveTag(polymer_id=polymer_id, tag_id=tag_id)
                for tag_id in ai_slave_tags
            ])

        if tags_v3:
            PolymerTagV3.objects.bulk_create([
                PolymerTagV3(polymer_id=polymer_id, tag_v3_id=tag_id)
                for tag_id in tags_v3
            ])



    def update(self, updates, **kwargs):
        
        _tabs = self._show_tabs(updates)
        gadget = updates.pop('gadget', None)
        banner = updates.pop('banner', None)
        tag = updates.pop('tag', None)
        agiletag = updates.pop('agiletag', None)
        is_surgery = updates.pop('is_surgery', None)
        ai_master_tag = updates.pop('ai_master_tag', None)
        ai_slave_tag = updates.pop('ai_slave_tag', None)
        tag_v3_ids = updates.pop('tag_v3_ids', None)
        polymer = Polymer.objects.get(**kwargs)
        #有优化空间
        if updates.get('first_title') or updates.get('first_url'):
            temp = []
            try:
                topTitle = TopItem.objects.get(polymer_id=polymer.id, ordering=1)
                if updates.get('first_title'):
                    topTitle.title = updates.get('first_title')
                    temp.append('title')
                    updates.pop('first_title')
                if updates.get('first_url'):
                    topTitle.url = updates.get('first_url')
                    temp.append('url')
                    updates.pop('first_url')
                topTitle.save(update_fields=temp)
            except TopItem.DoesNotExist:
                TopItem.objects.create(title=updates.get('first_title'), url=updates.get('first_url'),polymer_id=polymer.id, ordering=1)
                updates.pop('first_title')
                updates.pop('first_url')
        if updates.get('second_title') or updates.get('second_url'):
            temp = []
            try:
                topTitle = TopItem.objects.get(polymer_id=polymer.id, ordering=2)
                if updates.get('second_title'):
                    topTitle.title = updates.get('second_title')
                    temp.append('title')
                    updates.pop('second_title')
                if updates.get('second_url'):
                    topTitle.url = updates.get('second_url')
                    temp.append('url')
                    updates.pop('second_url')
                topTitle.save(update_fields=temp)
            except TopItem.DoesNotExist:
                TopItem.objects.create(title=updates.get('second_title'), url=updates.get('second_url'), polymer_id=polymer.id, ordering=2)
                updates.pop('second_title')
                updates.pop('second_url')
        if updates.get('third_title') or updates.get('third_url'):
            temp = []
            try:
                topTitle = TopItem.objects.get(polymer_id=polymer.id, ordering=3)
                if updates.get('third_title'):
                    topTitle.title = updates.get('third_title')
                    temp.append('title')
                    updates.pop('third_title')
                if updates.get('third_url'):
                    topTitle.url = updates.get('third_url')
                    temp.append('url')
                    updates.pop('third_url')
                topTitle.save(update_fields=temp)
            except TopItem.DoesNotExist:
                TopItem.objects.create(title=updates.get('third_title'), url=updates.get('third_url'), polymer_id=polymer.id, ordering=3)
                updates.pop('third_title')
                updates.pop('third_url')
        if updates.get('first_title') == "" and updates.get('first_url') == "":
            TopItem.objects.filter(polymer_id=polymer.id, ordering=1).delete()
            updates.pop('first_title')
            updates.pop('first_url')
        if updates.get('second_title') == "" and updates.get('second_url') == "":
            TopItem.objects.filter(polymer_id=polymer.id, ordering=2).delete()
            updates.pop('second_title')
            updates.pop('second_url')
        if updates.get('third_title') == "" and updates.get('third_url') == "":
            TopItem.objects.filter(polymer_id=polymer.id, ordering=3).delete()
            updates.pop('third_title')
            updates.pop('third_url')
        Polymer.objects.filter(**kwargs).update(**updates)
        if gadget is not None:
            polymer.gadget = gadget
        if banner is not None:
            polymer.banner = banner
        self._update_surgery(polymer.id, is_surgery)
        self._update_tag(polymer.id, tag, agiletag, ai_master_tag, ai_slave_tag, tag_v3_ids)
        self._update_tabs(polymer, _tabs)
        return 1


class PolymerContentDB(DataBuilder):

    def getval_citys(self, obj):
        return obj.get_cities_name()


@DB
class PolymerContentDQ(DataSQLQuery):
    model = PolymerContent
    data_model = PolymerContentDB

    def filter_citys(self, srch_key, srch_val, regex=False):
        city_obj = City.objects.get(id=srch_val)
        return Q(id__in=city_obj.polymercontent_set.all().values_list("id", flat=True)) | Q(is_related_city=False)

    def filter_start_time(self, srch_key, srch_val, regex=False):
        return self._qry_time_range(srch_key, srch_val, regex)

    def filter_end_time(self, srch_key, srch_val, regex=False):
        return self._qry_time_range(srch_key, srch_val, regex)

    def update(self, updates, **kwargs):
        update_city = updates.get('cities', '')
        if not update_city and isinstance(update_city, list):
            updates.update({"is_related_city": False})
        elif update_city:
            updates.update({"is_related_city": True})
        return super(PolymerContentDQ.sqlquery, self).update(updates, **kwargs)

    def create(self, **kwargs):
        cities = kwargs.pop("cities", "")
        polymer_obj = self.model.objects.create(**kwargs)
        if cities:
            cities_obj = list(City.objects.filter(id__in=cities))
            polymer_obj.cities.clear()
            polymer_obj.cities.add(*cities_obj)
            polymer_obj.is_related_city = True
            polymer_obj.save()
        return to_dict(polymer_obj)


@DB
class DeliverPolymerDQ(DataSQLQuery):
    model = DeliverPolymer

