# Copyright 2026 Your Company
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo.tests.common import TransactionCase


class TestProductPriceCategorySupplier(TransactionCase):
    """Test suite for product_price_category_supplier addon."""

    @classmethod
    def setUpClass(cls):
        """Set up test data."""
        super().setUpClass()

        # Create price categories
        cls.category_premium = cls.env["product.price.category"].create(
            {
                "name": "Premium",
            }
        )
        cls.category_standard = cls.env["product.price.category"].create(
            {
                "name": "Standard",
            }
        )

        # Create suppliers
        cls.supplier_a = cls.env["res.partner"].create(
            {
                "name": "Supplier A",
                "supplier_rank": 1,
                "default_price_category_id": cls.category_premium.id,
            }
        )
        cls.supplier_b = cls.env["res.partner"].create(
            {
                "name": "Supplier B",
                "supplier_rank": 1,
                "default_price_category_id": cls.category_standard.id,
            }
        )

        # Create a non-supplier partner
        cls.customer = cls.env["res.partner"].create(
            {
                "name": "Customer A",
                "customer_rank": 1,
                "supplier_rank": 0,
            }
        )

        # Create products with supplier A as default (with seller_ids)
        cls.product_1 = cls.env["product.template"].create(
            {
                "name": "Product 1",
                "seller_ids": [
                    (
                        0,
                        0,
                        {
                            "partner_id": cls.supplier_a.id,
                            "sequence": 10,
                            "min_qty": 0,
                        },
                    )
                ],
            }
        )
        cls.product_2 = cls.env["product.template"].create(
            {
                "name": "Product 2",
                "seller_ids": [
                    (
                        0,
                        0,
                        {
                            "partner_id": cls.supplier_a.id,
                            "sequence": 10,
                            "min_qty": 0,
                        },
                    )
                ],
            }
        )
        cls.product_3 = cls.env["product.template"].create(
            {
                "name": "Product 3",
                "seller_ids": [
                    (
                        0,
                        0,
                        {
                            "partner_id": cls.supplier_a.id,
                            "sequence": 10,
                            "min_qty": 0,
                        },
                    )
                ],
            }
        )

        # Create product with supplier B
        cls.product_4 = cls.env["product.template"].create(
            {
                "name": "Product 4",
                "seller_ids": [
                    (
                        0,
                        0,
                        {
                            "partner_id": cls.supplier_b.id,
                            "sequence": 10,
                            "min_qty": 0,
                        },
                    )
                ],
            }
        )

        # Create product without supplier
        cls.product_5 = cls.env["product.template"].create(
            {
                "name": "Product 5",
            }
        )

    def test_01_supplier_has_default_price_category_field(self):
        """Test that supplier has default_price_category_id field."""
        self.assertTrue(
            hasattr(self.supplier_a, "default_price_category_id"),
            "Supplier should have default_price_category_id field",
        )
        self.assertEqual(
            self.supplier_a.default_price_category_id.id,
            self.category_premium.id,
            "Supplier should have Premium category assigned",
        )

    def test_02_action_update_products_opens_wizard(self):
        """Test that action_update_products_price_category opens wizard."""
        action = self.supplier_a.action_update_products_price_category()

        self.assertEqual(
            action["type"], "ir.actions.act_window", "Action should be a window action"
        )
        self.assertEqual(
            action["res_model"],
            "wizard.update.product.category",
            "Action should open wizard model",
        )
        self.assertEqual(
            action["target"], "new", "Action should open in modal (target=new)"
        )
        self.assertIn("res_id", action, "Action should have res_id")
        self.assertTrue(
            action["res_id"] > 0, "res_id should be a valid wizard record ID"
        )

    def test_03_wizard_counts_products_correctly(self):
        """Test that wizard counts products from supplier correctly."""
        action = self.supplier_a.action_update_products_price_category()

        # Get the wizard record that was created
        wizard = self.env["wizard.update.product.category"].browse(action["res_id"])

        self.assertEqual(
            wizard.product_count, 3, "Wizard should count 3 products from Supplier A"
        )
        self.assertEqual(
            wizard.partner_name, "Supplier A", "Wizard should display supplier name"
        )
        self.assertEqual(
            wizard.price_category_id.id,
            self.category_premium.id,
            "Wizard should have Premium category from supplier",
        )

    def test_04_wizard_updates_all_products_from_supplier(self):
        """Test that wizard updates all products from supplier."""
        # Verify initial state - no categories assigned
        self.assertFalse(
            self.product_1.price_category_id,
            "Product 1 should not have category initially",
        )
        self.assertFalse(
            self.product_2.price_category_id,
            "Product 2 should not have category initially",
        )

        # Create and execute wizard
        wizard = self.env["wizard.update.product.category"].create(
            {
                "partner_id": self.supplier_a.id,
                "price_category_id": self.category_premium.id,
                "product_count": 3,
            }
        )
        result = wizard.action_confirm()

        # Verify products were updated
        self.assertEqual(
            self.product_1.price_category_id.id,
            self.category_premium.id,
            "Product 1 should have Premium category",
        )
        self.assertEqual(
            self.product_2.price_category_id.id,
            self.category_premium.id,
            "Product 2 should have Premium category",
        )
        self.assertEqual(
            self.product_3.price_category_id.id,
            self.category_premium.id,
            "Product 3 should have Premium category",
        )

        # Verify product from other supplier was NOT updated
        self.assertFalse(
            self.product_4.price_category_id,
            "Product 4 (from Supplier B) should not be updated",
        )

        # Verify success notification
        self.assertEqual(
            result["type"], "ir.actions.client", "Result should be a client action"
        )
        self.assertEqual(
            result["tag"],
            "display_notification",
            "Result should display a notification",
        )

    def test_05_wizard_handles_supplier_with_no_products(self):
        """Test wizard behavior when supplier has no products."""
        # Create supplier without products
        supplier_no_products = self.env["res.partner"].create(
            {
                "name": "Supplier No Products",
                "supplier_rank": 1,
                "default_price_category_id": self.category_standard.id,
            }
        )

        wizard = self.env["wizard.update.product.category"].create(
            {
                "partner_id": supplier_no_products.id,
                "price_category_id": self.category_standard.id,
                "product_count": 0,
            }
        )
        result = wizard.action_confirm()

        # Verify warning notification
        self.assertEqual(
            result["type"], "ir.actions.client", "Result should be a client action"
        )
        self.assertEqual(
            result["params"]["type"], "warning", "Should display warning notification"
        )

    def test_06_customer_does_not_show_price_category_field(self):
        """Test that customer (non-supplier) doesn't have visible category field."""
        # This is a view-level test - we verify the field exists but logic is correct
        self.assertFalse(
            self.customer.default_price_category_id,
            "Customer should not have price category set",
        )
        self.assertEqual(
            self.customer.supplier_rank, 0, "Customer should have supplier_rank = 0"
        )

    def test_07_wizard_overwrites_existing_categories(self):
        """Test that wizard overwrites existing product categories."""
        # Assign initial category to products
        self.product_1.price_category_id = self.category_standard.id
        self.product_2.price_category_id = self.category_standard.id

        self.assertEqual(
            self.product_1.price_category_id.id,
            self.category_standard.id,
            "Product 1 should have Standard category initially",
        )

        # Execute wizard to change to Premium
        wizard = self.env["wizard.update.product.category"].create(
            {
                "partner_id": self.supplier_a.id,
                "price_category_id": self.category_premium.id,
                "product_count": 3,
            }
        )
        wizard.action_confirm()

        # Verify categories were overwritten
        self.assertEqual(
            self.product_1.price_category_id.id,
            self.category_premium.id,
            "Product 1 category should be overwritten to Premium",
        )
        self.assertEqual(
            self.product_2.price_category_id.id,
            self.category_premium.id,
            "Product 2 category should be overwritten to Premium",
        )

    def test_08_multiple_suppliers_independent_updates(self):
        """Test that updating one supplier doesn't affect other suppliers' products."""
        # Update Supplier A products
        wizard_a = self.env["wizard.update.product.category"].create(
            {
                "partner_id": self.supplier_a.id,
                "price_category_id": self.category_premium.id,
                "product_count": 3,
            }
        )
        wizard_a.action_confirm()

        # Update Supplier B products
        wizard_b = self.env["wizard.update.product.category"].create(
            {
                "partner_id": self.supplier_b.id,
                "price_category_id": self.category_standard.id,
                "product_count": 1,
            }
        )
        wizard_b.action_confirm()

        # Verify each supplier's products have correct category
        self.assertEqual(
            self.product_1.price_category_id.id,
            self.category_premium.id,
            "Supplier A products should have Premium",
        )
        self.assertEqual(
            self.product_4.price_category_id.id,
            self.category_standard.id,
            "Supplier B products should have Standard",
        )

    def test_09_wizard_readonly_fields(self):
        """Test that wizard display fields are readonly."""
        wizard = self.env["wizard.update.product.category"].create(
            {
                "partner_id": self.supplier_a.id,
                "price_category_id": self.category_premium.id,
                "product_count": 3,
            }
        )

        # Verify partner_name is computed from partner_id
        self.assertEqual(
            wizard.partner_name,
            "Supplier A",
            "partner_name should be related to partner_id.name",
        )

    def test_10_action_counts_products_correctly(self):
        """Test that action_update_products_price_category counts products correctly."""
        action = self.supplier_a.action_update_products_price_category()

        # Get the wizard that was created
        wizard = self.env["wizard.update.product.category"].browse(action["res_id"])

        # Count products manually
        actual_count = self.env["product.template"].search_count(
            [("main_seller_id", "=", self.supplier_a.id)]
        )

        self.assertEqual(
            wizard.product_count,
            actual_count,
            f"Wizard should count {actual_count} products",
        )
        self.assertEqual(wizard.product_count, 3, "Supplier A should have 3 products")
