# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, with_statement

import json
from django.db.models import Q, F

from gm_dataquery.db import DB
from gm_dataquery.dataquery import DataSQLQuery, DataBuilder
from gm_types.gaia import TAG_V3_TYPE
from agile.models.tag import (
    TagSynonym,
    TagMapOldTag,
    TagCategoryMapTag,
    TagV3MapAttrTag,
    TagV3Relation,
    TagMapTag,

)
from agile.models.tag import TagV3


class AgileTagV3DB(DataBuilder):
    def getval_synonym(self, obj):  # 同义词
        synonym_name_list = list(TagSynonym.objects.filter(tag_id=obj.id).values_list(
            'name', flat=True
        ))
        return ', '.join(synonym_name_list)

    def getval_homoionym(self, obj):    # 近义词
        homoionym = obj.homoionym
        homoionym_name_list = json.loads(homoionym) if homoionym else ''
        return ', '.join(homoionym_name_list)

    def getval_first_symptom_count(self, obj):      # 症状链接数
        attr_ids = list(TagV3MapAttrTag.objects.filter(tag_id=obj.id).values_list('tag_attr_id', flat=True))
        return TagV3.objects.filter(id__in=attr_ids, tag_type=TAG_V3_TYPE.FIRST_SYMPTOM).count()

    def getval_symptom_count(self, obj):      # 症状链接数
        attr_ids = list(TagV3MapAttrTag.objects.filter(tag_id=obj.id).values_list('tag_attr_id', flat=True))
        return TagV3.objects.filter(id__in=attr_ids, tag_type=TAG_V3_TYPE.SECOND_SYMPTOM).count()

    def getval_mode_count(self, obj):         # 微观方式--> 二级方式
        attr_ids = list(TagV3MapAttrTag.objects.filter(tag_id=obj.id).values_list('tag_attr_id', flat=True))
        return TagV3.objects.filter(id__in=attr_ids, tag_type=TAG_V3_TYPE.FIRST_BRAND).count()

    def getval_first_position_count(self, obj):     # 位置
        attr_ids = list(TagV3MapAttrTag.objects.filter(tag_id=obj.id).values_list('tag_attr_id', flat=True))
        return TagV3.objects.filter(id__in=attr_ids, tag_type=TAG_V3_TYPE.FIRST_POSITION).count()

    def getval_position_count(self, obj):     # 位置
        attr_ids = list(TagV3MapAttrTag.objects.filter(tag_id=obj.id).values_list('tag_attr_id', flat=True))
        return TagV3.objects.filter(id__in=attr_ids, tag_type=TAG_V3_TYPE.SECOND_POSITION).count()

    def getval_first_brand_count(self, obj):        # 品牌
        attr_ids = list(TagV3MapAttrTag.objects.filter(tag_id=obj.id).values_list('tag_attr_id', flat=True))
        return TagV3.objects.filter(id__in=attr_ids, tag_type=TAG_V3_TYPE.FIRST_BRAND).count()

    def getval_brand_count(self, obj):        # 品牌
        attr_ids = list(TagV3MapAttrTag.objects.filter(tag_id=obj.id).values_list('tag_attr_id', flat=True))
        return TagV3.objects.filter(id__in=attr_ids, tag_type=TAG_V3_TYPE.SECOND_BRAND).count()

    def getval_second_appeal_count(self, obj):        # 二级诉求
        attr_ids = list(TagV3MapAttrTag.objects.filter(tag_id=obj.id).values_list('tag_attr_id', flat=True))
        return TagV3.objects.filter(id__in=attr_ids, tag_type=TAG_V3_TYPE.SECOND_APPEAL).count()

    def getval_first_appeal_count(self, obj):        # 一级诉求
        attr_ids = list(TagV3MapAttrTag.objects.filter(tag_id=obj.id).values_list('tag_attr_id', flat=True))
        return TagV3.objects.filter(id__in=attr_ids, tag_type=TAG_V3_TYPE.FIRST_APPEAL).count()

    def getval_related_old_tags(self, obj):        # 关联老标签
        return TagMapOldTag.objects.filter(tag_id=obj.id).count()

    def getval_macroscopic_mode_count(self, obj):  # 宏观方式--> 一级方式
        attr_ids = list(TagV3MapAttrTag.objects.filter(tag_id=obj.id).values_list('tag_attr_id', flat=True))
        return TagV3.objects.filter(id__in=attr_ids, tag_type=TAG_V3_TYPE.MACROSCOPIC_MODE).count()

    def getval_related_special_tags_count(self, obj):  # 关联标签数 -- 特殊类型的标签
        return TagMapTag.objects.filter(tag_id=obj.id).count()

    # 属性标签
    def getval_synonym(self, obj):
        synonym_name_list = list(TagSynonym.objects.filter(tag_id=obj.id).values_list(
            'name', flat=True
        ))
        return ', '.join(synonym_name_list)

    def getval_homoionym(self, obj):
        homoionym = obj.homoionym
        homoionym_name_list = json.loads(homoionym) if homoionym else []
        return ', '.join(homoionym_name_list)

    def getval_related_tags(self, obj):
        return TagV3MapAttrTag.objects.filter(tag_attr_id=obj.id).count()


