# coding: utf-8
from __future__ import absolute_import, print_function, unicode_literals

from django.core.exceptions import FieldDoesNotExist
from django.db import models
from django.db.models import Q
from django.utils import timezone
from gm_types.gaia import TAG_TYPE

from api.tool.datetime_tool import get_timestamp
from api.models.tag import Tag
from api.models.city import City
from api.tool.log_tool import logging_exception


class SeoCategory(models.Model):

    class Meta:
        verbose_name = u'SEO分类'
        app_label = 'api'

    tag_id = models.IntegerField(verbose_name=u'对应tag_id', max_length=11)
    name = models.CharField(verbose_name=u'seo分类名称', max_length=64)
    title = models.CharField(verbose_name=u'分类标题', max_length=128, null=True, blank=True)
    wiki_id = models.IntegerField(verbose_name=u'关联百科id', max_length=11, null=True, blank=True)
    category_type = models.CharField(verbose_name=u'分类类型', max_length=4, choices=TAG_TYPE, null=True, blank=True)
    icon = models.CharField(verbose_name=u'分类图标', max_length=128, null=True, blank=True)
    banner = models.CharField(verbose_name=u'分类横幅', max_length=128, null=True, blank=True)
    show_diary = models.BooleanField(verbose_name=u'显示日记本', default=False)
    desc_md = models.TextField(verbose_name=u'描述', null=True, blank=True)
    introduction = models.TextField(verbose_name=u'简介(富文本)', null=True, blank=True)
    is_online = models.BooleanField(verbose_name=u'是否上线', default=False)
    keywords = models.TextField(verbose_name=u'关键词', null=True, blank=True)

    @property
    def tag_name(self):
        return Tag.objects.get(id=self.tag_id).name if Tag.objects.get(id=self.tag_id).name else ''

    @classmethod
    def get_all_category_ids(cls):
        all_category_info = cls.objects.filter(is_online=True).values('id')
        all_ids = [category_info['id'] for category_info in all_category_info]
        return all_ids

    def detail_data(self):
        return {
            'category_id': self.id,
            'tag_id': self.tag_id,
            'name': self.name,
            'title': self.title,
            'category_type': self.category_type,
            'desc_md': self.desc_md,
            'introduction': self.introduction,
            'is_online': self.is_online,
            'keywords': self.keywords,
        }

    def simple_data(self):
        return {
            'category_id': self.id,
            'name': self.name,
            'tag_id': self.tag_id,
        }

    def parent_categories(self, category_is_online=True):
        if category_is_online:
            relations = CategoryRelation.objects.filter(child_category=self,
                                                        child_category__is_online=category_is_online
                                                        ).select_related('parent_category')
        else:
            relations = CategoryRelation.objects.filter(child_category=self).select_related('parent_category')

        categories = [relation.parent_category for relation in relations]
        return categories

    def child_categories(self, category_is_online=True, count=None):
        if self.category_type == TAG_TYPE.ITEM_WIKI:
            return []

        if category_is_online:
            relations = CategoryRelation.objects.filter(parent_category=self,
                                                        child_category__is_online=category_is_online
                                                        ).select_related('child_category')
        else:
            relations = CategoryRelation.objects.filter(parent_category=self).select_related('child_category')

        if count is not None:
            categories = [relation.child_category for relation in relations[:count]]
        else:
            categories = [relation.child_category for relation in relations]

        return categories

    def related_digests(self, start_num, count, order_by):
        digests = self.seodigest_set.filter(is_online=True)
        if order_by is not None:
            try:
                _ = SeoDigest._meta.get_field(order_by)
            except FieldDoesNotExist:
                logging_exception()
                return []

            digests = self.seodigest_set.filter(is_online=True).order_by(order_by)

        if start_num > digests.count():
            return []

        if start_num + count > digests.count():
            return digests[start_num:]

        return digests[start_num:start_num + count]

    def __unicode__(self):
        return "id:%s %s type:%s" % (self.id, self.name, self.category_type)


class CategoryRelation(models.Model):

    class Meta:
        verbose_name = u'SEO分类层级关系'
        app_label = 'api'

    parent_category = models.ForeignKey(SeoCategory, default=None, null=True, blank=True, related_name='parent_relations')
    child_category = models.ForeignKey(SeoCategory, default=None, null=True, blank=True, related_name='child_relations')

    def get_all_parent_category(self):
        relations = CategoryRelation.objects.filter(child_category=self)
        return relations.values_list('parent_category_id')


