"""Back-office order queue tests."""

from allianceauth.tests.auth_utils import AuthUtils
from django.contrib.auth.models import User
from django.test import TestCase
from django.urls import reverse

from shop.models import Buyer, Order, OrderLine, Shop
from shop.tests.test_stock import make_owner_character, make_ship_type
from shop.tests.test_views_backoffice import no_manifest_static


def member_with_access(username="mgr", char_id=1001):
    user, char = make_owner_character(username, char_id)
    AuthUtils.add_permission_to_user_by_name("shop.basic_access", user)
    return User.objects.get(pk=user.pk), char


@no_manifest_static
class OrderQueueTests(TestCase):
    def setUp(self):
        self.user, _ = member_with_access()
        self.shop = Shop.objects.create(
            slug="s", name="S", created_by=self.user, enabled_sections=["hulls"]
        )
        self.ship = make_ship_type()
        self.buyer = Buyer.objects.create(
            character_id=42, character_name="Sir Uhad", discord_handle="uhad"
        )
        self.order = Order.objects.create(
            shop=self.shop, buyer=self.buyer, additional_info="ME10 pls"
        )
        OrderLine.objects.create(
            order=self.order,
            section="hulls",
            eve_type=self.ship,
            quantity=2,
            unit_price=1000,
        )
        self.client.force_login(self.user)

    def _url(self, name, *args):
        return reverse(name, args=[self.shop.pk, *args])

    def test_list_shows_order(self):
        resp = self.client.get(self._url("backoffice:orders"), SERVER_NAME="localhost")
        self.assertEqual(resp.status_code, 200)
        self.assertContains(resp, self.order.reference)
        self.assertContains(resp, "Sir Uhad")

    def test_list_excludes_other_shop(self):
        other = Shop.objects.create(
            slug="o", name="O", created_by=self.user, enabled_sections=["hulls"]
        )
        foreign = Order.objects.create(shop=other, buyer=self.buyer)
        resp = self.client.get(self._url("backoffice:orders"), SERVER_NAME="localhost")
        self.assertNotContains(resp, foreign.reference)

    def test_list_requires_can_manage(self):
        intruder, _ = member_with_access("intruder", 2002)
        self.client.force_login(intruder)
        resp = self.client.get(self._url("backoffice:orders"), SERVER_NAME="localhost")
        self.assertEqual(resp.status_code, 403)

    def test_detail_shows_buyer_and_lines(self):
        resp = self.client.get(
            self._url("backoffice:order_detail", self.order.reference),
            SERVER_NAME="localhost",
        )
        self.assertEqual(resp.status_code, 200)
        self.assertContains(resp, "Sir Uhad")
        self.assertContains(resp, "uhad")  # discord handle
        self.assertContains(resp, "ME10 pls")  # additional info
        self.assertContains(resp, self.ship.name)  # line item

    def test_detail_shows_line_label(self):
        OrderLine.objects.create(
            order=self.order,
            section="bpc",
            eve_type=self.ship,
            quantity=1,
            unit_price=500,
            label="ME 10 · TE 20 · 50 runs",
        )
        resp = self.client.get(
            self._url("backoffice:order_detail", self.order.reference),
            SERVER_NAME="localhost",
        )
        self.assertContains(resp, "ME 10")

    def test_set_status(self):
        resp = self.client.post(
            self._url("backoffice:set_order_status", self.order.reference),
            {"status": "accepted"},
            SERVER_NAME="localhost",
        )
        self.assertEqual(resp.status_code, 302)
        self.order.refresh_from_db()
        self.assertEqual(self.order.status, "accepted")

    def test_set_status_ignores_invalid(self):
        self.client.post(
            self._url("backoffice:set_order_status", self.order.reference),
            {"status": "bogus"},
            SERVER_NAME="localhost",
        )
        self.order.refresh_from_db()
        self.assertEqual(self.order.status, "pending")

    def test_set_status_requires_can_manage(self):
        intruder, _ = member_with_access("intruder", 2002)
        self.client.force_login(intruder)
        resp = self.client.post(
            self._url("backoffice:set_order_status", self.order.reference),
            {"status": "accepted"},
            SERVER_NAME="localhost",
        )
        self.assertEqual(resp.status_code, 403)

    def test_index_shows_orders_button_and_open_count(self):
        resp = self.client.get(reverse("backoffice:index"), SERVER_NAME="localhost")
        self.assertEqual(resp.status_code, 200)
        self.assertContains(resp, self._url("backoffice:orders"))
        shops = list(resp.context["personal_shops"])
        self.assertEqual(shops[0].open_orders, 1)

    def test_index_open_count_excludes_completed(self):
        self.order.status = "completed"
        self.order.save(update_fields=["status"])
        resp = self.client.get(reverse("backoffice:index"), SERVER_NAME="localhost")
        self.assertEqual(list(resp.context["personal_shops"])[0].open_orders, 0)
