from django.conf import settings
from django.contrib.sitemaps import Sitemap
from django.utils.translation import gettext_lazy as _

from blog.models import Post
from core.models import Brand, Category, Product


class SitemapLanguageMixin:
    def _lang(self) -> str:
        req = getattr(self, "request", None)
        return getattr(req, "LANGUAGE_CODE", settings.LANGUAGE_CODE)


class StaticPagesSitemap(SitemapLanguageMixin, Sitemap):  # type: ignore [type-arg]
    protocol = "https"
    changefreq = "monthly"
    priority = 0.8
    limit = 1000

    def items(self):
        lang = self._lang()
        pages = [
            {
                "name": _("Home"),
                "path": f"/{lang}",
                "lastmod": settings.RELEASE_DATE,
            },
            {
                "name": _("Contact Us"),
                "path": f"/{lang}/contact-us",
                "lastmod": settings.RELEASE_DATE,
            },
            {
                "name": _("About Us"),
                "path": f"/{lang}/about-us",
                "lastmod": settings.RELEASE_DATE,
            },
        ]

        for static_post_page in Post.objects.filter(is_static_page=True, is_active=True).only(
            "title", "slug", "modified"
        ):
            pages.append(
                {
                    "name": static_post_page.title,
                    "path": f"/{lang}/information/{static_post_page.slug}",
                    "lastmod": static_post_page.modified,
                }
            )

        return pages

    def location(self, obj):
        return obj["path"]

    def lastmod(self, obj):
        return obj.get("lastmod")


class ProductSitemap(SitemapLanguageMixin, Sitemap):  # type: ignore [type-arg]
    protocol = "https"
    changefreq = "daily"
    priority = 0.9
    limit = 25000

    def items(self):
        return (
            Product.objects.filter(
                is_active=True,
                brand__is_active=True,
                category__is_active=True,
                stocks__isnull=False,
                stocks__vendor__is_active=True,
            )
            .only("uuid", "name", "modified", "slug")
            .order_by("-modified")
        )

    def lastmod(self, obj):
        return obj.modified

    def location(self, obj):
        return f"/{self._lang()}/product/{obj.slug if obj.slug else '404-non-existent-product'}"


class CategorySitemap(SitemapLanguageMixin, Sitemap):  # type: ignore [type-arg]
    protocol = "https"
    changefreq = "weekly"
    priority = 0.7
    limit = 10000

    def items(self):
        return Category.objects.filter(is_active=True).only("uuid", "name", "modified").order_by("-modified")

    def lastmod(self, obj):
        return obj.modified

    def location(self, obj):
        return f"/{self._lang()}/catalog/{obj.slug if obj.slug else '404-non-existent-category'}"


class BrandSitemap(SitemapLanguageMixin, Sitemap):  # type: ignore [type-arg]
    protocol = "https"
    changefreq = "weekly"
    priority = 0.6
    limit = 10000

    def items(self):
        return Brand.objects.filter(is_active=True).only("uuid", "name", "modified").order_by("-modified")

    def lastmod(self, obj):
        return obj.modified

    def location(self, obj):
        return f"/{self._lang()}/brand/{obj.slug if obj.slug else '404-non-existent-brand'}"