ATTR_TAG_TYPE = [
    TAG_V3_TYPE.FIRST_SYMPTOM, TAG_V3_TYPE.SECOND_SYMPTOM, TAG_V3_TYPE.FIRST_BRAND, TAG_V3_TYPE.SECOND_BRAND,
    TAG_V3_TYPE.MACROSCOPIC_MODE, TAG_V3_TYPE.FIRST_APPEAL, TAG_V3_TYPE.SECOND_APPEAL, TAG_V3_TYPE.FIRST_POSITION,
    TAG_V3_TYPE.SECOND_POSITION, TAG_V3_TYPE.DRUG, TAG_V3_TYPE.INSTRUMENT, TAG_V3_TYPE.CONSUMABLES,
    TAG_V3_TYPE.MATERIAL,
]


@DB
class AgileTagV3DQ(DataSQLQuery):
    model = TagV3
    data_model = AgileTagV3DB

    def filter_name(self, srch_key, srch_val, regex=False):
        if srch_val:
            return Q(name__contains=srch_val)
        return Q()

    def filter_synonym(self, srch_key, srch_val, regex=False):
        all_tag_ids = list(TagSynonym.objects.filter(
            name__contains=srch_val
        ).values_list('tag_id', flat=True))
        return Q(id__in=all_tag_ids)

    def update(self, updates, **kwargs):
        tag_id = kwargs.get('id')
        if 'is_display' in updates:
            TagV3.objects.filter(id=tag_id).update(
                is_display=updates.get('is_display', False),
            )
        elif 'is_online' in updates:
            TagV3.objects.filter(id=tag_id).update(
                is_online=updates.get('is_online', False),
            )
            TagV3Relation.objects.filter(
                Q(parent_id=tag_id) | Q(child_id=tag_id)
            ).update(is_online=updates.get('is_online', False))

        elif 'delete_tag' in updates:
            TagV3.objects.filter(id=int(tag_id)).delete()
            TagV3MapAttrTag.objects.filter(tag_id=int(tag_id)).delete()
            TagSynonym.objects.filter(tag_id=int(tag_id)).delete()
            TagCategoryMapTag.objects.filter(tag_id=tag_id).delete()
            TagV3Relation.objects.filter(Q(parent_id=tag_id) | Q(child_id=tag_id)).delete()
            TagMapTag.objects.filter(Q(tag_id=tag_id) | Q(related_tag_id=tag_id)).delete()

        return super(AgileTagV3DQ.sqlquery, self).update(updates, **kwargs)


# class AttrTagDB(DataBuilder):
#
#     def getval_synonym(self, obj):
#         synonym_name_list = list(TagSynonym.objects.filter(tag_id=obj.id).values_list(
#             'name', flat=True
#         ))
#         return ', '.join(synonym_name_list)
#
#     def getval_homoionym(self, obj):
#         homoionym = obj.homoionym
#         homoionym_name_list = json.loads(homoionym) if homoionym else ''
#         return ', '.join(homoionym_name_list)
#
#     def getval_related_tags(self, obj):
#         return TagV3MapAttrTag.objects.filter(tag_attr_id=obj.id).count()
#
#
# ATTR_TAG_TYPE = [
#     TAG_V3_TYPE.FIRST_SYMPTOM, TAG_V3_TYPE.SECOND_SYMPTOM, TAG_V3_TYPE.FIRST_BRAND, TAG_V3_TYPE.SECOND_BRAND,
#     TAG_V3_TYPE.MACROSCOPIC_MODE, TAG_V3_TYPE.FIRST_APPEAL, TAG_V3_TYPE.SECOND_APPEAL, TAG_V3_TYPE.FIRST_POSITION,
#     TAG_V3_TYPE.SECOND_POSITION, TAG_V3_TYPE.DRUG, TAG_V3_TYPE.INSTRUMENT, TAG_V3_TYPE.CONSUMABLES,
#     TAG_V3_TYPE.MATERIAL,
# ]
#
#
# @DB
# class AttrTagDQ(DataSQLQuery):
#     model = TagV3
#     data_model = AttrTagDB
#
#     def filter_name(self, srch_key, srch_val, regex=False):
#         if srch_val:
#             return Q(name__contains=srch_val, tag_type__in=ATTR_TAG_TYPE)
#         return Q()
#
#     def filter_synonym(self, srch_key, srch_val, regex=False):
#         all_tag_ids = list(TagSynonym.objects.filter(
#             name__contains=srch_val, tag_type__in=ATTR_TAG_TYPE
#         ).values_list('tag_attr_id', flat=True))
#         return Q(id__in=all_tag_ids)
#
#     def update(self, updates, **kwargs):
#         tag_id = kwargs.get('id')
#         if tag_id:
#             TagV3.objects.filter(id=tag_id).delete()
#
#         return super(AttrTagDQ.sqlquery, self).update(updates, **kwargs)
