"""Storefront hull-section tests."""

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

from shop.models import HULL, HullListing, Shop
from shop.tests.test_stock import make_owner_character, make_ship_type
from shop.tests.test_views_backoffice import no_manifest_static


@no_manifest_static
class StorefrontHullsTests(TestCase):
    def setUp(self):
        self.user, self.char = make_owner_character()
        self.ship = make_ship_type()
        self.shop = Shop.objects.create(
            slug="pub", name="Pub", created_by=self.user, is_published=True, enabled_sections=[HULL]
        )
        HullListing.objects.create(shop=self.shop, eve_type=self.ship, price=0, stock=0)

    def test_hull_card_and_group_render(self):
        resp = self.client.get("/shop/pub/", SERVER_NAME="localhost")
        self.assertEqual(resp.status_code, 200)
        self.assertContains(resp, "Erebus")
        self.assertContains(resp, "Titan")            # group header
        self.assertContains(resp, "Build to order")   # stock 0
        self.assertContains(resp, "Ask")              # price 0

    def test_table_view_renders_table(self):
        resp = self.client.get("/shop/pub/?view=table", SERVER_NAME="localhost")
        self.assertEqual(resp.status_code, 200)
        self.assertContains(resp, "<table")
        self.assertContains(resp, "Erebus")

    def test_no_hulls_section_when_disabled(self):
        self.shop.enabled_sections = []
        self.shop.save()
        resp = self.client.get("/shop/pub/", SERVER_NAME="localhost")
        self.assertNotContains(resp, "Erebus")

    def test_description_rendered_above_listings(self):
        self.shop.description = "**Welcome** to my shop"
        self.shop.save(update_fields=["description"])
        resp = self.client.get("/shop/pub/", SERVER_NAME="localhost")
        self.assertContains(resp, "shop-description")
        self.assertContains(resp, "<strong>Welcome</strong>")

    def test_no_description_block_when_blank(self):
        resp = self.client.get("/shop/pub/", SERVER_NAME="localhost")
        self.assertNotContains(resp, "shop-description")

    def test_grid_card_links_to_detail(self):
        listing = HullListing.objects.get(shop=self.shop, eve_type=self.ship)
        url = reverse("storefront:item", args=[self.shop.slug, listing.pk])
        resp = self.client.get("/shop/pub/", SERVER_NAME="localhost")
        self.assertContains(resp, f'href="{url}"')

    def test_featured_ordered_by_featured_at(self):
        from datetime import timedelta

        from django.utils import timezone
        # Two ships in the SAME group so only featured_at (not group/name) drives order.
        apex = make_ship_type(type_id=588, name="Apex", group_id=26, group_name="Cruiser")
        zephyr = make_ship_type(type_id=589, name="Zephyr", group_id=26, group_name="Cruiser")
        a = HullListing.objects.create(shop=self.shop, eve_type=apex, price=0, stock=1)
        z = HullListing.objects.create(shop=self.shop, eve_type=zephyr, price=0, stock=1)
        now = timezone.now()
        z.featured = True; z.featured_at = now - timedelta(hours=1); z.save()
        a.featured = True; a.featured_at = now; a.save()
        resp = self.client.get("/shop/pub/", SERVER_NAME="localhost")
        body = resp.content.decode()
        # Zephyr featured first -> before Apex, despite "Apex" < "Zephyr" alphabetically.
        self.assertLess(body.index("Zephyr"), body.index("Apex"))

    def test_featured_section_absent_when_none_starred(self):
        resp = self.client.get("/shop/pub/", SERVER_NAME="localhost")
        self.assertNotContains(resp, "Featured")

    def test_featured_section_present_and_dedup(self):
        # Second ship in a different group; feature the first (Erebus/Titan).
        rifter = make_ship_type(type_id=587, name="Rifter", group_id=25, group_name="Frigate")
        HullListing.objects.create(shop=self.shop, eve_type=rifter, price=0, stock=0)
        listing = HullListing.objects.get(shop=self.shop, eve_type=self.ship)
        listing.featured = True
        listing.save(update_fields=["featured"])
        resp = self.client.get("/shop/pub/", SERVER_NAME="localhost")
        self.assertContains(resp, "Featured")   # featured heading present
        self.assertContains(resp, "Erebus")     # featured card
        self.assertContains(resp, "Rifter")     # normal group card
        self.assertContains(resp, "Frigate")    # Rifter's group header
        # Titan group header should NOT render: its only member (Erebus) is featured-out.
        self.assertNotContains(resp, "Titan")

    def test_table_view_marks_featured(self):
        listing = HullListing.objects.get(shop=self.shop, eve_type=self.ship)
        listing.featured = True
        listing.save(update_fields=["featured"])
        resp = self.client.get("/shop/pub/?view=table", SERVER_NAME="localhost")
        self.assertContains(resp, "ti-star-filled")


@no_manifest_static
class ItemDetailTests(TestCase):
    def setUp(self):
        self.user, self.char = make_owner_character()
        self.ship = make_ship_type()
        self.shop = Shop.objects.create(
            slug="pub", name="Pub", created_by=self.user, is_published=True, enabled_sections=[HULL]
        )
        self.listing = HullListing.objects.create(
            shop=self.shop, eve_type=self.ship, price=5000000, stock=3, description="**great ship**"
        )

    def _url(self):
        return reverse("storefront:item", args=[self.shop.slug, self.listing.pk])

    def test_renders_detail(self):
        resp = self.client.get(self._url(), SERVER_NAME="localhost")
        self.assertEqual(resp.status_code, 200)
        self.assertContains(resp, "Erebus")
        # Qty + Add-to-order are hidden until the order flow ships.
        self.assertNotContains(resp, "Add to order")
        self.assertNotContains(resp, 'name="quantity"')
        self.assertContains(resp, "<strong>great ship</strong>")
        self.assertContains(resp, "in stock")

    def test_build_to_order_when_no_stock(self):
        self.listing.stock = 0
        self.listing.save(update_fields=["stock"])
        resp = self.client.get(self._url(), SERVER_NAME="localhost")
        self.assertContains(resp, "Build to order")

    def test_unpublished_404_for_anonymous(self):
        self.shop.is_published = False
        self.shop.save(update_fields=["is_published"])
        resp = self.client.get(self._url(), SERVER_NAME="localhost")
        self.assertEqual(resp.status_code, 404)

    def test_wrong_shop_404(self):
        other = Shop.objects.create(slug="other", name="Other", created_by=self.user, is_published=True)
        url = reverse("storefront:item", args=[other.slug, self.listing.pk])
        resp = self.client.get(url, SERVER_NAME="localhost")
        self.assertEqual(resp.status_code, 404)
