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

from __future__ import unicode_literals, absolute_import, print_function

from django.db.models import Q
from gm_types.error import ERROR as CODES

from api.tool.operate_tool import format_operate_query
from api.tool.user_tool import get_user_from_context
from api.tasks.tag_task import user_tag_relation_change
from rpc.decorators import bind, bind_context
from rpc.tool.error_code import gen

from polymer.models import Polymer, PolymerTab, PolymerExtra, \
    AgileTagRelationPolymer, PolymerTagV3
from relation.models import UserTagRelation
from wiki.models.collect import TopItem
from polymer.views.question_polymer import get_polymer_info_by_tags

from gm_types.gaia import POLYMER_DETAIL_TAB_TYPE
from api.models.types import USER_TAG_CHOICES


@bind("api/polymers/info")
def get_polymers_info(polymers_ids=None, **filters):
    """获取对应的聚合页列表信息。

    :param polymer_ids: 聚合页id列表，没有的话默认全部
    :param filters: 其他的过滤信息
    :return:
    """
    tab_types = filters.get("tab_types", [POLYMER_DETAIL_TAB_TYPE.DISSCUSS])
    polymer_tab_query = Q(enable=True) & Q(tab_type__in=tab_types) & \
                        Q(polymer__question_classify__isnull=False)

    if polymers_ids:
        polymer_tab_query = Q(polymer_id__in=polymers_ids)

    polymer_tabs = PolymerTab.objects.filter(polymer_tab_query).\
        exclude(polymer__question_classify='').distinct().prefetch_related("polymer")

    result = []
    for polymer_tab in polymer_tabs:
        item = {
            "id": polymer_tab.polymer.id,
            "name": polymer_tab.polymer.name,
            "rich_text": polymer_tab.polymer.description,
            "tags": polymer_tab.polymer.tag_list,
            "default_tab": polymer_tab.polymer.default_tab,
            "question_classify": polymer_tab.polymer.get_question_classify,
            "default_question_classify": polymer_tab.polymer.default_classify
        }
        result.append(item)

    return result


@bind_context("api/polymer/info")
def get_polymer_info(ctx, tag_id=None, polymer_id=None, device_id=None, platform=None, city_id=None,
                     new_tag=False, new_polymer=False, tag_v3_id=None):
    """
    通过 polymer_id or tag_id 获取圈子数据; 优先级 polymer_id > tag_id 二取一
    :param ctx:
    :param tag_id: 标签id
    :param polymer_id: 圈子id
    :param device_id: 设备id
    :param platform: 设备类型
    :param city_id: 城市id
    :return:
    """
    user = get_user_from_context(ctx)

    if not tag_id and not polymer_id and not tag_v3_id:
        return gen(CODES.PARAMS_INVALID)

    polymer_query = Q()

    if polymer_id:
        polymer_query = Q(pk=polymer_id)

    elif tag_id:
        if not new_tag:
            polymer_query = Q(tags__id=tag_id)
        else:
            po_id = AgileTagRelationPolymer.objects.filter(agile_tag_id=tag_id,
                is_online=True).values_list("polymer_id", flat=True).first()
            if not po_id:
                return gen(CODES.ZONE_NOT_FOUND)

            polymer_query = Q(pk=po_id)

    elif tag_v3_id:
        relation = PolymerTagV3.objects.filter(tag_v3_id=tag_v3_id).first()
        if not relation:
            return gen(CODES.ZONE_NOT_FOUND)

        polymer_query = Q(pk=relation.polymer_id)

    polymer = Polymer.objects.filter(polymer_query).first()
    if not polymer:
        return gen(CODES.ZONE_NOT_FOUND)

    # 老版本：圈子未配展示tab 返回错误信息
    if not new_polymer and not polymer.show_tab_list:
        return gen(CODES.ZONE_NOT_FOUND)

    # banners
    banner_query = format_operate_query(user=user, city_id=city_id, platform=platform, device_id=device_id)
    banners = polymer.banner.filter(banner_query).order_by("rank", "-id")
    banners_list = list(filter(lambda r: r['entity_id'] is not None, [banner.banner_data() for banner in banners]))

    # tags
    tags = polymer.tag_list
    agile_tags = polymer.agile_tag_list
    origin_info = tag_id and [tag["name"] for tag in tags if tag["id"] == tag_id]
    origin_info = origin_info and origin_info[0] or ""

    # 置顶内容
    top_topic = TopItem.get_top_topic(polymer_id=polymer_id)

    # followed
    followed = False
    if user:
        tag_ids =[tag["id"] for tag in tags]
        followed = UserTagRelation.user_followed_by_tag_ids(user.id, tag_ids)

    data = {
        "id": polymer.id,
        "name": polymer.name,
        "rich_text": polymer.description,
        "wiki_collect_id": polymer.wiki_collect_id,  # 项目百科聚合
        "wiki_item_id": polymer.wiki_item_id,  # 项目百科 详情页
        "default_tab": polymer.default_tab,
        "banners": banners_list,
        "gadgets": polymer.get_polymer_gadget(),  # gadget
        "show_tabs": [{"recommend": x.recommend, "tab_type": x.tab_type} for x in polymer.tabs.filter(enable=True)],  # 展示的tabs列表
        "tags": tags,
        "agile_tags": agile_tags,
        "recommends": polymer.get_operate_recommends(city_id),  # 运营推荐数据,需在backend 做处理
        "followed": followed,
        "origin_info": origin_info,
        "top_topic": top_topic,
        "question_classify": polymer.get_question_classify , #讨论下问题的分类
        "default_question_classify": polymer.default_classify,
        "bg_image": polymer.bg_image,
        "pub_type": polymer.pub_type,
        "introduction": polymer.introduction,
    }
    data.update(polymer.get_wiki_info)

    return data


