import unittest
from mindscreen.conversation_manager import ConversationManager
from mindscreen.models import SessionStage


class TestConversationManagerFlow(unittest.TestCase):
    def _consent_and_rapport(self, cm):
        cm.start()
        cm.handle_user_turn("yes")  # consent
        cm.handle_user_turn("It's been an okay week, a bit busy.")  # rapport

    def test_full_flow_completes_and_scores(self):
        cm = ConversationManager(participant_id="P001")
        self._consent_and_rapport(cm)
        self.assertEqual(cm.state.stage, SessionStage.PHQ9)

        # Answer all 9 PHQ-9 items with "not at all"
        result = None
        for _ in range(9):
            out = cm.handle_user_turn("not at all")
        self.assertEqual(cm.state.stage, SessionStage.GAD7)

        for _ in range(7):
            out = cm.handle_user_turn("not at all")
        self.assertEqual(cm.state.stage, SessionStage.PSS10)

        for _ in range(10):
            out = cm.handle_user_turn("never")
        self.assertEqual(cm.state.stage, SessionStage.OPEN_REFLECTION)

        out = cm.handle_user_turn("Not really, that covers it.")
        out = cm.handle_user_turn("I feel a bit lighter honestly.")

        self.assertEqual(out["stage"], SessionStage.COMPLETE)
        self.assertIsNotNone(out["result"])
        self.assertEqual(len(cm.state.phq9_responses), 9)
        self.assertEqual(len(cm.state.gad7_responses), 7)
        self.assertEqual(len(cm.state.pss10_responses), 10)

    def test_declining_consent_ends_session(self):
        cm = ConversationManager(participant_id="P002")
        cm.start()
        out = cm.handle_user_turn("no thanks")
        self.assertEqual(out["stage"], SessionStage.COMPLETE)

    def test_crisis_language_pauses_session_immediately(self):
        cm = ConversationManager(participant_id="P003")
        self._consent_and_rapport(cm)
        out = cm.handle_user_turn("not at all")  # first PHQ-9 item answered normally
        out = cm.handle_user_turn("Honestly I just want to end my life.")
        self.assertTrue(out["safety_triggered"])
        self.assertEqual(out["stage"], SessionStage.SAFETY_PAUSED)
        self.assertIn("988", out["bot_message"])

    def test_ambiguous_answer_asks_for_clarification(self):
        cm = ConversationManager(participant_id="P004")
        self._consent_and_rapport(cm)
        out = cm.handle_user_turn("hmm hard to say, kind of a mixed bag")
        # Should still be on PHQ9 (first item) since response was ambiguous
        self.assertEqual(cm.state.stage, SessionStage.PHQ9)
        self.assertEqual(len(cm.state.phq9_responses), 0)
        self.assertIn("make sure I capture", out["bot_message"])

    def test_phq9_item9_endorsement_flags_safety_even_without_keyword(self):
        cm = ConversationManager(participant_id="P005")
        self._consent_and_rapport(cm)
        # Answer first 8 PHQ-9 items benignly
        for _ in range(8):
            cm.handle_user_turn("not at all")
        # Item 9 (self-harm ideation) — answer in a way that maps to a
        # nonzero scale value but doesn't contain an explicit crisis phrase.
        out = cm.handle_user_turn("several days")
        self.assertEqual(len(cm.state.phq9_responses), 9)
        self.assertEqual(cm.state.phq9_responses[-1], 1)
        # Continue through the rest of the flow to trigger finalize()
        for _ in range(7):
            cm.handle_user_turn("not at all")
        for _ in range(10):
            cm.handle_user_turn("never")
        cm.handle_user_turn("no")
        final_out = cm.handle_user_turn("okay")
        self.assertEqual(cm.state.stage, SessionStage.SAFETY_PAUSED)


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