#!/usr/bin/env python
# -*- coding: utf-8 -*-

import copy

from gm_types.wiki import NEW_WIKI_WORDREL_CATEGORY
from gm_types.gaia import VIDEO_LIBRARY_VIDEO_TYPE
from wiki.models.video import VideoLibrary, VideoRelationWord
from wiki.tasks.video_tasks import (
    update_video_library_cover_url,
    set_video_library_water_mark_url,
)


class NewWikiRelationWords(object):
    def getval_item_words(self, obj):
        return list(obj.words.filter(
            category=NEW_WIKI_WORDREL_CATEGORY.ITEM, is_effect=True).values_list("wordrel_id", flat=True))

    def getval_part_words(self, obj):
        return list(obj.words.filter(
            category=NEW_WIKI_WORDREL_CATEGORY.PART, is_effect=True).values_list("wordrel_id", flat=True))

    def getval_symptom_words(self, obj):
        return list(obj.words.filter(
            category=NEW_WIKI_WORDREL_CATEGORY.SYMPTOM, is_effect=True).values_list("wordrel_id", flat=True))

    def getval_need_words(self, obj):
        return list(obj.words.filter(
            category=NEW_WIKI_WORDREL_CATEGORY.NEED, is_effect=True).values_list("wordrel_id", flat=True))

    def getval_cure_words(self, obj):
        return list(obj.words.filter(
            category=NEW_WIKI_WORDREL_CATEGORY.CURE, is_effect=True).values_list("wordrel_id", flat=True))

    def getval_stuff_words(self, obj):
        return list(obj.words.filter(
            category=NEW_WIKI_WORDREL_CATEGORY.STUFF, is_effect=True).values_list("wordrel_id", flat=True))

    def getval_brand_words(self, obj):
        return list(obj.words.filter(
            category=NEW_WIKI_WORDREL_CATEGORY.BRAND, is_effect=True).values_list("wordrel_id", flat=True))

    def getval_other_words(self, obj):
        return list(obj.words.filter(
            category=NEW_WIKI_WORDREL_CATEGORY.OTHER, is_effect=True).values_list("wordrel_id", flat=True))


new_wiki_words_dict = {
    "item_words": NEW_WIKI_WORDREL_CATEGORY.ITEM,
    "part_words": NEW_WIKI_WORDREL_CATEGORY.PART,
    "symptom_words": NEW_WIKI_WORDREL_CATEGORY.SYMPTOM,
    "need_words": NEW_WIKI_WORDREL_CATEGORY.NEED,
    "cure_words": NEW_WIKI_WORDREL_CATEGORY.CURE,
    "stuff_words": NEW_WIKI_WORDREL_CATEGORY.STUFF,
    "brand_words": NEW_WIKI_WORDREL_CATEGORY.BRAND,
    "other_words": NEW_WIKI_WORDREL_CATEGORY.OTHER,
}


def wiki_data_create(own_model, relation_models, model_param, **kwargs):
    """
    数据创建
    :param own_model: 当前model
    :param relation_models: dict 关联的记录数据的model
    :param model_param: model 字段
    :return:
    """
    tag_v3_ids = kwargs.pop("tag_v3_ids", [])
    relwords_model = relation_models.get("relwords", None)
    relation_tag_v3_model = relation_models.get("tag_v3", None)

    new_wiki_words_list = []
    for _item, _type in new_wiki_words_dict.items():
        _v = kwargs.pop(_item, [])
        for _id in _v:
            new_wiki_words_list.append({
                "wordrel_id": _id,
                "category": _type,
            })

    _obj = own_model.objects.create(**kwargs)
    _obj_id = _obj.id

    if all([relwords_model, new_wiki_words_list]):
        relwords_bulk_create_list = []
        for _item_dic in new_wiki_words_list:
            _item_dic[model_param] = _obj_id
            relwords_bulk_create_list.append(relwords_model(**_item_dic))

        relwords_model.objects.bulk_create(relwords_bulk_create_list)

    if all([relation_tag_v3_model, tag_v3_ids]):
        rel_tag_v3_bulk_create_list = [relation_tag_v3_model(**{
            "tag_v3_id": tag_id,
            model_param: _obj_id
        }) for tag_id in tag_v3_ids]

        relation_tag_v3_model.objects.bulk_create(rel_tag_v3_bulk_create_list)

    return _obj


