"""BPC model tests."""

from django.db import IntegrityError
from django.test import TestCase

from shop.models import BpcListing, BpcVariant, Shop
from shop.tests.test_stock import make_owner_character, make_ship_type


class BpcModelTests(TestCase):
    def setUp(self):
        self.user, self.char = make_owner_character()
        self.bp_type = make_ship_type(type_id=12040, name="Rifter Blueprint")
        self.shop = Shop.objects.create(slug="s", name="S", created_by=self.user)

    def test_variant_price_display(self):
        listing = BpcListing.objects.create(shop=self.shop, eve_type=self.bp_type)
        v = BpcVariant.objects.create(
            listing=listing, me=10, te=20, runs=50, stock=3, price=0
        )
        self.assertEqual(v.price_display, "Ask")
        v.price = 8_000_000
        self.assertEqual(v.price_display, "8M ISK")

    def test_aggregates(self):
        listing = BpcListing.objects.create(shop=self.shop, eve_type=self.bp_type)
        BpcVariant.objects.create(listing=listing, me=10, te=20, runs=50, stock=2)
        BpcVariant.objects.create(listing=listing, me=0, te=0, runs=10, stock=3)
        self.assertEqual(listing.variant_count, 2)
        self.assertEqual(listing.total_stock, 5)
        self.assertEqual(listing.total_runs, 50 * 2 + 10 * 3)

    def test_unique_variant(self):
        listing = BpcListing.objects.create(shop=self.shop, eve_type=self.bp_type)
        BpcVariant.objects.create(listing=listing, me=10, te=20, runs=50, stock=1)
        with self.assertRaises(IntegrityError):
            BpcVariant.objects.create(listing=listing, me=10, te=20, runs=50, stock=2)

    def _listing(self):
        return BpcListing.objects.create(shop=self.shop, eve_type=self.bp_type)

    def test_per_run_range_all_ask(self):
        listing = self._listing()
        BpcVariant.objects.create(
            listing=listing, me=0, te=0, runs=10, stock=1, price=0
        )
        self.assertEqual(listing.per_run_range_display, "ASK")

    def test_per_run_range_single_price(self):
        listing = self._listing()
        BpcVariant.objects.create(
            listing=listing, me=0, te=0, runs=10, stock=1, price=200, price_per_run=20
        )
        self.assertEqual(listing.per_run_range_display, "20 ISK / run")

    def test_per_run_range_single_price_with_ask(self):
        listing = self._listing()
        BpcVariant.objects.create(
            listing=listing, me=0, te=0, runs=10, stock=1, price=250, price_per_run=25
        )
        BpcVariant.objects.create(listing=listing, me=1, te=1, runs=5, stock=1, price=0)
        self.assertEqual(listing.per_run_range_display, "25 ISK / run | ASK")

    def test_per_run_range_span_with_ask(self):
        listing = self._listing()
        BpcVariant.objects.create(
            listing=listing, me=0, te=0, runs=10, stock=1, price=250, price_per_run=25
        )
        BpcVariant.objects.create(
            listing=listing, me=1, te=1, runs=5, stock=1, price=700, price_per_run=140
        )
        BpcVariant.objects.create(listing=listing, me=2, te=2, runs=3, stock=1, price=0)
        self.assertEqual(listing.per_run_range_display, "25-140 ISK / run | ASK")

    def test_hidden_excluded_from_aggregates(self):
        listing = self._listing()
        BpcVariant.objects.create(listing=listing, me=0, te=0, runs=10, stock=2)
        BpcVariant.objects.create(
            listing=listing, me=1, te=1, runs=5, stock=9, hidden=True
        )
        self.assertEqual(listing.variant_count, 1)
        self.assertEqual(listing.total_stock, 2)


class CorporationBlueprintModelTests(TestCase):
    def test_stores_fields_and_item_id_unique(self):
        from django.db import IntegrityError, transaction

        from shop.models import CorporationBlueprint
        from shop.tests._corptools import make_corp_owner

        _user, corp = make_corp_owner()
        bp = CorporationBlueprint.objects.create(
            corporation_audit=corp,
            item_id=555,
            type_id=12040,
            me=10,
            te=20,
            runs=50,
            quantity=-2,
        )
        self.assertEqual(bp.corporation_audit_id, corp.pk)
        self.assertEqual((bp.me, bp.te, bp.runs), (10, 20, 50))
        with self.assertRaises(IntegrityError):
            with transaction.atomic():
                CorporationBlueprint.objects.create(
                    corporation_audit=corp,
                    item_id=555,
                    type_id=1,
                    me=0,
                    te=0,
                    runs=1,
                    quantity=1,
                )
