import os
import sys

sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))

import time
from unittest.mock import patch

import pytest

# ---------------------------------------------------------------------------
# TestParseDuration
# ---------------------------------------------------------------------------


class TestParseDuration:
    """parse_duration() 함수 테스트"""

    def test_parse_minutes_korean(self):
        """'30분간' → 30"""
        from discussion_manager import parse_duration

        assert parse_duration("30분간 토론해줘") == 30

    def test_parse_minutes_korean_dong(self):
        """'30분동안' → 30"""
        from discussion_manager import parse_duration

        assert parse_duration("30분동안 얘기해줘") == 30

    def test_parse_hours_korean(self):
        """'2시간동안' → 120"""
        from discussion_manager import parse_duration

        assert parse_duration("2시간동안 토론해줘") == 120

    def test_parse_hours_korean_bare(self):
        """'2시간' → 120"""
        from discussion_manager import parse_duration

        assert parse_duration("2시간 토론해줘") == 120

    def test_parse_minutes_english(self):
        """'30min' → 30"""
        from discussion_manager import parse_duration

        assert parse_duration("discuss for 30min") == 30

    def test_parse_hours_english(self):
        """'2hour' → 120"""
        from discussion_manager import parse_duration

        assert parse_duration("talk for 2hour") == 120

    def test_parse_hours_english_hr(self):
        """'2hr' → 120"""
        from discussion_manager import parse_duration

        assert parse_duration("discuss for 2hr") == 120

    def test_max_duration_cap(self):
        """300분 → 180분으로 캡"""
        from discussion_manager import parse_duration

        assert parse_duration("300분간 토론") == 180

    def test_max_hours_cap(self):
        """10시간 → 180분으로 캡"""
        from discussion_manager import parse_duration

        result = parse_duration("10시간동안 토론")
        assert result == 180

    def test_no_duration(self):
        """일반 텍스트 → None"""
        from discussion_manager import parse_duration

        assert parse_duration("안녕하세요 반갑습니다") is None

    def test_no_duration_empty(self):
        """빈 문자열 → None"""
        from discussion_manager import parse_duration

        assert parse_duration("") is None


# ---------------------------------------------------------------------------
# TestDiscussionManager
# ---------------------------------------------------------------------------