def wiki_data_update(_update_id, updates, relation_models, model_param):
    """
    百科 关联 词 更新
    :param _update_id: 要更新的id
    :param updates: 更新的数据
    :param relation_models: 用于记录的model dict
    :param model_param: model 字段
    :return:
    """
    tag_v3_ids = updates.pop("tag_v3_ids", []) if "tag_v3_ids" in updates else None

    relwords_model = relation_models.get("relwords", None)
    relation_tag_v3_model = relation_models.get("tag_v3", None)

    if relation_tag_v3_model and tag_v3_ids is not None:
        new_tag_ids = set(map(int, tag_v3_ids))
        old_tag_ids = set(relation_tag_v3_model.objects.filter(**{
            model_param: _update_id
        }).values_list("tag_v3_id", flat=True))

        for tag_id in (new_tag_ids - old_tag_ids):
            relation_tag_v3_model.objects.get_or_create(**{
                "tag_v3_id": tag_id,
                model_param: _update_id,
            })
        need_del_ids = old_tag_ids - new_tag_ids
        if need_del_ids:
            relation_tag_v3_model.objects.filter(**{
                model_param: _update_id,
                "tag_v3_id__in": need_del_ids
            }).delete()

    for _k, _v in updates.items():
        if _k in new_wiki_words_dict and relwords_model:
            _category = new_wiki_words_dict[_k]
            base_kw = {
                model_param: _update_id,
                "is_effect": True,
                "category": _category,
            }
            model_objs = relwords_model.objects.filter(**base_kw)

            exist_ids = list(model_objs.values_list("wordrel_id", flat=True))
            need_delete_ids = set(exist_ids) - set(_v)
            need_add_ids = set(_v) - set(exist_ids)

            if need_delete_ids:
                model_objs.filter(wordrel_id__in=need_delete_ids).update(is_effect=False)

            if need_add_ids:
                # 若之前关联过这个词，则将这条数据制成有效
                _has_exist_query_dict = copy.deepcopy(base_kw)
                _has_exist_query_dict["is_effect"] = False
                has_exist_data = relwords_model.objects.filter(**_has_exist_query_dict).filter(wordrel_id__in=need_add_ids)
                has_exist_words_ids = list(has_exist_data.values_list("wordrel_id", flat=True))
                has_exist_data.update(is_effect=True)

                bulk_create_list = []
                for _id in need_add_ids:
                    if int(_id) not in has_exist_words_ids:
                        base_kw["wordrel_id"] = _id
                        bulk_create_list.append(relwords_model(**base_kw))

                if bulk_create_list:
                    relwords_model.objects.bulk_create(bulk_create_list)

    return updates


def wiki_video_update(wiki_id, video_data, video_type):
    video_list = []
    if not video_data:
        video_libs = list(VideoLibrary.objects.filter(source_id=int(wiki_id)).values_list('id', flat=True))
        VideoRelationWord.objects.filter(video_id__in=video_libs).delete()
        VideoLibrary.objects.filter(id__in=video_libs).update(is_online=False)

    for video in video_data:
        if not video.get('video'):
            continue
        try:
            video_lib = VideoLibrary.objects.get(source_id=int(wiki_id), ordering=int(video.get('order')))
        except VideoLibrary.DoesNotExist:
            video_lib = VideoLibrary.objects.create(source_id=int(wiki_id), ordering=int(video.get('order')),
                                                    raw_image_url=video.get('img'),
                                                    raw_video_url=video.get('video'),
                                                    video_type=video_type)
        else:
            video_lib.ordering = int(video.get('order'))
            video_lib.raw_image_url = video.get('img')
            video_lib.raw_video_url = video.get('video')
            video_lib.video_type = video_type
            video_lib.save()
        tags = str(video.get('tag'))
        tags.replace('，', ',')
        tag_ids = tags.split(",")
        video_list.append(video_lib.id)
        VideoRelationWord.objects.filter(video_id=video_lib.id).delete()
        for tag_id in tag_ids:
            if not tag_id:
                continue
            VideoRelationWord.objects.update_or_create(word_id=int(tag_id), video_id=video_lib.id)
        set_video_library_water_mark_url.delay(video_id=video_lib.id)
        update_video_library_cover_url.delay(video_id=video_lib.id)
    video_libs = list(VideoLibrary.objects.filter(source_id=int(wiki_id)).values_list('id', flat=True))
    VideoRelationWord.objects.filter(video_id__in=list(set(video_libs) - set(video_list))).delete()
    VideoLibrary.objects.filter(id__in=list(set(video_libs) - set(video_list))).update(is_online=False)


def wiki_video_create(wiki_id, video_data, video_type):
    for video in video_data:
        if not video.get('video'):
            continue
        video_lib = VideoLibrary.objects.create(source_id=int(wiki_id), ordering=int(video.get('order')),
                                                raw_image_url=video.get('img'),
                                                raw_video_url=video.get('video'),
                                                video_type=video_type)

        set_video_library_water_mark_url.delay(video_id=video_lib.id)
        update_video_library_cover_url.delay(video_id=video_lib.id)
        tags = str(video.get('tag'))
        tags.replace('，', ',')
        tag_ids = tags.split(",")
        for tag_id in tag_ids:
            if not tag_id or tag_id == 'undefined' or tag_id == '':
                continue
            VideoRelationWord.objects.create(word_id=int(tag_id), video_id=video_lib.id)