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

import copy
from collections import defaultdict
from operator import itemgetter

from django.db.models import Q

from launch.models import (
    QuestionnaireAnswer,
    QuestionnaireAnswerRelationTag,
    QuestionnaireAnswerRelationTagV3,
    QuestionnaireAnswerRelationAttrTag,
    QuestionnaireAnswerInterestQuestion,
)
from agile.services import TagV3Service


class QuestionnaireAnswerService(object):
    model = QuestionnaireAnswer
    base_query = Q(is_delete=False)

    @classmethod
    def get_exclude_names_by_ids(cls, answer_ids):
        return set(cls.model.objects.filter(
            pk__in=answer_ids, is_delete=False
        ).values_list("questionnaire_content", flat=True))

    @staticmethod
    def get_valid_answers(answers, exclude_names, display_nums):
        """
        获取有效的回答列表
        :param answers:
        :param exclude_names:
        :param display_nums:
        :return:
        """
        _answer_list = []
        for item in answers:
            _answer_content = item["questionnaire_content"]
            if _answer_content in exclude_names:
                continue

            _answer_data = {
                "a_id": item["id"],
                "text": item["questionnaire_content"],
                "image_url": item["questionnaire_image_url"],
                "is_ugc": item["is_ugc"],
            }

            _answer_list.append(_answer_data)

            if len(_answer_list) == display_nums:
                break

        return _answer_list

    @classmethod
    def get_querysets_data(cls, query, order_by=[], fields=[]):
        query_sets = cls.model.objects.filter(query).order_by(*order_by)

        if fields:
            query_sets = query_sets.values(*fields)

        return query_sets

    @staticmethod
    def _convert_answer_info_with_question(answers):
        """
        以问题id做key格式化回答
        :param answers:
        :return:
        """
        force_qa_dic = defaultdict(list)

        for force_qa in answers:
            force_qa_dic[force_qa["questionnaire_question_id"]].append(force_qa)

        return dict(force_qa_dic)

    @staticmethod
    def convert_data(map_items):
        convert_dic = {}

        for item_id, questionnaire_answer_id in map_items:
            if questionnaire_answer_id not in convert_dic:
                convert_dic[questionnaire_answer_id] = []

            convert_dic[questionnaire_answer_id].append(item_id)

        return convert_dic

    @classmethod
    def get_questionnaire_answers(cls, question_ids, exclude_names, display_nums=9):
        """
        获取问卷问题下的回答
        :param question_ids:
        :param exclude_names:
        :param display_nums:
        :return: {question_id:answer_list[]}
        """
        result = {}

        question_ids = set(filter(None, question_ids))
        if not question_ids:
            return result

        order_by = ["rank"]
        fields = ["id", "is_ugc", "questionnaire_question_id", "questionnaire_content", "questionnaire_image_url"]

        # 先取强制漏出回答
        force_display_query = cls.base_query & Q(
            questionnaire_question_id__in=question_ids,
            is_force_display=True
        )
        force_display_objs = cls.get_querysets_data(
            force_display_query,
            order_by=order_by,
            fields=fields
        )

        need_increase_q_ids = copy.deepcopy(question_ids)  # 强制漏出的回答数量不够，需要补充的问题id。默认是原始的问题id列表

        for q_id, answer_list in cls._convert_answer_info_with_question(force_display_objs).items():
            force_display_answers = cls.get_valid_answers(
                answer_list,
                exclude_names,
                display_nums
            )

            if len(force_display_answers) >= display_nums:  # 如果强制展示回答数量大于等于展示回答的总数，移除对应的问题id
                need_increase_q_ids.remove(q_id)

            result[q_id] = force_display_answers[:display_nums]

        # 再取普通回答
        if need_increase_q_ids:
            ordinary_query = cls.base_query & Q(
                questionnaire_question_id__in=need_increase_q_ids,
                is_force_display=False,
            )
            ordinary_answer_objs = cls.get_querysets_data(
                ordinary_query,
                order_by=order_by,
                fields=fields
            )

            for q_id, answer_list in cls._convert_answer_info_with_question(ordinary_answer_objs).items():
                _answers = result.get(q_id, [])
                ordinary_answers = cls.get_valid_answers(
                    answer_list,
                    exclude_names,
                    display_nums=(display_nums - len(_answers))
                )
                ordinary_answers.extend(_answers)

                result[q_id] = ordinary_answers

        return result

    @classmethod
    def get_record_info_by_answer_ids(cls, answer_ids):
        """
        通过回答id，获取上报相关信息
        :param answer_ids:
        :return: 以关联的问题id为key, 其他所有信息组到一个列表里 {"questionnaire_question_id": [{"回答信息"},]}
        """
        answers = cls.model.objects.filter(
            pk__in=answer_ids,
            is_delete=False
        ).values(
            "id", "questionnaire_question_id", "answer_create_content", "answer_create_image_url",
            "questionnaire_content", "relation_question_id", "is_ugc"
        )

        answer_ids = list(map(itemgetter("id"), answers))
        a_tags = QuestionnaireAnswerRelationTag.objects.filter(
            questionnaire_answer_id__in=answer_ids
        ).values_list("tag_id", "questionnaire_answer_id")

        a_tags_v3 = QuestionnaireAnswerRelationTagV3.objects.filter(
            questionnaire_answer_id__in=answer_ids
        ).values_list("tag_v3_id", "questionnaire_answer_id")

        # a_attr_tags = QuestionnaireAnswerRelationAttrTag.objects.filter(
        #     questionnaire_answer_id__in=answer_ids
        # ).values_list("attr_tag_id", "questionnaire_answer_id")

        a_tags_dic = cls.convert_data(a_tags)
        a_tags_v3_dic = cls.convert_data(a_tags_v3)
        # a_attr_tags_dic = cls.convert_data(a_attr_tags)

        tag_v3s = TagV3Service.get_tags_v3_by_ids([i[0] for i in a_tags_v3])
        # attr_tags = TagV3Service.get_attr_tag_info_by_attr_ids([i[0] for i in a_attr_tags])

        answers_data_dic = defaultdict(list)
        for item in answers:
            tag_v3_ids = a_tags_v3_dic.get(item["id"], [])
            # attr_tag_ids = a_attr_tags_dic.get(item["id"], [])
            _data = {
                "questionnaire_answer_id": item["id"],
                "questionnaire_content": item["questionnaire_content"],  # 问卷回答对应的文案
                "content": item["answer_create_content"],
                "image_url": item["answer_create_image_url"],
                "relation_question_id": item["relation_question_id"],
                "tag_ids": a_tags_dic.get(item["id"], []),
                "tag_v3_ids": tag_v3_ids,
                "tags": [tag_v3s[tag_v3_id] for tag_v3_id in tag_v3_ids if tag_v3_id in tag_v3s],
                # "attr_tags": [attr_tags[attr_tag_id] for attr_tag_id in attr_tag_ids if attr_tag_id in attr_tags],
                "attr_tags": [],
                "is_ugc": item["is_ugc"],
            }
            answers_data_dic[item["questionnaire_question_id"]].append(_data)

        return dict(answers_data_dic)

    @classmethod
    def get_questionnaire_answer_questions_of_interest(cls, answer_ids):
        """
        获取回答关联的感兴趣的问题ID
        :param answer_ids:
        :return:
        """
        interest_questions = QuestionnaireAnswerInterestQuestion.objects.filter(
            questionnaire_answer_id__in=answer_ids
        ).values_list("question_id", "questionnaire_answer_id")

        return cls.convert_data(interest_questions)