class TestDiscussionManager:
    """DiscussionManager 클래스 테스트"""

    def _make_manager(self):
        from discussion_manager import DiscussionManager

        return DiscussionManager()

    def test_user_message_activates_discussion(self):
        """유저 메시지를 받으면 토론 모드가 활성화된다"""
        mgr = self._make_manager()
        chat_id = 100

        assert mgr.is_discussion_active(chat_id) is False
        mgr.on_user_message(chat_id, "토론 시작해줘")
        assert mgr.is_discussion_active(chat_id) is True

    def test_user_message_with_duration_sets_duration(self):
        """시간 키워드가 있으면 duration_minutes가 설정된다"""
        from discussion_manager import DiscussionManager

        mgr = DiscussionManager()
        chat_id = 101

        mgr.on_user_message(chat_id, "30분간 토론해줘")
        state = mgr._states[chat_id]
        assert state.duration_minutes == 30

    def test_user_message_without_duration_sets_none(self):
        """시간 키워드 없으면 duration_minutes가 None이다 (idle 모드)"""
        from discussion_manager import DiscussionManager

        mgr = DiscussionManager()
        chat_id = 102

        mgr.on_user_message(chat_id, "토론 시작해줘")
        state = mgr._states[chat_id]
        assert state.duration_minutes is None

    def test_round_robin_turn_order(self):
        """봇 응답 후 라운드 로빈 순서대로 다음 턴이 설정된다"""
        from discussion_manager import DiscussionManager

        mgr = DiscussionManager()
        chat_id = 103

        mgr.on_user_message(chat_id, "토론해줘")

        # 첫 번째 봇이 응답
        first_bot = DiscussionManager.BOT_USERNAMES[0]
        mgr._states[chat_id].current_turn = first_bot

        next_bot = mgr.on_bot_response(first_bot)
        assert next_bot == DiscussionManager.BOT_USERNAMES[1]

        next_bot2 = mgr.on_bot_response(DiscussionManager.BOT_USERNAMES[1])
        assert next_bot2 == DiscussionManager.BOT_USERNAMES[2]

        # 마지막 봇 다음은 첫 번째 봇으로 돌아옴
        next_bot3 = mgr.on_bot_response(DiscussionManager.BOT_USERNAMES[2])
        assert next_bot3 == DiscussionManager.BOT_USERNAMES[0]

    def test_idle_timeout_stops_discussion(self):
        """IDLE_TIMEOUT 초과 후 advance_turn() 시 토론이 종료된다"""
        from discussion_manager import DiscussionManager

        mgr = DiscussionManager()
        chat_id = 104

        mgr.on_user_message(chat_id, "토론해줘")  # idle 모드
        # last_user_message_time을 IDLE_TIMEOUT+60초 전으로 설정
        mgr._states[chat_id].last_user_message_time = time.time() - (mgr.IDLE_TIMEOUT + 60)

        result = mgr.advance_turn()
        assert result is None
        assert mgr.is_discussion_active(chat_id) is False

    def test_timed_mode_ignores_idle(self):
        """시간 한정 모드에서는 idle 체크를 무시한다"""
        from discussion_manager import DiscussionManager

        mgr = DiscussionManager()
        chat_id = 105

        mgr.on_user_message(chat_id, "30분간 토론해줘")
        # last_user_message_time을 6분 전으로 설정 (idle 기준 초과)
        mgr._states[chat_id].last_user_message_time = time.time() - 360

        # 30분 duration이므로 아직 종료되지 않아야 함
        assert mgr.check_should_stop() is False

    def test_timed_mode_stops_after_duration(self):
        """시간 한정 모드에서 duration_minutes 초과 시 종료된다"""
        from discussion_manager import DiscussionManager

        mgr = DiscussionManager()
        chat_id = 106

        mgr.on_user_message(chat_id, "1분간 토론해줘")
        # start_time을 2분 전으로 설정
        mgr._states[chat_id].start_time = time.time() - 120

        assert mgr.check_should_stop() is True

    def test_user_message_resets_idle_timer(self):
        """유저 메시지가 오면 idle 타이머가 리셋된다"""
        from discussion_manager import DiscussionManager

        mgr = DiscussionManager()
        chat_id = 107

        mgr.on_user_message(chat_id, "토론해줘")
        # idle 타이머를 옛날 시간으로 설정
        mgr._states[chat_id].last_user_message_time = time.time() - 400

        # 두 번째 유저 메시지
        before = time.time()
        mgr.on_user_message(chat_id, "계속 얘기해줘")
        after = time.time()

        new_time = mgr._states[chat_id].last_user_message_time
        assert before <= new_time <= after + 0.01

    def test_stop_discussion_resets_state(self):
        """stop_discussion() 호출 시 상태가 초기화된다"""
        from discussion_manager import DiscussionManager

        mgr = DiscussionManager()
        chat_id = 108

        mgr.on_user_message(chat_id, "토론해줘")
        assert mgr.is_discussion_active(chat_id) is True

        mgr.stop_discussion()
        assert mgr.is_discussion_active(chat_id) is False

    def test_should_bot_respond_during_discussion_my_turn(self):
        """토론 모드에서 현재 턴이 자신이면 True를 반환한다"""
        from discussion_manager import DiscussionManager

        mgr = DiscussionManager()
        chat_id = 109

        mgr.on_user_message(chat_id, "토론해줘")
        my_bot = DiscussionManager.BOT_USERNAMES[0]
        mgr._states[chat_id].current_turn = my_bot

        result = mgr.should_bot_respond(
            bot_username=my_bot,
            sender_username="someuser",
            sender_is_bot=True,
            chat_id=chat_id,
        )
        assert result is True

    def test_should_bot_respond_not_my_turn(self):
        """토론 모드에서 현재 턴이 자신이 아니면 False를 반환한다"""
        from discussion_manager import DiscussionManager

        mgr = DiscussionManager()
        chat_id = 110

        mgr.on_user_message(chat_id, "토론해줘")
        mgr._states[chat_id].current_turn = DiscussionManager.BOT_USERNAMES[0]

        result = mgr.should_bot_respond(
            bot_username=DiscussionManager.BOT_USERNAMES[1],
            sender_username="someuser",
            sender_is_bot=True,
            chat_id=chat_id,
        )
        assert result is False

    def test_should_bot_respond_non_discussion_bot_message_false(self):
        """토론 모드가 아닐 때 봇 메시지에는 False를 반환한다"""
        from discussion_manager import DiscussionManager

        mgr = DiscussionManager()
        chat_id = 111

        # 토론 모드 비활성화 상태
        result = mgr.should_bot_respond(
            bot_username=DiscussionManager.BOT_USERNAMES[0],
            sender_username=DiscussionManager.BOT_USERNAMES[1],
            sender_is_bot=True,
            chat_id=chat_id,
        )
        assert result is False

    def test_get_next_bot_wraps_around(self):
        """get_next_bot()은 마지막 봇 다음에 첫 번째 봇을 반환한다"""
        from discussion_manager import DiscussionManager

        mgr = DiscussionManager()
        chat_id = 112

        mgr.on_user_message(chat_id, "토론해줘")
        last_bot = DiscussionManager.BOT_USERNAMES[-1]
        mgr._states[chat_id].current_turn = last_bot

        next_bot = mgr.get_next_bot()
        assert next_bot == DiscussionManager.BOT_USERNAMES[0]

    def test_multiple_chats_independent_state(self):
        """서로 다른 chat_id는 독립적인 상태를 가진다"""
        from discussion_manager import DiscussionManager

        mgr = DiscussionManager()
        chat_id_a = 200
        chat_id_b = 201

        mgr.on_user_message(chat_id_a, "토론해줘")
        assert mgr.is_discussion_active(chat_id_a) is True
        assert mgr.is_discussion_active(chat_id_b) is False

    def test_advance_turn_returns_next_bot_when_active(self):
        """토론 진행 중 advance_turn()은 다음 봇 username을 반환한다"""
        from discussion_manager import DiscussionManager

        mgr = DiscussionManager()
        chat_id = 113

        mgr.on_user_message(chat_id, "토론해줘")
        # idle 타이머를 최신으로 설정
        mgr._states[chat_id].last_user_message_time = time.time()
        mgr._states[chat_id].current_turn = DiscussionManager.BOT_USERNAMES[0]

        result = mgr.advance_turn()
        assert result in DiscussionManager.BOT_USERNAMES


