import typing
from datetime import datetime

from django.contrib.syndication.views import Feed
from django.template.loader import render_to_string
from django.urls import reverse

from .models import MainArticlePage, MainArticlesPage


class LatestArticlesFeed(Feed):
    def get_object(self, request, id: int) -> MainArticlesPage:
        return MainArticlesPage.objects.get(id=id)

    def title(self, obj: MainArticlesPage) -> str:
        return obj.title

    def link(self, obj: MainArticlesPage) -> str:
        return obj.get_full_url()

    def description(self, obj: MainArticlesPage) -> str:
        return obj.perex

    def items(self, obj: MainArticlesPage) -> list:
        return obj.materialize_shared_articles_query(
            obj.append_all_shared_articles_query(MainArticlePage.objects.child_of(obj))[
                :32
            ]
        )

    def item_title(self, item: MainArticlePage) -> str:
        return item.title

    def item_description(self, item: MainArticlePage) -> str:
        return render_to_string(
            "main/feed_item_description.html",
            {"item": item},
        )

    def item_pubdate(self, item: MainArticlePage) -> datetime:
        return datetime(
            item.date.year,
            item.date.month,
            item.date.day,
            12,
            0,
        )

    def item_author_name(self, item: MainArticlePage) -> str:
        if item.author:
            return item.author

        if item.author_page and item.author_page.title:
            return item.author_page.title

        return ""

    def item_categories(self, item: MainArticlePage) -> list:
        return item.get_tags

    def item_link(self, item: MainArticlePage) -> str:
        return item.get_full_url()

    def item_enclosure_url(self, item: MainArticlePage) -> typing.Union[None, str]:
        if item.image is None:
            return None

        return item.image.get_rendition("format-webp").full_url

    item_enclosure_mime_type = "image/webp"

    def item_enclosure_length(self, item: MainArticlePage) -> int:
        return item.image.file_size