# -*- coding: utf-8 -*-
from django.db import IntegrityError, transaction
from gm_types.error import ERROR
from gm_types.gaia import AGILE_TAG_TYPE, AGILE_TAG_CREATE_TYPE

from agile.models.agile_tag import (
    AgileTag,
    AgileTagType,
    AgileTagMapping,
    AgileTagRecommendType,
)
from polymer.models import AgileTagRelationPolymer
from rpc.decorators import bind
from rpc.exceptions import RPCIntegrityError
from rpc.tool.error_code import gen


@bind('hera/agile/detail')
def modify_agile_get(agile_tag_id=None):
    if not agile_tag_id:
        return {}

    try:
        agile = AgileTag.objects.get(id=agile_tag_id)
    except AgileTag.DoesNotExist:
        return gen(ERROR.MESSAGE_CONVERSATION_TAG_NOT_EXIST)

    data = {
        'id': agile.id,
        'name': agile.name,
        'description': agile.description,
        'order': agile.topic_recommend_sort,
        'create_tag_type': agile.create_tag_type,
        'style': agile.style,
        'topic_recommend_sort': agile.topic_recommend_sort,
        'is_online': agile.is_online,
        'attribute': agile.attribute,
    }
    tag_type = list(AgileTagType.objects.filter(
        agile_tag_id=agile.id, is_online=True).values_list('agile_tag_type', flat=True))
    data.update({'tag_type': tag_type})

    related_old_tags = list(AgileTagMapping.objects.filter(
        agile_tag_id=agile.id, is_online=True).values_list('old_tag_id', flat=True))
    data.update({'related_old_tags': related_old_tags})

    recommend_types = list(AgileTagRecommendType.objects.filter(
        agile_tag_id=agile.id, is_online=True).values_list('agile_tag_type', flat=True))
    data.update({'recommend_types': recommend_types})

    related_polymer = list(AgileTagRelationPolymer.objects.filter(
        agile_tag_id=agile.id, is_online=True).values_list('polymer_id', flat=True))
    data.update({"related_polymer": related_polymer})

    return {'data': data}


@bind('hera/agile_modify')
def modify_agile_edit(agile_info, agile_tag_id=None):
    """
    新标签创建、编辑
    :param agile_info:
    :param agile_tag_id:
    :return:
    """
    result = {
        'error': 0,
        'message': '创建成功',
        'data': ''
    }
    tag_type = agile_info.pop('tag_type', [AGILE_TAG_TYPE.UNDEFINED])  # 标签类型
    related_old_tags = agile_info.pop('related_old_tags', [])  # 关联老标签
    recommend_types = agile_info.pop('recommend_types', [])  # 推荐类型
    related_polymer = agile_info.pop('related_polymer', [])  # 关联的聚合页id

    if not agile_tag_id:
        try:
            agile = AgileTag.objects.create(**agile_info)
        except IntegrityError:
            raise RPCIntegrityError(message='名称不能重复')
    else:
        agile = AgileTag.objects.get(id=agile_tag_id)
        try:
            for key, value in agile_info.items():
                setattr(agile, key, value)
            agile.save()
        except IntegrityError:
            result['error'] = -1
            result['message'] = '名称不能重复'
            result['data'] = agile.id
            return result

    # 关联聚合页
    old_related_polymer = list(AgileTagRelationPolymer.objects.filter(
        agile_tag_id=agile.id, is_online=True).values_list('polymer_id', flat=True))
    related_polymer = [int(item) for item in related_polymer]
    need_create_related_polymer = set(related_polymer) - set(old_related_polymer)
    need_offline_related_polymer = set(old_related_polymer) - set(related_polymer)
    polymer_list = []
    for _id in need_create_related_polymer:
        polymer = AgileTagRelationPolymer(
            agile_tag_id=agile.id,
            polymer_id=_id
        )
        polymer_list.append(polymer)

    # 关联标签类型
    old_agile_type = list(AgileTagType.objects.filter(
        agile_tag_id=agile.id, is_online=True).values_list('agile_tag_type', flat=True))
    need_create_agile_tag_type = set(tag_type) - set(old_agile_type)
    need_offline_agile_tag_type = set(old_agile_type) - set(tag_type)
    type_list = []
    for _type in need_create_agile_tag_type:
        agile_type = AgileTagType(
            agile_tag_id=agile.id,
            agile_tag_type=_type
        )
        type_list.append(agile_type)

    # 关联老标签
    old_agile_tag_mapping = list(AgileTagMapping.objects.filter(
        agile_tag_id=agile.id, is_online=True).values_list('old_tag_id', flat=True))
    related_old_tags = [int(item) for item in related_old_tags]
    need_create_agile_tag_mapping = set(related_old_tags) - set(old_agile_tag_mapping)
    need_offline_agile_tag_mapping = set(old_agile_tag_mapping) - set(related_old_tags)
    tag_map_list = []
    for _id in need_create_agile_tag_mapping:
        agile_map = AgileTagMapping(
            agile_tag_id=agile.id,
            old_tag_id=_id
        )
        tag_map_list.append(agile_map)

    # 关联推荐类型
    old_recommend_type = set(AgileTagRecommendType.objects.filter(
        agile_tag_id=agile.id, is_online=True).values_list('agile_tag_type', flat=True))
    need_create_recommend_type = set(recommend_types) - set(old_recommend_type)
    need_offline_recommend_type = set(old_recommend_type) - set(recommend_types)
    recommend_list = []
    for _type in need_create_recommend_type:
        recommend = AgileTagRecommendType(
            agile_tag_id=agile.id,
            agile_tag_type=_type
        )
        recommend_list.append(recommend)

    with transaction.atomic():
        AgileTagType.objects.filter(
            agile_tag_id=agile.id, agile_tag_type__in=need_offline_agile_tag_type).update(is_online=False)
        AgileTagType.objects.bulk_create(type_list)

        AgileTagMapping.objects.filter(
            agile_tag_id=agile.id, old_tag_id__in=need_offline_agile_tag_mapping).update(is_online=False)
        AgileTagMapping.objects.bulk_create(tag_map_list)

        AgileTagRecommendType.objects.filter(
            agile_tag_id=agile.id, agile_tag_type__in=need_offline_recommend_type).update(is_online=False)
        AgileTagRecommendType.objects.bulk_create(recommend_list)

        AgileTagRelationPolymer.objects.filter(
            agile_tag_id=agile.id, polymer_id__in=need_offline_related_polymer).update(is_online=False)
        AgileTagRelationPolymer.objects.bulk_create(polymer_list)

    result['data'] = agile.id

    return result
