# -*- coding: utf-8 -*-
# based on original @nephila plugin https://github.com/nephila/djangocms-blog

from django.db import models
from django.db.models import Q
from django.utils.translation import ugettext_lazy as _
from django.core.urlresolvers import reverse
from django.core.cache import cache
from django.utils import timezone
from django.utils.encoding import force_text, python_2_unicode_compatible
from django.conf import settings
from django.contrib.auth import get_user_model

from cms.models import CMSPlugin, PlaceholderField

from djangocms_text_ckeditor.fields import HTMLField
from filer.fields.image import FilerImageField
from taggit_autosuggest.managers import TaggableManager
from taggit.models import TaggedItem

from oscar.core.utils import slugify
from oscar.core.compat import AUTH_USER_MODEL
from oscar.models.fields import AutoSlugField
from oscar.apps.catalogue.abstract_models import AbstractCategory

# TODO: move defaults to the app's settings module
ENABLE_COMMENTS = getattr(settings, 'ENABLE_COMMENTS', False)
AUTHOR_DEFAULT = getattr(settings, 'AUTHOR_DEFAULT', True)
LATEST_NEWS = getattr(settings, 'LATEST_NEWS', 3)


# it's not the best place for this method but i've not found yet better way to show
# annotated tags for each instance and keep it DRY :)
def get_tag_cloud(model, queryset, tags_filter=None):
    if tags_filter is None:
        tags_filter = set()
        for item in queryset.all():
            tags_filter.update(item.tags.all())

    tags_filter = set([tag.id for tag in tags_filter])
    tags = set(TaggedItem.objects.filter(
        content_type__model=model.__name__.lower()
    ).values_list('tag_id', flat=True))

    if tags_filter is not None:
        tags = tags.intersection(tags_filter)
    tag_ids = list(tags)

    kwargs = TaggedItem.bulk_lookup_kwargs(queryset)
    kwargs['tag_id__in'] = tag_ids
    counted_tags = dict(TaggedItem.objects
                                  .filter(**kwargs)
                                  .values('tag')
                                  .annotate(count=models.Count('tag'))
                                  .values_list('tag', 'count'))
    tags = TaggedItem.tag_model().objects.filter(pk__in=counted_tags.keys())
    for tag in tags:
        tag.count = counted_tags[tag.pk]
    return sorted(tags, key=lambda x: -x.count)


class NewsManager(models.Manager):

    def __init__(self, *args, **kwargs):
        self.published_query = Q(publish=True) & Q(date_published__lte=timezone.now()) & \
                           (Q(date_published_end__isnull=True) | Q(date_published_end__gte=timezone.now()))
        super(NewsManager, self).__init__(*args, **kwargs)

    def tag_cloud(self):
        queryset = self.get_queryset()
        return get_tag_cloud(self.model, queryset)


class PublishedNewsManager(NewsManager):
    """
        Filters out all unpublished and items with a publication
        date in the future
    """
    def get_queryset(self):
        return super(PublishedNewsManager, self).get_queryset().filter(self.published_query)


class News(models.Model):
    """
    News