@bind_context("api/polymers/user/follow")
def user_follow_polymer(ctx, size=20):
    """用户关注的聚合页信息列表"""

    user = get_user_from_context(ctx)
    if not user:
        return []

    tags = UserTagRelation.objects.filter(user=user, related_tag__is_online=True,
                                          tag_type=USER_TAG_CHOICES.FOLLOWED).\
        values_list("related_tag_id", flat=True)

    polymers = get_polymer_info_by_tags(tag_list=list(tags), is_discuss=True, external_display=False)
    if not polymers:
        return []

    polymers_ids = [i["id"] for i in polymers]
    polymer_extra = PolymerExtra.objects.filter(polymer_id__in=polymers_ids)\
        .values("polymer_id", "total_cnt")

    polymer_extra_dict = {}
    for item in polymer_extra:
        polymer_extra_dict[item["polymer_id"]] = item["total_cnt"]

    polymers.sort(key=lambda i: (-polymer_extra_dict.get(i["id"], 0), i["id"]))

    return polymers[:size]


@bind_context("api/polymer/follow", login_required=True)
def follow_polymer(ctx, zone_id):
    if not zone_id:
        return gen(CODES.PARAMS_INCOMPLETE)

    user = get_user_from_context(ctx)
    try:
        polymer = Polymer.objects.get(pk=zone_id)
    except Polymer.DoesNotExist:
        return gen(CODES.ZONE_NOT_FOUND)

    tag_ids = [tag["id"] for tag in polymer.tag_list]
    UserTagRelation.multi_follow_tags(user.id, tag_ids)
    user_tag_relation_change.delay(user)

    return gen(CODES.SUCCESS)


@bind_context("api/polymer/unfollow", login_required=True)
def unfollow_polymer(ctx, zone_id):
    """
    新版圈子，取消关注
    :param ctx:
    :param zone_id:
    :return:
    """
    if not zone_id:
        return gen(CODES.PARAMS_INCOMPLETE)

    user = get_user_from_context(ctx)
    try:
        polymer = Polymer.objects.get(pk=zone_id)
    except Polymer.DoesNotExist:
        return gen(CODES.ZONE_NOT_FOUND)

    tag_ids =[tag["id"] for tag in polymer.tag_list]
    UserTagRelation.unfollow_tags(user.id, tag_ids)
    user_tag_relation_change.delay(user)

    return gen(CODES.SUCCESS)


@bind_context("api/polymer/base_info")
def follow_polymer(ctx, polymer_id):
    if not polymer_id:
        return gen(CODES.PARAMS_INCOMPLETE)


    try:
        polymer = Polymer.objects.get(pk=polymer_id)
    except Polymer.DoesNotExist:
        return gen(CODES.ZONE_NOT_FOUND)

    user = get_user_from_context(ctx)
    followed = False
    if user:
        tag_ids = [tag["id"] for tag in polymer.tag_list]
        followed = UserTagRelation.user_followed_by_tag_ids(user.id, tag_ids)

    return {
        "user_id": user.id if user else None,
        "followed": followed,
        "name": polymer.name,
        "description": polymer.description,
        "polymer_id": polymer_id,
        "tags": polymer.tag_list,
        "default_tab": polymer.default_tab,
        "default_classify": polymer.default_classify,
        "question_classify": polymer.get_question_classify
    }