# ---------------------------------------------------------------------------
# TestShouldRespond (bot_utils.py 수정 반영)
# ---------------------------------------------------------------------------


class TestShouldRespondBotMessages:
    """bot_utils.should_respond()의 봇 메시지 처리 테스트 (수정된 동작 반영)"""

    def _make_user(self, user_id: int, is_bot: bool = False, username: str = "testuser"):
        from unittest.mock import MagicMock

        user = MagicMock()
        user.id = user_id
        user.is_bot = is_bot
        user.username = username
        return user

    def _make_message(self, text: str, from_user, chat_type: str = "group", entities=None):
        from unittest.mock import AsyncMock, MagicMock

        msg = MagicMock()
        msg.text = text
        msg.from_user = from_user
        msg.chat = MagicMock()
        msg.chat.type = chat_type
        msg.reply_to_message = None
        msg.entities = entities or []
        msg.reply_text = AsyncMock()
        return msg

    def _make_update(self, message):
        from unittest.mock import MagicMock

        update = MagicMock()
        update.message = message
        update.effective_message = message
        update.effective_user = message.from_user
        return update

    def test_self_bot_message_returns_false(self):
        """자기 자신(같은 username)이 보낸 봇 메시지에는 응답하지 않는다"""
        from bot_utils import should_respond

        # 자기 자신 봇이 보낸 메시지
        self_bot = self._make_user(user_id=999, is_bot=True, username="mybot")
        entity = __import__("unittest.mock", fromlist=["MagicMock"]).MagicMock()
        entity.type = "mention"
        entity.offset = 0
        entity.length = len("@mybot")

        message = self._make_message(
            text="@mybot 안녕",
            from_user=self_bot,
            chat_type="group",
            entities=[entity],
        )
        update = self._make_update(message)

        result = should_respond(update, bot_username="mybot", owner_user_id=123456789)
        assert result is False

    def test_other_bot_message_with_mention_returns_true(self):
        """다른 봇이 @멘션한 메시지에는 응답해야 한다 (수정된 동작)"""
        from unittest.mock import MagicMock

        from bot_utils import should_respond

        other_bot = self._make_user(user_id=888, is_bot=True, username="otherbot")

        entity = MagicMock()
        entity.type = "mention"
        entity.offset = 0
        entity.length = len("@mybot")

        message = self._make_message(
            text="@mybot 안녕",
            from_user=other_bot,
            chat_type="group",
            entities=[entity],
        )
        update = self._make_update(message)

        result = should_respond(update, bot_username="mybot", owner_user_id=123456789)
        assert result is True

    def test_other_bot_username_none_returns_false(self):
        """다른 봇이지만 sender.username이 None이면 응답하지 않는다"""
        from unittest.mock import MagicMock

        from bot_utils import should_respond

        other_bot = self._make_user(user_id=888, is_bot=True, username=None)

        entity = MagicMock()
        entity.type = "mention"
        entity.offset = 0
        entity.length = len("@mybot")

        message = self._make_message(
            text="@mybot 안녕",
            from_user=other_bot,
            chat_type="group",
            entities=[entity],
        )
        # username이 None인 봇 설정
        message.from_user.username = None
        update = self._make_update(message)

        result = should_respond(update, bot_username="mybot", owner_user_id=123456789)
        # username이 None이면 자기 자신이 아닌 것으로 판단 → 멘션 조건에 따라 True
        # (is_bot이지만 username이 None이면 자기 자신 체크에서 통과)
        assert result is True