class SeoDigest(models.Model):

    class Meta:
        verbose_name = u'SEO相关资讯'
        app_label = 'api'

    title = models.CharField(verbose_name=u'咨询标题', max_length=128)
    keywords = models.TextField(verbose_name=u'关键词', null=True, blank=True)
    description = models.TextField(verbose_name=u'描述', null=True, blank=True)
    seo_category = models.ForeignKey(SeoCategory, default=None, null=True, blank=True)
    editor = models.CharField(verbose_name=u'编辑名称', max_length=16, default=None, null=True, blank=True)
    content = models.TextField(verbose_name=u'资讯内容', null=True, blank=True)
    create_time = models.DateTimeField(verbose_name=u'编辑时间', default=timezone.now)
    online_time = models.DateTimeField(verbose_name=u'上线时间', default=timezone.now, db_index=True)
    is_online = models.BooleanField(verbose_name=u'是否上线', default=False)

    def detail_data(self):
        return {
            'id': self.id,
            'title': self.title,
            'keywords': self.keywords,
            'description': self.description,
            'seo_category': {
                'category_id': self.seo_category.id,
                'category_name': self.seo_category.name,
                'is_online': self.seo_category.is_online,
            },
            'editor': self.editor,
            'content': self.content,
            'create_time': get_timestamp(self.create_time),
            'online_time': get_timestamp(self.online_time),
            'is_online': self.is_online,
        }

    def digests_in_same_category(self, size=10, is_online=True):
        if is_online:
            digests = self.seo_category.seodigest_set.filter(is_online=is_online)
        else:
            digests = self.seo_category.seodigest_set.all()

        digests = digests.exclude(id=self.id)[:size]

        return digests

    def digests_in_parent_category(self, size=10, category_is_online=True):
        parent_categories = self.seo_category.parent_categories(category_is_online=category_is_online)

        brother_categories = []
        for parent_category in parent_categories:
            brother_categories.extend(parent_category.child_categories(category_is_online=category_is_online))

        all_categories = parent_categories + brother_categories

        digests = SeoDigest.get_digests_objs_by_categories(all_categories).exclude(id=self.id)[:size]

        return digests

    @classmethod
    def get_digests_objs_by_categories(cls, categories):
        digests = cls.objects.filter(seo_category__in=categories)
        return digests

    def related_digests_for_list(self, size=50, category_is_online=True):
        related_digests = list(self.digests_in_same_category(size=size))

        if len(related_digests) < size:
            parent_categories_digests = self.digests_in_parent_category(size=size - len(related_digests),
                                                                        category_is_online=category_is_online)
            related_digests.extend(list(parent_categories_digests))

        digests_info = []
        for digest in related_digests:
            digests_info.append(
                {
                    'id': digest.id,
                    'title': digest.title,
                    'online_time': get_timestamp(digest.online_time),
                    'category_name': self.seo_category.name,
                }
            )

        return digests_info


class FriendlySite(models.Model):
    class Meta:
        verbose_name = u'友情链接'
        app_label = 'api'

    site_name = models.CharField(verbose_name=u'页面名称', max_length=32)
    site_url = models.CharField(verbose_name=u'页面地址', max_length=128)
    is_online = models.BooleanField(verbose_name=u'是否在线', default=False)
    city = models.ForeignKey(City, verbose_name=u'友情链接城市', default=None, null=True)

    def data(self):
        return {
            'site_name': self.site_name,
            'site_url': self.site_url,
            "city_id": self.city_id,
        }

    @classmethod
    def online_sites(cls, city_id):
        query = Q(is_online=True)
        if city_id:
            query &= Q(city_id=city_id)
        else:
            query &= (Q(city_id='') | Q(city_id__isnull=True))
        sites = cls.objects.filter(query)
        return [site.data() for site in sites]


class InnerHyperlink(models.Model):
    class Meta:
        verbose_name = u'内链'
    name = models.CharField(verbose_name=u'页面名称', max_length=32)
    url = models.CharField(verbose_name=u'页面地址', max_length=128)

    def data(self):
        return {
            'name': self.name,
            'url': self.url,
        }

    @classmethod
    def links(cls):
        hyperlinks = cls.objects.all()
        return [link.data() for link in hyperlinks]
