import datetime

from django.core.exceptions import ValidationError
from django.db import models
from django.utils.translation import gettext_lazy as _

from wagtail.admin.panels import (
    FieldPanel,
    MultiFieldPanel,
    InlinePanel,
)
from wagtail.fields import RichTextField
from modelcluster.contrib.taggit import ClusterTaggableManager
from wagtailmarkdown.fields import MarkdownField
from colorful.fields import RGBColorField

from .utils import get_image_model_path
import markdown


class BlogAbstract(models.Model):
    description = models.CharField(
        verbose_name=_("Description"),
        max_length=255,
        blank=True,
        help_text=_("The blog description that will appear under the title."),
    )
    header_image = models.ForeignKey(
        get_image_model_path(),
        verbose_name=_("Header image"),
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
    )

    main_color = RGBColorField(_("Blog Main Color"), default="#4D6AE0")

    display_comments = models.BooleanField(default=False, verbose_name=_("Display comments"))
    display_categories = models.BooleanField(default=True, verbose_name=_("Display categories"))
    display_tags = models.BooleanField(default=True, verbose_name=_("Display tags"))
    display_popular_entries = models.BooleanField(default=True, verbose_name=_("Display popular entries"))
    display_last_entries = models.BooleanField(default=True, verbose_name=_("Display last entries"))
    display_archive = models.BooleanField(default=True, verbose_name=_("Display archive"))

    disqus_api_secret = models.TextField(blank=True)
    disqus_shortname = models.CharField(max_length=128, blank=True)

    num_entries_page = models.IntegerField(default=5, verbose_name=_("Entries per page"))
    num_last_entries = models.IntegerField(default=3, verbose_name=_("Last entries limit"))
    num_popular_entries = models.IntegerField(default=3, verbose_name=_("Popular entries limit"))
    num_tags_entry_header = models.IntegerField(default=5, verbose_name=_("Tags limit entry header"))

    short_feed_description = models.BooleanField(default=True, verbose_name=_("Use short description in feeds"))

    content_panels = [
        FieldPanel("description", classname="full"),
        FieldPanel("header_image"),
        FieldPanel("main_color"),
    ]
    settings_panels = [
        MultiFieldPanel(
            [
                FieldPanel("display_categories"),
                FieldPanel("display_tags"),
                FieldPanel("display_popular_entries"),
                FieldPanel("display_last_entries"),
                FieldPanel("display_archive"),
            ],
            heading=_("Widgets"),
        ),
        MultiFieldPanel(
            [
                FieldPanel("num_entries_page"),
                FieldPanel("num_last_entries"),
                FieldPanel("num_popular_entries"),
                FieldPanel("num_tags_entry_header"),
            ],
            heading=_("Parameters"),
        ),
        MultiFieldPanel(
            [
                FieldPanel("display_comments"),
                FieldPanel("disqus_api_secret"),
                FieldPanel("disqus_shortname"),
            ],
            heading=_("Comments"),
        ),
        MultiFieldPanel(
            [
                FieldPanel("short_feed_description"),
            ],
            heading=_("Feeds"),
        ),
    ]

    class Meta:
        abstract = True


class EntryAbstract(models.Model):
    body = RichTextField(verbose_name=_("body"), blank=True, null=True)
    markdown_body = MarkdownField(blank=True, null=True, verbose_name="body (Markdown)")
    tags = ClusterTaggableManager(through="puput.TagEntryPage", blank=True)
    date = models.DateTimeField(verbose_name=_("Post date"), default=datetime.datetime.today)
    header_image = models.ForeignKey(
        get_image_model_path(),
        verbose_name=_("Header image"),
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
    )
    categories = models.ManyToManyField("puput.Category", through="puput.CategoryEntryPage", blank=True)
    excerpt = RichTextField(
        verbose_name=_("excerpt"),
        blank=True,
        help_text=_(
            "Entry excerpt to be displayed on entries list. "
            "If this field is not filled, a truncate version of body text will be used."
        ),
    )
    num_comments = models.IntegerField(default=0, editable=False)

    content_panels = [
        MultiFieldPanel(
            [
                FieldPanel("title", classname="title"),
                FieldPanel("header_image"),
                FieldPanel("body", classname="full"),
                FieldPanel("markdown_body"),
                FieldPanel("excerpt", classname="full"),
            ],
            heading=_("Content"),
        ),
        MultiFieldPanel(
            [
                FieldPanel("tags"),
                InlinePanel("entry_categories", label=_("Categories")),
                InlinePanel(
                    "related_entrypage_from",
                    label=_("Related Entries"),
                    panels=[FieldPanel("entrypage_to")],
                ),
            ],
            heading=_("Metadata"),
        ),
    ]

    class Meta:
        abstract = True

    def clean(self):
        if not (self.markdown_body or self.body):
            raise ValidationError("You must specify either body or markdown body")

    def save(self, *args, **kwargs):
        if self.markdown_body:
            self.body = markdown.markdown(self.markdown_body, extensions=["extra", "codehilite"])
        super().save(*args, **kwargs)
