# coding:utf-8
from collections import defaultdict

from django.db import models
from django.core.management import BaseCommand
from django.conf import settings

from gm_types.gaia import DIARY_CONTENT_LEVEL
from gm_types.gaia import TAG_V3_TYPE
from gm_types.gaia import PROBLEM_FLAG_CHOICES
from gm_types.mimas import TRACTATE_CONTENT_LEVEL

from agile.models import TagV3, TagMapOldTag
from api.models import Tag, ServiceNewTag, Service, Doctor, Hospital
from talos.models.diary import Diary, DiaryTagV3
from talos.models.topic import Problem


mimas_slave = settings.MIMAS_SLAVE_DB_NAME
slave = settings.SLAVE_DB_NAME


class Tractate(models.Model):

    class Meta:
        verbose_name = u'新帖子'
        db_table = 'api_tractate'
        app_label = 'talos'

    is_online = models.BooleanField(verbose_name=u"是否在线", default=True)
    content_level = models.CharField(verbose_name=u"内容等级", max_length=12,
                                     choices=TRACTATE_CONTENT_LEVEL, default=TRACTATE_CONTENT_LEVEL.NULL)


class TractateTagV3(models.Model):
    class Meta:
        db_table = 'api_tractate_tag_v3'
        app_label = "talos"

    tractate_id = models.IntegerField(verbose_name="新帖子id", db_index=True)
    tag_v3_id = models.IntegerField(verbose_name="标签V3", db_index=True)



class Command(BaseCommand):

    @staticmethod
    def get_service_cnt_info_by_tag_id(tag_id):

        service_ids = list(ServiceNewTag.objects.using(slave).filter(tag_id=tag_id).values_list("service_id", flat=True))
        service_cnt = Service.objects.using(slave).filter(pk__in=service_ids, is_online=True).count()

        doctor_ids = list(Service.objects.using(slave).filter(pk__in=service_ids, is_online=True).values_list("doctor_id", flat=True))
        doctor_cnt = Doctor.objects.filter(is_online=True, id__in=doctor_ids).count()

        hospital_ids = list(Doctor.objects.using(slave).filter(pk__in=doctor_ids, is_online=True).values_list("hospital_id", flat=True))
        hospital_cnt = Hospital.objects.filter(is_online=True, id__in=hospital_ids).count()

        return {
            "service_cnt": service_cnt,
            "doctor_cnt": doctor_cnt,
            "hospital_cnt": hospital_cnt,
        }

    @staticmethod
    def get_diary_cnt_info_by_tag_id(tag_id):
        diary_ids = list(DiaryTagV3.objects.using(mimas_slave).filter(tag_v3_id=tag_id).values_list("diary_id", flat=True))

        level3_diary_cnt = Diary.objects.using(mimas_slave).filter(
            pk__in=diary_ids, is_online=True,
            content_level__in=[DIARY_CONTENT_LEVEL.GENERAL, DIARY_CONTENT_LEVEL.FINE, DIARY_CONTENT_LEVEL.EXCELLENT, DIARY_CONTENT_LEVEL.BETTER, DIARY_CONTENT_LEVEL.OUTSTANDING]
        ).count()

        no_empty_diary_cnt = 0
        diarys = Diary.objects.using(mimas_slave).filter(pk__in=diary_ids, is_online=True)
        for diary in diarys:
            if Problem.objects.using(mimas_slave).filter(diary_id=diary.id, flag=PROBLEM_FLAG_CHOICES.NORMAL, is_online=True).exists():
                no_empty_diary_cnt += 1

        return {
            "level3_diary_cnt": level3_diary_cnt,
            "no_empty_diary_cnt": no_empty_diary_cnt,
        }

    @staticmethod
    def get_tractate_cnt_info_by_tag_id(tag_id):
        tractate_ids = list(TractateTagV3.objects.using(mimas_slave).filter(tag_v3_id=tag_id).values_list("tractate_id", flat=True))
        trancate_cnt = Tractate.objects.using(mimas_slave).filter(
            pk__in=tractate_ids,
            is_online=True,
            content_level__in=[TRACTATE_CONTENT_LEVEL.GENERAL, TRACTATE_CONTENT_LEVEL.FINE, TRACTATE_CONTENT_LEVEL.EXCELLENT, TRACTATE_CONTENT_LEVEL.OUTSTANDING]
        ).count()

        return {
            "trancate_cnt": trancate_cnt,
        }

    @staticmethod
    def get_tags():

        tags_v3 = TagV3.objects.using(slave).filter(tag_type=TAG_V3_TYPE.NORMAL).values("id", "name", "is_online")
        tags_v3_ids = [tag["id"] for tag in tags_v3]
        tags_v3_dict = {tag["id"]: tag for tag in tags_v3}

        tags_v3_map = TagMapOldTag.objects.using(slave).filter(tag_id__in=tags_v3_ids).values("tag_id", "old_tag_id")
        tags_v3_to_1 = defaultdict(list)
        for item in tags_v3_map:
            tags_v3_to_1[item["tag_id"]].append(item["old_tag_id"])

        tags_v1_ids = [item["old_tag_id"] for item in tags_v3_map]
        tags_v1 = Tag.objects.using(slave).filter(pk__in=tags_v1_ids, is_online=True).values("id", "name")
        tags_v1_dict = {item["id"]: item for item in tags_v1}

        res = {}
        for tag_v3_id, tag_v3 in tags_v3_dict.items():
            tags_v1_ids = tags_v3_to_1.get(tag_v3_id, [])
            v1 = [tags_v1_dict.get(tags_v1_id, None) for tags_v1_id in tags_v1_ids]
            res_v1 = [item["name"] + '(' + str(item["id"]) + ')' for item in v1 if item]

            res[tag_v3_id] = {
                "name": tag_v3["name"] + "(" + str(tag_v3_id) + ")",
                "is_online": tag_v3["is_online"],
                "tags_v1": res_v1
            }

        return res

    def handle(self, *args, **options):

        f = open("res.txt", "a")

        tags_info = self.get_tags()
        for tag_v3_id, info in tags_info.items():
            name = info["name"]
            is_online = u'是' if info["is_online"] else u'否'
            tags_v1 = ";".join(info["tags_v1"])

            service_cnt_info = self.get_service_cnt_info_by_tag_id(tag_v3_id)
            service_cnt = service_cnt_info.get("service_cnt", 0)
            doctor_cnt = service_cnt_info.get("doctor_cnt", 0)
            hospital_cnt = service_cnt_info.get("hospital_cnt", 0)

            diary_cnt_info = self.get_diary_cnt_info_by_tag_id(tag_v3_id)
            level3_diary_cnt = diary_cnt_info.get("level3_diary_cnt", 0)
            no_empty_diary_cnt = diary_cnt_info.get("no_empty_diary_cnt", 0)

            tractate_cnt_info = self.get_tractate_cnt_info_by_tag_id(tag_v3_id)
            trancate_cnt = tractate_cnt_info.get("trancate_cnt", 0)

            f.write(",".join([
                name,
                is_online,
                tags_v1,

                str(service_cnt),
                str(doctor_cnt),
                str(hospital_cnt),

                str(level3_diary_cnt),
                str(no_empty_diary_cnt),

                str(trancate_cnt),
            ]))
            f.write('\n')

        f.close()
