# -*- coding: utf-8 -*-
"""STEP 9 tests — child-support modification workflow.

    odoo -d <db> -u activeblue_familylaw --test-enable \
         --test-tags familylaw_step9 --stop-after-init

Proves:
  * a modification opens a NEW proceeding under the same case;
  * the 15%/$50 substantial-change threshold (max of 15% or $50);
  * a 20-day answer deadline is created on the new proceeding;
  * the DOR flag and retroactivity date are captured;
  * prior-judgment handling produces a summary + FLAGGED interpretation questions,
    never a conclusion (AI mocked).
"""

from datetime import date

from unittest.mock import patch

from odoo.tests.common import TransactionCase, tagged

CLIENT = "odoo.addons.activeblue_familylaw_v2.models.familylaw_ai.FamilyLawAIClient"


def _ai(text="EXTRACTION OUTPUT"):
    return {"text": text, "usage": {"input_tokens": 5, "output_tokens": 5},
            "citations": []}


@tagged("post_install", "-at_install", "familylaw", "familylaw_step9")
class TestStep9Modification(TransactionCase):

    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        cls.partner = cls.env["res.partner"].create({"name": "Mod Client"})
        cls.case = cls.env["familylaw.case"].create({
            "name": "Mod Matter", "client_id": cls.partner.id,
            "case_type": "support_modification",
        })
        cls.Mod = cls.env["familylaw.support.modification"]
        icp = cls.env["ir.config_parameter"].sudo()
        icp.set_param("familylaw.anthropic_api_key", "k")
        icp.set_param("familylaw.model", "claude-sonnet-4-6")

    # --- new proceeding -----------------------------------------------------
    def test_01_opens_new_proceeding(self):
        before = len(self.case.proceeding_ids)
        rec = self.Mod.open_for_case(self.case, 1000.0, 1200.0)
        self.assertEqual(len(self.case.proceeding_ids), before + 1)
        self.assertEqual(rec.proceeding_id.proceeding_type, "modification")
        self.assertEqual(rec.case_id, self.case)

    def test_02_separate_from_original_proceeding(self):
        original = self.case.proceeding_ids[0]
        rec = self.Mod.open_for_case(self.case, 1000.0, 1200.0)
        self.assertNotEqual(rec.proceeding_id, original)

    # --- threshold ----------------------------------------------------------
    def test_03_meets_threshold_15pct(self):
        rec = self.Mod.open_for_case(self.case, 1000.0, 1200.0)  # +200 vs thr 150
        self.assertTrue(rec.meets_threshold)

    def test_04_below_threshold(self):
        rec = self.Mod.open_for_case(self.case, 1000.0, 1100.0)  # +100 vs thr 150
        self.assertFalse(rec.meets_threshold)

    def test_05_fifty_dollar_prong(self):
        # low base: 15% of 200 = 30, but $50 floor applies; +60 meets
        rec = self.Mod.open_for_case(self.case, 200.0, 260.0)
        self.assertEqual(rec.threshold_amount, 50.0)
        self.assertTrue(rec.meets_threshold)

    def test_06_fifty_dollar_prong_not_met(self):
        rec = self.Mod.open_for_case(self.case, 200.0, 240.0)  # +40 < $50
        self.assertFalse(rec.meets_threshold)

    def test_07_change_pct(self):
        rec = self.Mod.open_for_case(self.case, 1000.0, 1200.0)
        self.assertAlmostEqual(rec.change_pct, 20.0, places=2)

    def test_08_no_change_not_met(self):
        rec = self.Mod.open_for_case(self.case, 1000.0, 1000.0)
        self.assertFalse(rec.meets_threshold)

    # --- 20-day answer deadline ---------------------------------------------
    def test_09_answer_deadline_created(self):
        rec = self.Mod.open_for_case(self.case, 1000.0, 1200.0,
                                     filing_date=date(2025, 1, 1))
        answer = rec.proceeding_id.deadline_ids.filtered(
            lambda d: d.deadline_type == "answer")
        self.assertTrue(answer)
        self.assertEqual(answer.days, 20)
        # 2025-01-01 + 20 = 2025-01-21 (Tue)
        self.assertEqual(answer.due_date, date(2025, 1, 21))

    # --- DOR + retroactivity ------------------------------------------------
    def test_10_dor_flag(self):
        rec = self.Mod.open_for_case(self.case, 1000.0, 1200.0, is_dor=True)
        self.assertTrue(rec.is_dor_case)

    def test_11_retroactivity_date_is_filing_date(self):
        rec = self.Mod.open_for_case(self.case, 1000.0, 1200.0,
                                     filing_date=date(2025, 3, 5))
        self.assertEqual(rec.retroactivity_date, date(2025, 3, 5))

    # --- prior-judgment extraction (flagged, not concluded) -----------------
    def test_12_extraction_summarizes_and_flags(self):
        rec = self.Mod.open_for_case(self.case, 1000.0, 1200.0,
                                     prior_order_text="Order: $1000/mo to Mother.")
        with patch(CLIENT + "._call_provider", return_value=_ai("SUMMARY TEXT")):
            rec.action_extract_prior_judgment()
        self.assertIn("SUMMARY TEXT", rec.extracted_summary)
        self.assertTrue(rec.interpretation_flags)

    def test_13_interpretation_is_flagged_not_concluded(self):
        rec = self.Mod.open_for_case(self.case, 1000.0, 1200.0,
                                     prior_order_text="Order text.")
        with patch(CLIENT + "._call_provider", return_value=_ai()):
            rec.action_extract_prior_judgment()
        # the interpretation field carries the not-a-conclusion disclaimer
        self.assertIn("NOT conclusions", rec.interpretation_flags)
        # the model structurally has no field that states a legal conclusion/ruling
        self.assertNotIn("legal_conclusion", rec._fields)
        self.assertNotIn("ruling", rec._fields)

    def test_14_extraction_logs_ai_task(self):
        rec = self.Mod.open_for_case(self.case, 1000.0, 1200.0,
                                     prior_order_text="Order text.")
        with patch(CLIENT + "._call_provider", return_value=_ai()):
            rec.action_extract_prior_judgment()
        self.assertTrue(rec.extraction_task_id)
        self.assertEqual(rec.extraction_task_id.state, "done")
