# -*- coding: utf-8 -*-
"""STEP 3 tests — documents + THE REVIEW GATE (Gate 1).

Run just this step:
    odoo -d <db> -u activeblue_familylaw --test-enable \
         --test-tags familylaw_step3 --stop-after-init

Proves:
  * an AI-assembled document is born in 'ai_draft';
  * only an attorney can approve / reject / file / send;
  * a document cannot be filed or sent unless it is approved (Gate 1);
  * the review workflow transitions correctly and is audited.
"""

from odoo.tests.common import TransactionCase, new_test_user, tagged
from odoo.exceptions import UserError


@tagged("post_install", "-at_install", "familylaw", "familylaw_step3")
class TestStep3ReviewGate(TransactionCase):

    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        cls.attorney = new_test_user(
            cls.env, login="fl_atty3", name="Attorney 3",
            email="atty3@example.com",
            groups="base.group_user,activeblue_familylaw_v2.group_familylaw_attorney",
        )
        cls.paralegal = new_test_user(
            cls.env, login="fl_para3", name="Paralegal 3",
            email="para3@example.com",
            groups="base.group_user,activeblue_familylaw_v2.group_familylaw_user",
        )
        cls.partner = cls.env["res.partner"].create({"name": "Doc Client"})
        cls.case = cls.env["familylaw.case"].create({
            "name": "Doc Matter",
            "client_id": cls.partner.id,
            "case_type": "support_modification",
        })
        cls.proceeding = cls.case.proceeding_ids[0]
        cls.Doc = cls.env["familylaw.document"]

    def _make_doc(self, **kw):
        vals = {
            "name": "Test Motion",
            "proceeding_id": self.proceeding.id,
            "document_type": "pleading",
            "source": "ai",
        }
        vals.update(kw)
        return self.Doc.create(vals)

    # --- born as draft ------------------------------------------------------
    def test_01_ai_document_born_draft(self):
        doc = self._make_doc(source="ai")
        self.assertEqual(doc.state, "ai_draft")

    def test_02_case_id_derived_from_proceeding(self):
        doc = self._make_doc()
        self.assertEqual(doc.case_id, self.case)

    # --- Gate 1: cannot file/send unapproved --------------------------------
    def test_03_cannot_file_draft(self):
        doc = self._make_doc()
        with self.assertRaises(UserError):
            doc.with_user(self.attorney).action_mark_filed()
        self.assertNotEqual(doc.state, "filed")

    def test_04_cannot_send_draft(self):
        doc = self._make_doc()
        with self.assertRaises(UserError):
            doc.with_user(self.attorney).action_mark_sent()
        self.assertNotEqual(doc.state, "sent")

    def test_05_cannot_file_in_review(self):
        doc = self._make_doc()
        doc.action_submit_for_review()
        with self.assertRaises(UserError):
            doc.with_user(self.attorney).action_mark_filed()

    # --- attorney-only approval ---------------------------------------------
    def test_06_approve_requires_attorney(self):
        doc = self._make_doc()
        doc.action_submit_for_review()
        with self.assertRaises(UserError):
            doc.with_user(self.paralegal).action_approve()
        self.assertEqual(doc.state, "attorney_review")

    def test_07_attorney_approves(self):
        doc = self._make_doc()
        doc.action_submit_for_review()
        doc.with_user(self.attorney).action_approve()
        self.assertEqual(doc.state, "approved")
        self.assertEqual(doc.approved_by_id, self.attorney)
        self.assertTrue(doc.approved_date)

    def test_08_cannot_approve_draft_directly(self):
        doc = self._make_doc()
        with self.assertRaises(UserError):
            doc.with_user(self.attorney).action_approve()

    # --- full happy path ----------------------------------------------------
    def test_09_full_path_to_filed(self):
        doc = self._make_doc()
        doc.action_submit_for_review()
        doc.with_user(self.attorney).action_approve()
        doc.with_user(self.attorney).action_mark_filed()
        self.assertEqual(doc.state, "filed")

    def test_10_approved_then_send(self):
        doc = self._make_doc()
        doc.action_submit_for_review()
        doc.with_user(self.attorney).action_approve()
        doc.with_user(self.attorney).action_mark_sent()
        self.assertEqual(doc.state, "sent")

    # --- reject / reset -----------------------------------------------------
    def test_11_reject_requires_attorney(self):
        doc = self._make_doc()
        doc.action_submit_for_review()
        with self.assertRaises(UserError):
            doc.with_user(self.paralegal).action_reject()

    def test_12_reject_clears_approval(self):
        doc = self._make_doc()
        doc.action_submit_for_review()
        doc.with_user(self.attorney).action_approve()
        doc.with_user(self.attorney).action_reject()
        self.assertEqual(doc.state, "rejected")
        self.assertFalse(doc.approved_by_id)
        self.assertFalse(doc.approved_date)

    def test_13_rejected_can_resubmit(self):
        doc = self._make_doc()
        doc.action_submit_for_review()
        doc.with_user(self.attorney).action_reject()
        doc.action_submit_for_review()
        self.assertEqual(doc.state, "attorney_review")

    # --- file/send are attorney-only even if approved -----------------------
    def test_14_file_requires_attorney(self):
        doc = self._make_doc()
        doc.action_submit_for_review()
        doc.with_user(self.attorney).action_approve()
        with self.assertRaises(UserError):
            doc.with_user(self.paralegal).action_mark_filed()

    # --- audit --------------------------------------------------------------
    def test_15_workflow_is_audited(self):
        doc = self._make_doc()
        before = len(doc.message_ids)
        doc.action_submit_for_review()
        doc.with_user(self.attorney).action_approve()
        self.assertGreater(len(doc.message_ids), before)

    # --- proceeding linkage -------------------------------------------------
    def test_16_document_listed_on_proceeding(self):
        doc = self._make_doc()
        self.assertIn(doc, self.proceeding.document_ids)