# ---------------------------------------------------------------------------
# TestDetectCodeAnalysis
# ---------------------------------------------------------------------------


class TestDetectCodeAnalysis:
    """detect_code_analysis() 함수 테스트"""

    def test_detect_code_analysis_with_two_keywords(self):
        """'코드 구조를 분석해줘' → True (코드, 분석 2개 매칭)"""
        from discussion_manager import detect_code_analysis

        assert detect_code_analysis("코드 구조를 분석해줘") is True

    def test_detect_code_analysis_with_path(self):
        """.py 파일 읽어줘 → True (경로 패턴)"""
        from discussion_manager import detect_code_analysis

        assert detect_code_analysis(".py 파일 읽어줘") is True

    def test_detect_code_analysis_with_project_path(self):
        """/home/jay/workspace 코드 → True (프로젝트 경로)"""
        from discussion_manager import detect_code_analysis

        assert detect_code_analysis("/home/jay/workspace 코드") is True

    def test_detect_code_analysis_normal_message(self):
        """'오늘 날씨 어때?' → False"""
        from discussion_manager import detect_code_analysis

        assert detect_code_analysis("오늘 날씨 어때?") is False

    def test_detect_code_analysis_single_keyword(self):
        """'코드 좋아' → False (1개만 매칭)"""
        from discussion_manager import detect_code_analysis

        assert detect_code_analysis("코드 좋아") is False

    def test_detect_code_analysis_english(self):
        """'analyze the function implementation' → True"""
        from discussion_manager import detect_code_analysis

        assert detect_code_analysis("analyze the function implementation") is True


# ---------------------------------------------------------------------------
# TestDiscussionManager (코드 분석 모드 관련 테스트 추가)
# ---------------------------------------------------------------------------


