from django.test import TestCase
from django.urls import reverse

from apps.products.models import Article, ArticleSection, MainProduct, SubProduct


class ProductViewsSetup(TestCase):
    def setUp(self):
        self.main_product = MainProduct.objects.create(
            name="Radiuma",
            slug="radiuma",
            short_description="Radiomics software",
            description="Full description.",
        )
        self.sub_product = SubProduct.objects.create(
            main_product=self.main_product,
            name="Image Processing",
            slug="image-processing",
            short_description="Filtering and registration",
            description="Sub description.",
        )
        self.article = Article.objects.create(
            sub_product=self.sub_product,
            title="Filtering",
            description="Article body.",
        )
        ArticleSection.objects.create(
            article=self.article,
            title="Standard",
            value="IBSI 2.0",
        )


class ProductOverviewViewTest(ProductViewsSetup):
    def test_overview_returns_200(self):
        response = self.client.get(reverse("products:overview"))
        self.assertEqual(response.status_code, 200)

    def test_overview_uses_correct_template(self):
        response = self.client.get(reverse("products:overview"))
        self.assertTemplateUsed(response, "products/overview.html")

    def test_overview_contains_main_product(self):
        response = self.client.get(reverse("products:overview"))
        self.assertIn(self.main_product, response.context["main_products"])

    def test_inactive_product_excluded(self):
        inactive = MainProduct.objects.create(
            name="Inactive",
            short_description="s",
            description="d",
            is_active=False,
        )
        response = self.client.get(reverse("products:overview"))
        self.assertNotIn(inactive, response.context["main_products"])


class MainProductDetailViewTest(ProductViewsSetup):
    def test_detail_returns_200(self):
        url = reverse("products:main_product_detail", kwargs={"main_slug": "radiuma"})
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

    def test_detail_uses_correct_template(self):
        url = reverse("products:main_product_detail", kwargs={"main_slug": "radiuma"})
        response = self.client.get(url)
        self.assertTemplateUsed(response, "products/main_detail.html")

    def test_detail_contains_product_in_context(self):
        url = reverse("products:main_product_detail", kwargs={"main_slug": "radiuma"})
        response = self.client.get(url)
        self.assertEqual(response.context["main_product"], self.main_product)

    def test_nonexistent_slug_returns_404(self):
        url = reverse("products:main_product_detail", kwargs={"main_slug": "nonexistent"})
        response = self.client.get(url)
        self.assertEqual(response.status_code, 404)

    def test_inactive_product_returns_404(self):
        self.main_product.is_active = False
        self.main_product.save()
        url = reverse("products:main_product_detail", kwargs={"main_slug": "radiuma"})
        response = self.client.get(url)
        self.assertEqual(response.status_code, 404)

    def test_detail_articles_in_context(self):
        main_article = Article.objects.create(
            main_product=self.main_product,
            title="Overview",
            description="Main product article.",
        )
        url = reverse("products:main_product_detail", kwargs={"main_slug": "radiuma"})
        response = self.client.get(url)
        self.assertIn("articles", response.context)
        self.assertIn(main_article, list(response.context["articles"]))
        self.assertNotIn(self.article, list(response.context["articles"]))


class SubProductDetailViewTest(ProductViewsSetup):
    def test_sub_detail_returns_200(self):
        url = reverse(
            "products:sub_product_detail",
            kwargs={"main_slug": "radiuma", "sub_slug": "image-processing"},
        )
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

    def test_sub_detail_uses_correct_template(self):
        url = reverse(
            "products:sub_product_detail",
            kwargs={"main_slug": "radiuma", "sub_slug": "image-processing"},
        )
        response = self.client.get(url)
        self.assertTemplateUsed(response, "products/sub_detail.html")

    def test_sub_detail_context_keys(self):
        url = reverse(
            "products:sub_product_detail",
            kwargs={"main_slug": "radiuma", "sub_slug": "image-processing"},
        )
        response = self.client.get(url)
        self.assertIn("main_product", response.context)
        self.assertIn("sub_product", response.context)
        self.assertIn("articles", response.context)
        self.assertIn("siblings", response.context)

    def test_sub_detail_articles_in_context(self):
        url = reverse(
            "products:sub_product_detail",
            kwargs={"main_slug": "radiuma", "sub_slug": "image-processing"},
        )
        response = self.client.get(url)
        self.assertIn(self.article, list(response.context["articles"]))

    def test_nonexistent_sub_slug_returns_404(self):
        url = reverse(
            "products:sub_product_detail",
            kwargs={"main_slug": "radiuma", "sub_slug": "does-not-exist"},
        )
        response = self.client.get(url)
        self.assertEqual(response.status_code, 404)

    def test_mismatched_main_slug_returns_404(self):
        url = reverse(
            "products:sub_product_detail",
            kwargs={"main_slug": "wrong-product", "sub_slug": "image-processing"},
        )
        response = self.client.get(url)
        self.assertEqual(response.status_code, 404)


class SubProductOlderVersionsViewTest(ProductViewsSetup):
    def test_versions_returns_200(self):
        from apps.products.models import SubProductVersion

        SubProductVersion.objects.create(
            sub_product=self.sub_product,
            version="9.9",
            is_featured_stable=True,
            windows_download_url="https://example.com/w",
            is_active=True,
        )
        SubProductVersion.objects.create(
            sub_product=self.sub_product,
            version="9.8",
            is_featured_stable=False,
            windows_download_url="https://example.com/w2",
            is_active=True,
        )
        url = reverse(
            "products:sub_product_versions",
            kwargs={"main_slug": "radiuma", "sub_slug": "image-processing"},
        )
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, "products/versions_archive.html")

    def test_main_versions_returns_200(self):
        from apps.products.models import SubProductVersion

        SubProductVersion.objects.create(
            main_product=self.main_product,
            version="9.9",
            is_featured_stable=True,
            windows_download_url="https://example.com/win.exe",
            is_active=True,
        )
        SubProductVersion.objects.create(
            main_product=self.main_product,
            version="9.8",
            is_active=True,
        )
        url = reverse(
            "products:main_product_versions",
            kwargs={"main_slug": "radiuma"},
        )
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, "products/versions_archive.html")

    def test_main_detail_releases_in_context(self):
        from apps.products.models import SubProductVersion

        SubProductVersion.objects.create(
            main_product=self.main_product,
            version="1.0",
            windows_download_url="https://example.com/win.exe",
            is_active=True,
        )
        url = reverse("products:main_product_detail", kwargs={"main_slug": "radiuma"})
        response = self.client.get(url)
        self.assertTrue(response.context["show_releases_section"])
