"""Claude 텔레그램 봇.

python-telegram-bot v20+ (async) 기반.
환경변수 CLAUDE_BOT_TOKEN을 사용합니다.
"""

from __future__ import annotations

import logging

from bot_utils import replace_thinking_message, send_response, send_thinking_message, should_respond
from conversation_memory import BOT_PERSONAS, ConversationMemory
from discussion_manager import DiscussionManager
from engine_v2.bot_api import call_claude
from telegram import Update
from telegram.constants import ChatAction
from telegram.ext import Application, ContextTypes, MessageHandler, filters

from config import CLAUDE_BOT_TOKEN, MAX_MESSAGE_LENGTH, OWNER_USER_ID

logging.basicConfig(
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
    level=logging.INFO,
)
logger = logging.getLogger(__name__)

CODE_ANALYSIS_PROMPT_PREFIX = """[코드 분석 모드] 사용자가 코드/파일 분석을 요청했습니다.
Read, Grep, Glob 도구를 사용하여 관련 파일을 읽고 분석하세요.
분석 결과를 다른 참여자(잼민이, 코덱스)가 이해할 수 있도록 핵심 내용을 정리하여 공유하세요.
프로젝트 경로: /home/jay/workspace/ (시스템), /home/jay/projects/ (프로젝트)

"""


async def handle_message(
    update: Update,
    context: ContextTypes.DEFAULT_TYPE,
    dm: DiscussionManager | None = None,
    memory: ConversationMemory | None = None,
) -> None:
    """수신 메시지를 처리하고 Claude CLI 결과를 반환합니다."""
    if update.message is None:
        return

    bot_username = context.bot.username or ""
    message = update.message
    sender = message.from_user
    if sender is None:
        return

    chat_id = message.chat.id
    user_text = (message.text or "").strip()
    if not user_text:
        return

    if dm is not None and sender.is_bot:
        # 봇 메시지 → 토론 모드일 때만 응답
        sender_username = sender.username or ""
        if not dm.should_bot_respond(bot_username, sender_username, True, chat_id):
            return
    else:
        # 유저 메시지 → 기존 should_respond 로직
        if not should_respond(update, bot_username, OWNER_USER_ID):
            return

    # 유저 메시지일 때 토론 매니저에 알림 + 순차 응답 체크
    if dm is not None and not sender.is_bot:
        is_new = dm.on_user_message(chat_id, user_text)
        # 순차 응답: 이 봇의 턴이 아니면 스킵
        if not dm.is_my_turn(bot_username, chat_id):
            return
        # --deep 플래그 제거 (토론 주제에서 제외)
        user_text = user_text.replace("--deep", "").strip() if "--deep" in user_text else user_text
        # 심층 분석 모드 안내 (1회)
        if is_new and dm.should_announce_deep_mode(chat_id):
            await context.bot.send_message(chat_id=chat_id, text="🔬 심층 분석 모드")
        # 유저 메시지를 메모리에 저장 (턴인 봇만 1회 저장)
        if memory is not None:
            memory.add_message(chat_id, "제이회장님", user_text, is_bot=False)

    try:
        if memory is not None:
            # 사고 모드: 생각 중... → 맥락 프롬프트 → 응답 교체
            thinking_msg_id = await send_thinking_message(context.bot, chat_id)

            context_prompt = memory.format_context(chat_id, bot_username, current_message=user_text)
            is_code_mode = dm is not None and dm.is_code_analysis_mode(chat_id)
            if is_code_mode:
                context_prompt = CODE_ANALYSIS_PROMPT_PREFIX + context_prompt
            result = await call_claude(context_prompt, code_analysis=is_code_mode)

            await replace_thinking_message(context.bot, chat_id, thinking_msg_id, result)

            # 응답을 메모리에 저장
            bot_name = BOT_PERSONAS.get(bot_username, {}).get("name", bot_username)
            memory.add_message(chat_id, bot_name, result, is_bot=True)
        else:
            # 폴백: 기존 동작 (memory 없을 때)
            chat = update.effective_chat
            if chat is not None:
                await context.bot.send_chat_action(
                    chat_id=chat.id,
                    action=ChatAction.TYPING,
                )
            is_code_mode = dm is not None and dm.is_code_analysis_mode(chat_id)
            prompt = (CODE_ANALYSIS_PROMPT_PREFIX + user_text) if is_code_mode else user_text
            result = await call_claude(prompt, code_analysis=is_code_mode)
            await send_response(update, context, result, max_len=MAX_MESSAGE_LENGTH)

        # 봇 응답 후 다음 턴 트리거 (체인이 이미 실행 중이면 스킵)
        if dm is not None and not dm.is_chain_running(chat_id):
            next_bot = dm.on_bot_response(bot_username)
            if next_bot:
                import asyncio

                dm.set_chain_running(chat_id, True)
                trigger_fn = context.bot_data.get("trigger_next_bot_response")
                if trigger_fn is not None:
                    asyncio.create_task(
                        trigger_fn(
                            next_bot,
                            chat_id,
                            result,
                            bot_username,
                        )
                    )
            else:
                dm.stop_discussion()

    except Exception as e:
        logger.error("handle_message 오류: %s", e, exc_info=True)
        try:
            await update.message.reply_text(f"❌ 오류가 발생했습니다: {e}")
        except Exception:
            pass


def main() -> None:
    application = Application.builder().token(CLAUDE_BOT_TOKEN).build()
    application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message))
    logger.info("Claude 봇 시작 중...")
    application.run_polling()


if __name__ == "__main__":
    main()