class TestDiscussionManagerCodeAnalysis:
    """DiscussionManager 코드 분석 모드 테스트"""

    def _make_manager(self):
        from discussion_manager import DiscussionManager

        return DiscussionManager()

    def test_code_analysis_mode_sets_claude_first(self):
        """코드 분석 메시지 시 current_turn이 'claude_view_bot'이어야 함"""
        mgr = self._make_manager()
        chat_id = 300

        mgr.on_user_message(chat_id, "코드 구조를 분석해줘")
        state = mgr._states[chat_id]
        assert state.current_turn == "claude_view_bot"

    def test_code_analysis_mode_flag_set(self):
        """코드 분석 메시지 시 state.code_analysis_mode == True"""
        mgr = self._make_manager()
        chat_id = 301

        mgr.on_user_message(chat_id, "코드 구조를 분석해줘")
        state = mgr._states[chat_id]
        assert state.code_analysis_mode is True

    def test_normal_message_no_code_analysis_mode(self):
        """일반 메시지 시 state.code_analysis_mode == False"""
        mgr = self._make_manager()
        chat_id = 302

        mgr.on_user_message(chat_id, "오늘 날씨 어때?")
        state = mgr._states[chat_id]
        assert state.code_analysis_mode is False

    def test_is_code_analysis_mode_returns_true(self):
        """is_code_analysis_mode() 메서드 동작 확인"""
        mgr = self._make_manager()
        chat_id = 303

        mgr.on_user_message(chat_id, "코드 구조를 분석해줘")
        assert mgr.is_code_analysis_mode(chat_id) is True

    def test_is_code_analysis_mode_returns_false_unknown_chat(self):
        """존재하지 않는 chat_id면 False"""
        mgr = self._make_manager()

        assert mgr.is_code_analysis_mode(99999) is False

    def test_code_analysis_mode_does_not_change_start_index(self):
        """_start_index가 코드 분석과 무관하게 증가"""
        mgr = self._make_manager()
        chat_id_a = 304
        chat_id_b = 305

        initial_index = mgr._start_index
        mgr.on_user_message(chat_id_a, "코드 구조를 분석해줘")
        assert mgr._start_index == initial_index + 1

        mgr.stop_discussion()
        mgr.on_user_message(chat_id_b, "오늘 날씨 어때?")
        assert mgr._start_index == initial_index + 2


# ---------------------------------------------------------------------------
# TestDiscussionPhase
# ---------------------------------------------------------------------------


