"""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)
