# Copyright (C) 2025: Criptomart (https://criptomart.net)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from odoo.tests import tagged
from odoo.tests.common import TransactionCase


@tagged("post_install", "-at_install")
class TestAccountMove(TransactionCase):
    @classmethod
    def setUpClass(cls):
        super().setUpClass()

        # Create a partner
        cls.partner = cls.env["res.partner"].create(
            {
                "name": "Test Customer",
                "email": "customer@test.com",
            }
        )

        # Create a product
        cls.product = cls.env["product.product"].create(
            {
                "name": "Test Product Invoice",
                "type": "consu",
                "list_price": 200.0,
                "standard_price": 100.0,
            }
        )

        # Create tax
        cls.tax = cls.env["account.tax"].create(
            {
                "name": "Test Tax 10%",
                "amount": 10.0,
                "amount_type": "percent",
                "type_tax_use": "sale",
            }
        )

        # Create an invoice
        cls.invoice = cls.env["account.move"].create(
            {
                "move_type": "out_invoice",
                "partner_id": cls.partner.id,
                "invoice_date": "2026-01-01",
            }
        )

        # Create invoice line
        cls.invoice_line = cls.env["account.move.line"].create(
            {
                "move_id": cls.invoice.id,
                "product_id": cls.product.id,
                "quantity": 5,
                "price_unit": 200.0,
                "discount1": 10.0,
                "discount2": 5.0,
                "discount3": 2.0,
                "tax_ids": [(6, 0, [cls.tax.id])],
            }
        )

    def test_invoice_line_discount_readonly(self):
        """Test that discount field is readonly in invoice lines"""
        field = self.invoice_line._fields["discount"]
        self.assertTrue(
            field.readonly, "Discount field should be readonly in invoice lines"
        )

    def test_invoice_line_write_with_explicit_discounts(self):
        """Test writing invoice line with explicit discounts"""
        self.invoice_line.write(
            {
                "discount": 30.0,  # Should be ignored
                "discount1": 15.0,
                "discount2": 10.0,
                "discount3": 5.0,
            }
        )

        self.assertEqual(self.invoice_line.discount1, 15.0)
        self.assertEqual(self.invoice_line.discount2, 10.0)
        self.assertEqual(self.invoice_line.discount3, 5.0)

    def test_invoice_line_legacy_discount(self):
        """Test legacy discount behavior in invoice lines"""
        self.invoice_line.write(
            {
                "discount": 20.0,
            }
        )

        # Should map to discount1 and reset others
        self.assertEqual(self.invoice_line.discount1, 20.0)
        self.assertEqual(self.invoice_line.discount2, 0.0)
        self.assertEqual(self.invoice_line.discount3, 0.0)

    def test_invoice_line_price_calculation(self):
        """Test that price subtotal is calculated correctly with triple discount"""
        self.invoice_line.write(
            {
                "discount1": 10.0,
                "discount2": 5.0,
                "discount3": 0.0,
            }
        )

        # Base: 5 * 200 = 1000
        # After 10% discount: 900
        # After 5% discount: 855
        expected_subtotal = 5 * 200 * 0.9 * 0.95
        self.assertAlmostEqual(
            self.invoice_line.price_subtotal, expected_subtotal, places=2
        )

    def test_multiple_invoice_lines(self):
        """Test multiple invoice lines with different discounts"""
        line2 = self.env["account.move.line"].create(
            {
                "move_id": self.invoice.id,
                "product_id": self.product.id,
                "quantity": 3,
                "price_unit": 150.0,
                "discount1": 20.0,
                "discount2": 10.0,
                "discount3": 5.0,
                "tax_ids": [(6, 0, [self.tax.id])],
            }
        )

        # Verify both lines have correct discounts
        self.assertEqual(self.invoice_line.discount1, 10.0)
        self.assertEqual(line2.discount1, 20.0)
        self.assertEqual(line2.discount2, 10.0)
        self.assertEqual(line2.discount3, 5.0)

    def test_invoice_line_update_quantity(self):
        """Test updating quantity doesn't affect discounts"""
        initial_discount1 = self.invoice_line.discount1
        initial_discount2 = self.invoice_line.discount2

        self.invoice_line.write(
            {
                "quantity": 10,
            }
        )

        # Discounts should remain unchanged
        self.assertEqual(self.invoice_line.discount1, initial_discount1)
        self.assertEqual(self.invoice_line.discount2, initial_discount2)
        # Quantity should be updated
        self.assertEqual(self.invoice_line.quantity, 10)

    def test_invoice_line_update_price(self):
        """Test updating price doesn't affect discounts"""
        initial_discount1 = self.invoice_line.discount1

        self.invoice_line.write(
            {
                "price_unit": 250.0,
            }
        )

        # Discount should remain unchanged
        self.assertEqual(self.invoice_line.discount1, initial_discount1)
        # Price should be updated
        self.assertEqual(self.invoice_line.price_unit, 250.0)

    def test_invoice_with_zero_discounts(self):
        """Test invoice line with all zero discounts"""
        self.invoice_line.write(
            {
                "discount1": 0.0,
                "discount2": 0.0,
                "discount3": 0.0,
            }
        )

        # All discounts should be zero
        self.assertEqual(self.invoice_line.discount, 0.0)
        self.assertEqual(self.invoice_line.discount1, 0.0)
        self.assertEqual(self.invoice_line.discount2, 0.0)
        self.assertEqual(self.invoice_line.discount3, 0.0)

        # Subtotal should be quantity * price
        expected = 5 * 200
        self.assertEqual(self.invoice_line.price_subtotal, expected)

    def test_invoice_line_combined_operations(self):
        """Test combined operations on invoice line"""
        # Update multiple fields at once
        self.invoice_line.write(
            {
                "quantity": 8,
                "price_unit": 180.0,
                "discount1": 12.0,
                "discount2": 6.0,
                "discount3": 0.0,  # Reset discount3 explicitly
            }
        )

        # All fields should be updated correctly
        self.assertEqual(self.invoice_line.quantity, 8)
        self.assertEqual(self.invoice_line.price_unit, 180.0)
        self.assertEqual(self.invoice_line.discount1, 12.0)
        self.assertEqual(self.invoice_line.discount2, 6.0)
        self.assertEqual(self.invoice_line.discount3, 0.0)

        # Calculate expected subtotal: 8 * 180 * (1-0.12) * (1-0.06)
        expected = 8 * 180 * 0.88 * 0.94
        self.assertAlmostEqual(self.invoice_line.price_subtotal, expected, places=2)
