"""
Unit tests for server/tax_advisory_engines.py.

Run with: cd server && ../venv/bin/python3 -m unittest tests.test_tax_advisory_engines -v
"""
import os
import sys
import unittest

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import tax_advisory_engines as te  # noqa: E402


class SalesVatReconciliationTests(unittest.TestCase):
    def test_undeclared_detected(self):
        out = te.sales_vat_reconciliation([
            {"taxable_sales": 100000, "output_vat": 13000, "declared_in_return": True},
            {"taxable_sales": 50000, "output_vat": 6500, "declared_in_return": False},
        ])
        self.assertEqual(out["undeclared_count"], 1)
        self.assertEqual(out["undeclared_output_vat"], 6500.0)

    def test_variance_vs_return(self):
        out = te.sales_vat_reconciliation(
            [{"taxable_sales": 100000, "output_vat": 13000, "declared_in_return": True}], return_output_vat=10000)
        self.assertEqual(out["variance_vs_return"], 3000.0)

    def test_empty_no_crash(self):
        out = te.sales_vat_reconciliation([])
        self.assertEqual(out["total_output_vat"], 0.0)


class PurchaseVatReconciliationTests(unittest.TestCase):
    def test_ineligible_excluded_from_eligible_total(self):
        out = te.purchase_vat_reconciliation([
            {"taxable_purchase": 80000, "input_vat": 10400, "eligible": True},
            {"taxable_purchase": 20000, "input_vat": 2600, "eligible": False},
        ])
        self.assertEqual(out["total_input_vat"], 13000.0)
        self.assertEqual(out["total_eligible_input_vat"], 10400.0)
        self.assertEqual(out["ineligible_count"], 1)

    def test_unmatched_detected(self):
        out = te.purchase_vat_reconciliation([{"taxable_purchase": 100, "input_vat": 13, "matched_with_supplier": False}])
        self.assertEqual(out["unmatched_count"], 1)

    def test_default_eligible_true(self):
        out = te.purchase_vat_reconciliation([{"taxable_purchase": 100, "input_vat": 13}])
        self.assertTrue(out["rows"][0]["eligible"])


class TdsReconciliationTests(unittest.TestCase):
    def test_short_deposit_detected(self):
        out = te.tds_reconciliation([{"tds_deducted": 3000, "tds_deposited": 2000, "return_filed": False}])
        self.assertFalse(out["rows"][0]["fully_deposited"])
        self.assertEqual(out["short_deposited_count"], 1)
        self.assertEqual(out["not_filed_count"], 1)

    def test_fully_deposited_and_filed(self):
        out = te.tds_reconciliation([{"tds_deducted": 50000, "tds_deposited": 50000, "return_filed": True}])
        self.assertTrue(out["rows"][0]["fully_deposited"])
        self.assertEqual(out["short_deposited_count"], 0)
        self.assertEqual(out["not_filed_count"], 0)

    def test_totals(self):
        out = te.tds_reconciliation([
            {"tds_deducted": 50000, "tds_deposited": 50000}, {"tds_deducted": 3000, "tds_deposited": 2000}])
        self.assertEqual(out["total_deducted"], 53000.0)
        self.assertEqual(out["total_variance"], -1000.0)


class DeferredTaxProvisionTests(unittest.TestCase):
    def test_net_liability_when_book_exceeds_tax(self):
        out = te.deferred_tax_provision([{"book_value": 5000000, "tax_value": 4000000}], 25)
        self.assertEqual(out["net_deferred_tax"], 250000.0)
        self.assertEqual(out["classification"], "Net deferred tax liability")

    def test_net_asset_when_tax_exceeds_book(self):
        out = te.deferred_tax_provision([{"book_value": 0, "tax_value": 200000}], 25)
        self.assertEqual(out["classification"], "Net deferred tax asset")

    def test_nil_when_equal(self):
        out = te.deferred_tax_provision([{"book_value": 100, "tax_value": 100}], 25)
        self.assertEqual(out["classification"], "Nil")
        self.assertEqual(out["net_deferred_tax"], 0.0)


class MinimumTaxCheckTests(unittest.TestCase):
    def test_shortfall_when_below_floor(self):
        out = te.minimum_tax_check(computed_tax_liability=300000, turnover=100000000, minimum_tax_pct=0.5)
        self.assertEqual(out["minimum_tax_amount"], 500000.0)
        self.assertEqual(out["shortfall"], 200000.0)
        self.assertTrue(out["minimum_tax_binding"])

    def test_no_shortfall_when_above_floor(self):
        out = te.minimum_tax_check(computed_tax_liability=600000, turnover=100000000, minimum_tax_pct=0.5)
        self.assertEqual(out["shortfall"], 0.0)
        self.assertFalse(out["minimum_tax_binding"])

    def test_no_pct_entered_returns_none_not_zero(self):
        out = te.minimum_tax_check(computed_tax_liability=600000, turnover=100000000, minimum_tax_pct=None)
        self.assertIsNone(out["minimum_tax_amount"])
        self.assertIsNone(out["minimum_tax_binding"])
        self.assertIn("note", out)


class PeRiskAssessmentTests(unittest.TestCase):
    def test_overall_risk_is_highest_present(self):
        out = te.pe_risk_assessment([
            {"factor": "A", "present": True, "risk_level": "Low"},
            {"factor": "B", "present": True, "risk_level": "High"},
            {"factor": "C", "present": False, "risk_level": "High"},
        ])
        self.assertEqual(out["overall_risk"], "High")
        self.assertEqual(out["present_count"], 2)

    def test_none_present_gives_none_risk(self):
        out = te.pe_risk_assessment([{"factor": "A", "present": False, "risk_level": "High"}])
        self.assertEqual(out["overall_risk"], "None")

    def test_empty_no_crash(self):
        out = te.pe_risk_assessment([])
        self.assertEqual(out["overall_risk"], "None")
        self.assertEqual(out["present_count"], 0)


if __name__ == "__main__":
    unittest.main()