class TestDiscussionPhase:
    """DiscussionPhase + get_current_phase() 테스트"""

    def _make_manager(self):
        from discussion_manager import DiscussionManager

        return DiscussionManager()

    def test_phase_enum_values(self):
        from discussion_manager import DiscussionPhase

        assert DiscussionPhase.DIVERGE == "diverge"
        assert DiscussionPhase.CONVERGE == "converge"
        assert DiscussionPhase.CONSENSUS == "consensus"

    def test_initial_phase_is_diverge_idle_mode(self):
        """idle 모드 시작 시 DIVERGE"""
        mgr = self._make_manager()
        chat_id = 400
        mgr.on_user_message(chat_id, "토론해줘")
        from discussion_manager import DiscussionPhase

        assert mgr.get_current_phase(chat_id) == DiscussionPhase.DIVERGE

    def test_idle_mode_converge_at_round_4(self):
        """idle 모드: 4라운드에서 CONVERGE"""
        mgr = self._make_manager()
        chat_id = 401
        mgr.on_user_message(chat_id, "토론해줘")
        mgr._states[chat_id].round_count = 3  # 라운드 4 시작 시점
        from discussion_manager import DiscussionPhase

        assert mgr.get_current_phase(chat_id) == DiscussionPhase.CONVERGE

    def test_idle_mode_consensus_at_round_7(self):
        """idle 모드: 7라운드에서 CONSENSUS"""
        mgr = self._make_manager()
        chat_id = 402
        mgr.on_user_message(chat_id, "토론해줘")
        mgr._states[chat_id].round_count = 6  # 라운드 7 시작 시점
        from discussion_manager import DiscussionPhase

        assert mgr.get_current_phase(chat_id) == DiscussionPhase.CONSENSUS

    def test_timed_mode_diverge_early(self):
        """시간 모드: 초기(0~60%)에 DIVERGE"""
        import time

        mgr = self._make_manager()
        chat_id = 403
        mgr.on_user_message(chat_id, "10분간 토론해줘")
        # 시작 직후 (0%)
        from discussion_manager import DiscussionPhase

        assert mgr.get_current_phase(chat_id) == DiscussionPhase.DIVERGE

    def test_timed_mode_converge_at_70_percent(self):
        """시간 모드: 70%에서 CONVERGE"""
        import time

        mgr = self._make_manager()
        chat_id = 404
        mgr.on_user_message(chat_id, "10분간 토론해줘")
        # 10분의 70% = 7분 경과
        mgr._states[chat_id].start_time = time.time() - 420  # 7분 전
        from discussion_manager import DiscussionPhase

        assert mgr.get_current_phase(chat_id) == DiscussionPhase.CONVERGE

    def test_timed_mode_consensus_at_95_percent(self):
        """시간 모드: 95%에서 CONSENSUS"""
        import time

        mgr = self._make_manager()
        chat_id = 405
        mgr.on_user_message(chat_id, "10분간 토론해줘")
        # 10분의 95% = 9.5분 경과
        mgr._states[chat_id].start_time = time.time() - 570  # 9.5분 전
        from discussion_manager import DiscussionPhase

        assert mgr.get_current_phase(chat_id) == DiscussionPhase.CONSENSUS

    def test_round_count_increments_after_3_bot_responses(self):
        """3봇 응답 후 round_count가 1 증가"""
        mgr = self._make_manager()
        chat_id = 406
        mgr.on_user_message(chat_id, "토론해줘")
        first_bot = mgr._states[chat_id].current_turn

        # 3봇이 순서대로 응답
        bot2 = mgr.on_bot_response(first_bot)
        assert mgr._states[chat_id].round_count == 0  # 아직 1라운드 완료 전

        bot3 = mgr.on_bot_response(bot2)
        assert mgr._states[chat_id].round_count == 0  # 아직

        mgr.on_bot_response(bot3)  # 3번째 봇 응답 → 1라운드 완료
        assert mgr._states[chat_id].round_count == 1
        assert mgr._states[chat_id].bot_response_count == 0  # 리셋

    def test_stop_discussion_resets_round_count(self):
        """stop_discussion()은 round_count도 초기화"""
        mgr = self._make_manager()
        chat_id = 407
        mgr.on_user_message(chat_id, "토론해줘")
        mgr._states[chat_id].round_count = 5
        mgr._states[chat_id].bot_response_count = 2
        mgr.stop_discussion()
        assert mgr._states[chat_id].round_count == 0
        assert mgr._states[chat_id].bot_response_count == 0

    def test_inactive_chat_returns_diverge(self):
        """비활성 chat에서도 기본값 DIVERGE 반환"""
        mgr = self._make_manager()
        from discussion_manager import DiscussionPhase

        assert mgr.get_current_phase(999) == DiscussionPhase.DIVERGE


# ---------------------------------------------------------------------------
# TestDiscussionManagerChainGuard
# ---------------------------------------------------------------------------


class TestDiscussionManagerChainGuard:
    """DiscussionManager 체인 중복 방지 테스트"""

    def _make_manager(self):
        from discussion_manager import DiscussionManager

        return DiscussionManager()

    def test_chain_running_default_false(self):
        """기본값은 False"""
        mgr = self._make_manager()
        assert mgr.is_chain_running(100) is False

    def test_set_chain_running_true(self):
        """set_chain_running(True) 후 is_chain_running True"""
        mgr = self._make_manager()
        mgr.set_chain_running(100, True)
        assert mgr.is_chain_running(100) is True

    def test_set_chain_running_false(self):
        """set_chain_running(False) 후 is_chain_running False"""
        mgr = self._make_manager()
        mgr.set_chain_running(100, True)
        mgr.set_chain_running(100, False)
        assert mgr.is_chain_running(100) is False

    def test_stop_discussion_resets_chain_running(self):
        """stop_discussion() 시 chain_running도 초기화"""
        mgr = self._make_manager()
        chat_id = 500
        mgr.on_user_message(chat_id, "토론해줘")
        mgr.set_chain_running(chat_id, True)
        mgr.stop_discussion()
        assert mgr.is_chain_running(chat_id) is False

    def test_on_user_message_returns_true_for_new_discussion(self):
        """새 토론 시작 시 on_user_message는 True 반환"""
        mgr = self._make_manager()
        result = mgr.on_user_message(100, "토론해줘")
        assert result is True

    def test_on_user_message_returns_false_for_active_discussion(self):
        """이미 활성 토론 중 유저 메시지 시 False 반환"""
        mgr = self._make_manager()
        mgr.on_user_message(100, "토론해줘")
        result = mgr.on_user_message(100, "계속해줘")
        assert result is False


