"""blog models"""

import re

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

from .utils import Announcement, Category, ContentWarning


def validate_ap_address(value):
    """is the activitypub address valid?"""
    p = re.compile("@(.*)@((\w|-)*)\.((\w)*)")
    m = p.match(value)
    if not m:
        raise ValidationError(
            _("%(value)s should be in the form '@user@domain.tld'"),
            params={"value": value},
        )


class BlogData(models.Model):
    """Base bloggy data"""

    title = models.CharField(max_length=2000)
    author_name = models.CharField(max_length=1000, null=True, blank=True)
    url = models.URLField(max_length=2000, unique=True)
    description = models.TextField(null=True, blank=True)
    updateddate = models.DateTimeField()
    pubdate = models.DateTimeField(null=True, default=timezone.now)

    class Meta:
        """This is an abstract model for common data"""

        abstract = True

    def __str__(self):
        """display for admin dropdowns"""
        return self.title

    def get_absolute_url(self):
        """override"""

        return self.url

    def save(self, *args, **kwargs):
        if not self.updateddate:
            self.updateddate = timezone.now()
        super().save(*args, **kwargs)


class Blog(BlogData):
    """A blog"""

    feed = models.URLField(max_length=2000)
    category = models.CharField(choices=Category.choices, max_length=4)
    added = models.DateTimeField(default=timezone.now)
    approved = models.BooleanField(default=False)
    announced = models.BooleanField(default=False)
    failing = models.BooleanField(default=False, blank=True, null=True)
    suspended = models.BooleanField(default=False, blank=True, null=True)
    suspension_lifted = models.DateTimeField(blank=True, null=True)
    active = models.BooleanField(null=True, default=True)
    activitypub_account_name = models.CharField(
        max_length=200, blank=True, null=True, validators=[validate_ap_address]
    )
    contact_email = models.EmailField(blank=True, null=True)

    def announce(self):
        """queue announcement"""

        if self.activitypub_account_name:
            author = f" by {self.activitypub_account_name}"
        elif self.author_name:
            author = f" by {self.author_name}"
        else:
            author = ""

        category = Category(self.category).label
        status = f"{self.title}{author} has been added to Aus GLAMR! \n\nIt's about {category}\n\n{self.url}"

        Announcement.objects.create(status=status)
        self.announced = True
        super().save()

    def set_failing(self):
        """set the blog feed as failing"""

        self.failing = True
        super().save()

    def set_success(self, updateddate):
        """
        set failing to false
        set the updateddate to a datetime

        """

        self.failing = False
        self.updateddate = updateddate
        super().save()


class Article(BlogData):
    """A blog post"""

    blog = models.ForeignKey(Blog, on_delete=models.CASCADE, related_name="articles")
    guid = models.CharField(max_length=2000)
    tags = models.ManyToManyField("Tag", related_name="articles")

    # pylint: disable=undefined-variable
    def announce(self):
        """queue a blog post announcement"""

        summary = []
        warnings = ContentWarning.objects.all()
        for warning in warnings:
            for text in [self.title, self.description]:
                label = warning.is_in(text)
                if label:
                    summmary.append(label)
            for tag in self.tags.all():  # pylint: disable=E1133
                label = warning.is_in(tag.name)
                if label:
                    summmary.append(label)

        summary_text = ", ".join(summary) if len(summary) > 0 else None
        author = self.blog.activitypub_account_name or self.author_name

        if self.blog.activitypub_account_name:
            author = f"{self.blog.activitypub_account_name} "
        elif self.author_name:
            author = f"{self.author_name} "
        else:
            author = ""

        status = f"{self.title} ({author}on {self.blog.title})\n\n{self.url}"

        Announcement.objects.create(status=status, summary=summary_text)


class Tag(models.Model):
    """An article tag"""

    name = models.CharField(max_length=100, unique=True)

    def __str__(self):
        """display for admin dropdowns"""
        return self.name