# ---------------------------------------------------------------------------
# TestDeepMode
# ---------------------------------------------------------------------------


class TestDeepMode:
    """--deep 모드 + codex_model 테스트"""

    def _make_manager(self):
        from discussion_manager import DiscussionManager

        return DiscussionManager()

    def test_default_codex_model_is_mini(self):
        """기본 codex_model은 gpt-5.1-codex-mini"""
        mgr = self._make_manager()
        chat_id = 600
        mgr.on_user_message(chat_id, "토론해줘")
        assert mgr._states[chat_id].codex_model == "gpt-5.1-codex-mini"

    def test_deep_flag_sets_codex_model(self):
        """--deep 포함 시 codex_model이 gpt-5.2-codex로 설정"""
        mgr = self._make_manager()
        chat_id = 601
        mgr.on_user_message(chat_id, "--deep 이 주제를 토론해줘")
        assert mgr._states[chat_id].codex_model == "gpt-5.2-codex"

    def test_deep_flag_stripped_from_message(self):
        """--deep 플래그가 제거된 후 duration 파싱 및 코드분석 감지에 사용"""
        mgr = self._make_manager()
        chat_id = 602
        # --deep만 있고 시간 없음 → duration_minutes는 None
        mgr.on_user_message(chat_id, "--deep 일반 토론")
        assert mgr._states[chat_id].duration_minutes is None

    def test_deep_flag_with_duration(self):
        """--deep과 시간 키워드 동시 사용"""
        mgr = self._make_manager()
        chat_id = 603
        mgr.on_user_message(chat_id, "--deep 30분간 토론해줘")
        assert mgr._states[chat_id].codex_model == "gpt-5.2-codex"
        assert mgr._states[chat_id].duration_minutes == 30

    def test_get_codex_model_returns_model(self):
        """get_codex_model()이 올바른 모델 반환"""
        mgr = self._make_manager()
        chat_id = 604
        mgr.on_user_message(chat_id, "--deep 토론")
        assert mgr.get_codex_model(chat_id) == "gpt-5.2-codex"

    def test_get_codex_model_default(self):
        """get_codex_model()이 기본값 반환"""
        mgr = self._make_manager()
        chat_id = 605
        mgr.on_user_message(chat_id, "일반 토론")
        assert mgr.get_codex_model(chat_id) == "gpt-5.1-codex-mini"

    def test_get_codex_model_unknown_chat(self):
        """존재하지 않는 chat_id에 대해 기본값 반환"""
        mgr = self._make_manager()
        assert mgr.get_codex_model(99999) == "gpt-5.1-codex-mini"

    def test_stop_discussion_resets_codex_model(self):
        """stop_discussion() 시 codex_model 초기화"""
        mgr = self._make_manager()
        chat_id = 606
        mgr.on_user_message(chat_id, "--deep 토론")
        assert mgr._states[chat_id].codex_model == "gpt-5.2-codex"
        mgr.stop_discussion()
        assert mgr._states[chat_id].codex_model == "gpt-5.1-codex-mini"

    def test_deep_flag_without_extra_text(self):
        """--deep만 있는 경우"""
        mgr = self._make_manager()
        chat_id = 607
        mgr.on_user_message(chat_id, "--deep")
        assert mgr._states[chat_id].codex_model == "gpt-5.2-codex"

    def test_no_deep_flag_keeps_default(self):
        """--deep 없으면 기본 모델 유지"""
        mgr = self._make_manager()
        chat_id = 608
        mgr.on_user_message(chat_id, "보험에 대해 토론해줘")
        assert mgr._states[chat_id].codex_model == "gpt-5.1-codex-mini"

    def test_deep_mode_announced_flag(self):
        """should_announce_deep_mode() 한번만 True 반환"""
        mgr = self._make_manager()
        chat_id = 609
        mgr.on_user_message(chat_id, "--deep 토론")
        assert mgr.should_announce_deep_mode(chat_id) is True
        assert mgr.should_announce_deep_mode(chat_id) is False  # 두번째 호출은 False
