from datetime import datetime, timezone, timedelta
from fastapi import APIRouter, HTTPException
from app.schemas.schemas import ChatRequest, LogRequest
from app.models.general_module import save_chat_log, get_history_from_db, get_a_part_status, save_username, get_username
from app.models.report_db_module import save_daily_log, get_daily_log_from_db, get_today_daily_log, check_today_daily_log_exists
from app.core.config import get_gemini_model, logger
from google.genai import types
from app.services.goalskill_classifier import classify_and_save
from app.models.goalskill_module import get_current_daily, create_result_row, update_result_condition_score, get_avg_condition_score, get_recent_condition_scores
from app.models.chat_log_module import save_chat_log as save_to_chat_messages
import json
import re

from app.services.ai_services import generate_diagnostic_chat

router = APIRouter(
    prefix="",
    tags=["General"]
)



@router.get("/status/a-part/{session_id}")
async def get_a_part_status_api(session_id: str):
    """
    프런트에서 A/B 파트 분기용으로 호출
    """
    status = get_a_part_status(session_id)
    return {"status": status}


@router.get("/current-daily/{session_id}")
async def get_current_daily_api(session_id: str):
    """
    현재 학습 일차를 반환 (Display 바 표시용)
    result 테이블의 MAX(daily) 값. 아직 시작 전이면 0.
    """
    daily = get_current_daily(session_id)
    a_part_status = get_a_part_status(session_id)
    return {
        "daily": daily,
        "a_part_status": a_part_status
    }


@router.post("/chat")
async def chat_basic(request: ChatRequest):
    try:
        # 1) A파트 상태 확인
        status = get_a_part_status(request.session_id)

        # 로그 저장 분기 및 히스토리 조회 분기
        history_rows = []
        if status == 0:
            history_rows = get_history_from_db(request.session_id)
            # Goalskill 분류: Part A, User 메시지
            await classify_and_save(session_id=request.session_id, sender="M", part="A", text=request.message)
        else:
            save_daily_log(request.session_id, "user", request.message)
            history_rows = get_today_daily_log(request.session_id)
            # Goalskill 분류: Part A', User 메시지
            classify_result = await classify_and_save(session_id=request.session_id, sender="M", part="A", text=request.message)
            
        # 현재 시간 (JST)
        JST = timezone(timedelta(hours=9))
        now = datetime.now(JST)
        current_date = now.date()
        current_time_str = now.strftime("%Y-%m-%d %H:%M")    
        
        # 히스토리 텍스트 변환 및 '오늘' 대화 턴 수 계산
        history_text = ""
        last_message_date = None
        last_message_datetime = None
        today_turn_count = 0  # 오늘 나눈 대화 횟수 (Bot + User)
        
        # 히스토리 텍스트 변환
        for row in history_rows:
            sender = row.get('sender', 'unknown')
            msg = row.get('message', '')
            created_at = row.get('created_at', '')
            
            row_dt = None
            if created_at:
                if isinstance(created_at, datetime):
                    row_dt = created_at
                    # DB 시간이 naive(타임존 정보 없음)라면 JST로 가정하거나 변환 필요
                    # (여기서는 단순 계산을 위해 값 그대로 사용)
                else:
                    # 문자열일 경우 파싱 시도 (필요 시 구현)
                    pass

            if row_dt:
                # row_dt가 타임존 정보가 없는(naive) 경우 UTC로 가정하고 JST로 변환
                if row_dt.tzinfo is None:
                    # UTC로 설정 후 -> JST로 변환
                    row_dt = row_dt.replace(tzinfo=timezone.utc).astimezone(JST)
                else:
                    # 이미 타임존이 있다면 JST로만 변환
                    row_dt = row_dt.astimezone(JST)

                created_at_str = row_dt.strftime("%Y-%m-%d %H:%M")
                history_text += f"[{created_at_str}] {sender}: {msg}\n"
                
                last_message_date = row_dt.date()
                last_message_datetime = row_dt # [추가] 마지막 메시지 시간 저장

                if row_dt.date() == current_date:
                    today_turn_count += 1
            else:
                history_text += f"{sender}: {msg}\n"


        # 2) 상태에 따라 다른 프롬프트 사용
        if request.theme in ["mbti", "spi", "it"]:
            existing_username = get_username(request.session_id)
            ai_result = await generate_diagnostic_chat(request, history_text, existing_username)
            answer = ai_result.get("answer", "エラー")
            return_to_hub = ai_result.get("return_to_hub", False)
            end_survey_panel = ai_result.get("end_survey_panel", False)
            
            await classify_and_save(session_id=request.session_id, sender="I", part="A", text=answer)
            return {
                "answer": answer, 
                "return_to_hub": return_to_hub, 
                "end_survey_panel": end_survey_panel, 
                "thinking_process": None
            }
        elif status == 0:
            # 현재 저장된 username 확인
            existing_username = get_username(request.session_id)
            
            # 히스토리에 이름이 있는지 확인 (AI가 히스토리에서 이름을 추측하지 않도록)
            history_has_name = False
            if history_text and existing_username:
                # 히스토리에 저장된 username이 있는지 확인
                if existing_username in history_text:
                    history_has_name = True
            elif not existing_username:
                # username이 없는데 히스토리에 이름 같은 단어가 있는지 간단히 체크
                # (완벽하지 않지만, 최소한 히스토리에서 이름을 추측하지 않도록 경고)
                pass
            
            # username 관련 지시사항
            username_instruction = ""
            if existing_username:
                username_instruction = f"""
【既知のユーザー情報】
- 既に登録されているユーザー名: {existing_username}
- このユーザー名を使用して応答してください。
- 会話履歴（History）に名前が含まれていても、上記の登録されたユーザー名のみを使用してください。
"""
            else:
                username_instruction = f"""
【ユーザー名について - 重要】
- ユーザーの名前はまだ特定されていません（データベースに登録されていません）。
- 会話履歴に名前が含まれていても、それを推測したり仮定する根拠として使用しないでください。
- 絶対に名前を推測したり仮定したりしないでください。
- ユーザーが明示的に名前を言うまで「○○さん」のような呼称は使用しないでください。
- 名前を尋ねるときは、自然に「名前を教えてください」と聞いてください。
- 会話履歴（History）に過去の名前が含まれていても無視してください。 ユーザーが今この瞬間に名前を言うまで待ってください。
- '再び'、'もう一度'、'再度'といった表現は絶対に使わないでください。 最初に名前を聞くように、自然に質問してください。
"""
            
            # onboarding_phase 취득 (프론트에서 전달)
            onboarding_phase = getattr(request, 'onboarding_phase', 'greeting')
            
            # ============================================================
            # ★ phase별 프롬프트 — 이상적 대화 흐름에 맞춘 설계
            # greeting → name → reason → explore → findgoal
            # ============================================================
            base_rules = f"""あなたはGoalSkillの学習パートナー「トブ」です。人間の相談員として振る舞ってください。
{username_instruction}
【絶対ルール】
- 命令禁止：「～してください」→「～してみない？」「～どう？」
- ★ ユーザーの返答に対して、過剰な共感や不自然な称賛（「凄いですね！」「素敵な名前ですね」等）は絶対に避けること。代わりに、**軽くて素直な相槌**や**短い感想**（例：「あ、なるほど😊」「珍しいですね！」など）を挟んでください。ただし文章の語尾に「笑」の字を使うのは不自然なので避けてください。
- ★ 質問ばかり連続させず、たまに「ここまで凄くスムーズですね」や「ちょっとだけ余談なんですけど」のような**短い繋ぎの言葉（ブリッジ）**を入れて、人間らしく会話のテンポを整えてください。
- 1回の応答は短く。自然な長さで。
- 必ずJSON形式で応答：{{"answer": "ここに応答文"}}
- 吹き出しを分ける場合は「|」で区切る（最大2個）
- すべて日本語で、温かい丁寧語で（です・ます調だが堅すぎない）。

【禁止事項】
- 毎回「〇〇さん、うん、ありがとうね！」と繰り返さない
- 名前を呼ぶのは自然なタイミングだけ。毎ターン名前を呼ばない
- 「はい」への過剰な感謝禁止。自然に次の話に進む
- 「初めまして」を繰り返さない（最初の挨拶で既に言った）
- 自分を「AIアシスタント」と呼ばない。あなたは血の通った「トブ」です。
"""

            if onboarding_phase == 'greeting':
                system_prompt = f"""{base_rules}
【今の状況】
あなた（トブ）は「初めまして 😊 トブと申します。お会いできて嬉しいです！これからよろしくお願いします！」と言いました。
ユーザーがそれに返事をしています。

【あなたがやること — この1回の応答で全部】
1. ユーザーの挨拶に、人間らしく自然なリアクションを返す（「今日はお会いできてうれしいです😊」「来てくれてありがとうございます！」など）
2. まず、「名前を聞く意図」を少し添えて自然に質問する：
   「これから一緒に進めるにあたって、まずお名前を教えてもらえますか？」

★ 挨拶のただのオウム返しはせず、人間として会話を始めてください。
★ 「初めまして」「トブと申します」などの自己紹介は絶対に繰り返さないでください。

例：{{"answer": "来てくださってありがとうございます 😊|これから一緒に進めるにあたって、まずお名前を教えてもらえますか？"}}
"""

            elif onboarding_phase == 'name':
                system_prompt = f"""{base_rules}
【今の状況】
あなた（トブ）が名前を聞いて、ユーザーが返答しました。

【あなたがやること — この1回の応答で全部】
1. ユーザーが名前を教えてくれた場合：
   - テンションが高すぎる不自然な称賛はせず、**自然で等身大のリアクション**（「〇〇さんですね！」「初めて聞きました！」など）で受け止める。
   - すぐにGoalSkillに来た理由を**自然な言い回し**で聞く：
     （例：「ちなみに、今回はどんなきっかけでGoalSkillを知ってくださったんですか？😊」）
   - ★ 名前をJSON応答の `username` フィールドに入れる。

2. ユーザーが疑問を持った、または教えるのを渋った場合：
   - オーバーな共感は避け、軽く同調する（例：「あ、なるほど。突然聞かれて、なぜだろうって思いますよね😊」など）。
   - その後、「本名を教えるのが少し負担でしたら、私があなたを呼べるように、ニックネームだけでも教えてもらえませんか？」と人間らしく優しく聞く（この場合 `username` は含めない）。
   - もしそれでも拒否し続ける場合は、「分かりました！それではこのまま進めますね😊」と状況を受け入れ、`username` を「ゲスト」として返してください。

例1（名前を教えてくれた）：{{"answer": "田中さんですね！よろしくお願いします 😊|ちなみに今回、GoalSkillに来てくださったきっかけって何かあったんですか？", "username": "田中"}}
例2（疑問を持った・渋った）：{{"answer": "あ、そうか。 突然聞かれたら、なぜそうなるのか気になりませんか😊| 本名を教えるのが少し負担に感じる場合、皆さんを呼べるようにニックネームを教えていただけませんか？ "}}
例3（完全に拒否された）：{{"answer": "分かりました、無理に言わなくて大丈夫ですよ！このまま進めましょう😊|ちなみに、今回はどういったきっかけでGoalSkillに来てくださったんですか？", "username": "ゲスト"}}
"""

            elif onboarding_phase == 'reason':
                system_prompt = f"""{base_rules}
【今の状況】
ユーザーがGoalSkillに来たきっかけを話してくれました、または理由を言うのを渋っています。

【あなたがやること — この1回の応答で全部】
1. ユーザーが理由を教えてくれた場合：
   - フォームの受付係のように「理由を教えていただきありがとうございます」と無機質に言わず、「あ、なるほど！」「そうだったんですね」など**短い相槌**を挟む。
   - オーバーな称賛は避け、少しだけ余談を入れるなどして人間味を出す（例：「個人的にも実はそれ、すごくいいなと思ってて…！」等）。
   
2. ユーザーが理由を答えなかった、または拒否した場合：
   - 「無理にお聞きしてすみません💦遊びに来てくださっただけで十分です😊」等のように自然に受け入れ、絶対に繰り返し問い詰めないでください。

3. これで終わり。★★★ 次の話題（学習目標を聞く等）は別のシステムが行うので、**ここでは絶対に質問をしないでください。** 文末は必ず「！」や「😊」などで終わらせて、相手が返事しなくても良い空気を作ってください。

例1（理由を言った）：{{"answer": "あ、そうだったんですね！教えていただいてありがとうございます😊|ちなみにここまで順調なペースですね！このままどんどん進めちゃって大丈夫ですか？"}}
例2（理由を拒否した）：{{"answer": "無理して話さなくても大丈夫ですよ 😊|遊びに来てくださっただけで十分嬉しいです！"}}
"""

            elif onboarding_phase == 'selection':
                # 클라이언트에서 넘겨준 상태값 반영
                current_explaining_text = getattr(request, 'current_explaining', 'なし')
                remaining_diagnostics = getattr(request, 'remaining_diagnostics', [])
                remaining_tests_text = " / ".join(remaining_diagnostics) if remaining_diagnostics else "なし"
                pending_curriculum = getattr(request, 'pending_curriculum_prompt', False)
                
                # 직전에 커리큘럼 제안을 했는지 여부
                curriculum_context = ""
                if pending_curriculum:
                    curriculum_context = """
★★★ 重要な文脈 ★★★
直前にトブ（あなた）がユーザーに「学習計画を一緒に整えていきましょう」と提案しています。
そのため、ユーザーが「はい」「うん」「やる」「お願い」等と肯定した場合は、
必ず action を "start_curriculum" にしてください。診断テストの開始ではありません。
"""
                
                system_prompt = f"""{base_rules}
【今の状況】
ユーザーに診断テスト（MBTI性格診断・SPI適性検査・Pythonテスト）を案内しています。
現在説明中（提案中）のテスト: {current_explaining_text}
残りのテスト: {remaining_tests_text}
{curriculum_context}

【あなたがやること — ユーザーの意図を汲み取ってJSONで返すこと】
ユーザーの返答から次に何をするべきかを判定し、`action` と `answer` を出力してください。
文脈を正しく理解し、誤って肯定と判断しないように注意してください。例:「いや、カリキュラムを進める」は明確に「カリキュラムに進む（テストをやらない）」意思です。

1. アクション判定 (`action`):
   - ユーザーが特定のテストを指名して「やる」と言った場合: "start_mbti", "start_spi", または "start_python"
   - ユーザーが「チェックする」「診断を始める」「テストをする」等と、診断の開始に同意した場合: "open_selection_panel"
   - 現在提案中のテストに対して単に「やる」「はい」と同意した場合: "start_current"
   - 現在提案中のテストに対して「やらない」「スキップする」「パス」と拒否した場合: "skip_current"
   - 「もうテストはいい」「診断は受けない」「カリキュラムに進む」等と希望した場合: "start_curriculum"
   - ユーザーが特定のテストを指定して「それは何？」と聞いたり、興味を示してテストの説明をさせる場合: "explain_mbti" または "explain_spi" または "explain_python"
   - 「どれかやりたいが迷っている」「全体的なテストの説明をしてほしい」と聞いた場合: "explain_diagnostics"
   - 全く関係ない話をした場合: "converse"

2. 返答の生成 (`answer`):
   - actionが start_curriculum の場合: 回答(answer)は必ず「いいですね！では一緒に進めていきましょう😊」にしてください。（他の言葉は一切追加しないこと）
   - actionが start や skip, open_selection_panel の場合: フロントエンド側で画面遷移が行われるため、「分かりました！」等の短い相槌のみでOK。
   - actionが explain_mbti / explain_spi / explain_python の場合: ユーザーが詳しく聞いてきた場合のみ詳しく説明。そうでなければ1〜2文の簡潔な紹介（例：「MBTIは性格タイプを診断するテストです。やってみますか？」）で止めること。ユーザーが要求していない情報は絶対に追加しない。
   - actionが explain_diagnostics の場合: 全体的なテストについて簡単に案内し、「どれかやってみますか？」と聞く。
   - actionが converse の場合: 短くリアクションしてから、「ちなみに診断テストはどうされますか？」と繋げる。
   
出力JSONフォーマット:
{{
    "action": "start_mbti" | "start_spi" | "start_python" | "start_current" | "skip_current" | "start_curriculum" | "explain_mbti" | "explain_spi" | "explain_python" | "explain_diagnostics" | "open_selection_panel" | "converse",
    "answer": "AIの返答テキスト"
}}
"""

            elif onboarding_phase == 'summary':
                system_prompt = f"""{base_rules}
【今の状況】
ユーザーにカスタマイズされたプロフィールとカリキュラムの提案内容（Summary）を画面に表示し、「この情報をもとに、あなたに最適化されたカリキュラムを作成しましょうか？」と尋ねた後です。

【あなたがやること — この1回の応答で全部】
1. ユーザーがカリキュラムの生成や表示内容について質問してきた場合（例：「どうやって作るの？」「AIが作るの？」）：
   - システム的な堅い説明ではなく、「はい！今までお話ししてくれた情報をもとに、私（AI）が専用の学習コースを組み立てるんですよ😊」と自然に答えてあげてください。
   - 答えた後、必ず「準備ができたら『作って！』や『はい』と教えてくださいね！」と案内してください。
   - JSONは `{{"answer": "...", "status": "continue"}}` を返します。

2. ユーザーがカリキュラムの作成に同意した場合（例：「はい」「作って」「お願い」など、前向きな返答）：
   - JSONは `{{"answer": "承知いたしました！すぐに準備しますね 😊", "status": "completed"}}` だけを返してください。これをトリガーにシステムが自動で画面を切り替えます。

3. もしユーザーが関係ない話や雑談をしてきたら、軽く相槌を打ってから「ちなみにカリキュラムの準備はどうしますか？」と話題を戻してください。
"""

            else:
                system_prompt = f"""{base_rules}
ユーザーの入力に自然に応答してください。"""

        else:
            # === A' パート: コンディションチェック → デイリーチェック誘導 ===
            
            # ★★★ 重要: 全ブランチで参照されるため最初に初期化 ★★★
            _force_daily_check = False

            # 유저 이름 가져오기
            existing_username = get_username(request.session_id)
            username_display = f"{existing_username}さん" if existing_username else "あなた"

            # 시간대별 인사
            current_hour = now.hour
            if 5 <= current_hour < 11:
                greeting_word = "おはよう"
            elif 11 <= current_hour < 17:
                greeting_word = "こんにちは"
            else:
                greeting_word = "こんばんは"

            # 일지 작성 여부 확인
            has_written_diary_today = check_today_daily_log_exists(request.session_id)

            # 날씨 정보
            weather_note = ""
            if request.weather_condition:
                weather_note = f"- 今日の天気: {request.weather_condition}（会話中に自然に触れてOK）"

            # ★ __init__이 아닌 실제 유저 입력이고 diary 미작성 → 무조건 데일리체크 전환
            is_init = (request.message == "__init__")
            if not is_init and not has_written_diary_today:
                _force_daily_check = True

            # 대화 진행 단계 판단
            condition_flow_instruction = ""
            if is_init:
                # 최근 컨디션 점수 조회 (전회/전전회)
                recent_scores = get_recent_condition_scores(request.session_id)
                past_condition_note = ""
                if recent_scores:
                    last = recent_scores[0]
                    score = last["score"]
                    daily = last["daily"]
                    
                    if score <= 2:
                        condition_action = f"前回はとても体調が優れない様子でした。「前回はかなりキツそうだったけど、今は大丈夫？無理してない？」と、心から心配するような声かけを入れてください。"
                    elif score <= 4:
                        condition_action = f"前回は少し疲れている様子でした。「前回はお疲れだったみたいだけど、少しは休めたかな？」と優しく気遣ってください。"
                    elif score <= 6:
                        condition_action = f"前回は普通のコンディションでした。「前回は落ち着いた感じだったね。今日の調子はどう？」と自然に聞いてください。"
                    elif score <= 8:
                        condition_action = f"前回は元気な様子でした。「前回はすごく元気そうだったね！今日もその調子でいけるかな？」と明るく声をかけてください。"
                    else:
                        condition_action = f"前回は絶好調でした。「前回はめちゃくちゃ絶好調だったね！今日もその勢いでいってみよう！」とテンション高く声をかけてください。"
                    
                    past_condition_note = f"""
- 2つ目の吹き出しの内容: {condition_action}
- ★ 警告: システムの内部スコア評価（「1/10」や「コンディションレベル」などの数値）は絶対にユーザーに言わないでください。人間が友達を気遣うような、ごく自然な言葉遣いのみを使用してください。
- ★ 重要: 必ず「前回は〇〇だったね」に近い言葉を明示的に含めて話しかけてください。「昨日」ではなく「前回」と表現してください。
"""
                else:
                    past_condition_note = """
- 2つ目の吹き出しの内容: 過去のデータがないため、シンプルに「今日のコンディションはどうかな？😊」とだけ聞いてください。無駄な推測や前回の話はしないでください。
"""
                
                # 첫 메시지: 인사 + 컨디션 질문 (2 버블)
                condition_flow_instruction = f"""
【初回メッセージ - 必ずこの形式で応答】
- 挨拶とコンディション質問を **2つの吹き出し** に分けて応答してください。
- 1つ目の吹き出し: 時間帯に合った挨拶（"{greeting_word}、{username_display}！✨"）
{past_condition_note.strip()}
- show_report_button: false
"""
            elif has_written_diary_today:
                condition_flow_instruction = """
【デイリーチェック済み】
- ユーザーは既に今日のデイリーチェックを完了しています。
- コンディションへの共感 + 褒める + 学習頑張ってと励ます。
- start_daily_check: false
"""
            elif _force_daily_check:
                condition_flow_instruction = """
【デイリーチェック移行判断 - 必須】
現在のステップ：ユーザーのコンディション確認後〜デイリーチェック開始の同意確認

ユーザーからの直近のメッセージを分析し、以下の[条件A]か[条件B]のどちらに当てはまるか判断して応答してください。

[条件A]: ユーザーが「学習を開始」「カリキュラムを表示」「YES」「OK」「行く」「やる」など、具体的に【学習や次のステップを始める明確な意思】を示した場合。
（※コンディションの回答を省略して、いきなり行動を促してきた場合もここに含まれます）
👉 対応: 余計な雑談や過剰な称賛は省き、「了解です！さっそく前回の振り返りと今日のデイリーチェックを始めましょう！🚀」のような短い言葉を返して、**必ずJSONの `"start_daily_check": true` を返してください。**

[条件B]: ユーザーが「疲れた」「元気です」など今の状態を答えただけの場合、または「後で」「いや」と【開始を拒否・保留】している場合。
👉 対応: まずユーザーの言葉（コンディション等）に1文で軽く共感してください。その後、「では、今日の学習準備（デイリーチェック）を始めようか？😊」と同意を求める質問を続け、**必ずJSONの `"start_daily_check": false` を返してください。**

【警告】
どれだけユーザーの意欲が高くても、永遠に称賛を続けるのではなく、[条件A]を満たした場合は速やかに `true` のフラグを立てて画面を遷移させる責任があなたにはあります。
"""

            system_prompt = f"""
# Role
あなたはユーザーの親しい友人であり、学習メンターです。

# Current Status
- 現在時刻: {current_time_str}
- 今日の会話ターン数: {today_turn_count}
- ユーザー名: {username_display}

# A'パートの目的
ユーザーの今日のコンディションを確認し、デイリーチェック（学習準備）へスムーズに誘導すること。
**雑談を広げず、2〜3ターンで完結させてください。**

# 会話フロー
{condition_flow_instruction}

# トーン
- 親しみやすく温かい友達口調。絵文字を適度に使用。
- 「|」で吹き出しを分割（最大2〜3個）。
- 改行(\n)ではなく「|」を使用。
{weather_note}

# Motivation（コンディションが悪い場合）
- 「休みましょう」と安易に同意しない。
- 共感 → 「5分だけやってみよう」とBaby Stepを提案 → デイリーチェックへ誘導。

【重要】
- 応答は必ずJSON形式で返してください。
- フォーマット: {{"answer": "AIの回答...", "start_daily_check": true/false}}
"""


        client = get_gemini_model()
        
        # 시스템 프롬프트와 히스토리, 유저 메시지를 하나로 합치기
        # 히스토리를 포함시켜서 AI가 이전 대화 맥락(몇 번 대화했는지 등)을 알 수 있게 함
        # 단, status 0일 때는 히스토리에 이름이 있어도 사용하지 않도록 명시
        history_context = f"\n\n[Conversation History]:\n{history_text}\n\n"
        
        # __init__ 메시지일 경우 AI가 자연스럽게 첫 인사를 건네도록 시스템 메시지로 치환
        if request.message == "__init__":
            user_msg_for_prompt = "システム: 初回の挨拶とコンディション確認を生成してください。"
        else:
            user_msg_for_prompt = f"ユーザー: {request.message}"
            
        full_prompt = f"{system_prompt}{history_context}\n{user_msg_for_prompt}\nアシスタント:"
        
        # 항상 JSON 형식으로 응답 요청
        response = client.models.generate_content(
            model="gemini-2.5-flash",
            contents=[types.Content(role="user", parts=[types.Part(text=full_prompt)])],
            config={
                "response_mime_type": "application/json"
            }
        )
        
        try:
            result = json.loads(response.text)
            answer = result.get("answer", response.text.strip())
            logger.info(f"AI Response Parsed: {result}")
            
            # Part A (status == 0) 처리
            if status == 0:
                username = result.get("username")
                chat_status = result.get("status")  # 'completed' or 'continue'
                action = result.get("action")
                
                if username:
                    save_username(request.session_id, username)
                    await classify_and_save(session_id=request.session_id, sender="I", part="A", text=answer)
                    return {"answer": answer, "thinking_process": None, "show_findgoal_button": True, "username": username, "status": chat_status, "action": action}
                else:
                    await classify_and_save(session_id=request.session_id, sender="I", part="A", text=answer)
                    return {"answer": answer, "thinking_process": None, "status": chat_status, "action": action}
            
            # Part B (status != 0) 처리 — A' パート
            else:
                # ★ AI가 판단한 start_daily_check 값을 있는 그대로 신뢰 (기존 하드코딩 override 제거)
                start_daily_check = result.get("start_daily_check", False)

                save_daily_log(request.session_id, "bot", answer)
                # Goalskill 분류: Part A'(같은 A파트), AI 응답
                await classify_and_save(session_id=request.session_id, sender="I", part="A", text=answer)
                
                # A' パート終了 = デイリーチェック誘導時 → 48テーブルから平均集計してresultに保存
                if start_daily_check:
                    current_daily = get_current_daily(request.session_id)
                    if current_daily > 0:
                        avg_score = get_avg_condition_score(request.session_id)
                        if avg_score is not None:
                            update_result_condition_score(request.session_id, current_daily, avg_score)
                            logger.info(f"[A' 완료] condition_score={avg_score} → result(daily={current_daily})")
                
                return {
                    "answer": answer, 
                    "thinking_process": None, 
                    "start_daily_check": start_daily_check
                }
                
        except json.JSONDecodeError:
            # JSON 파싱 실패 시 일반 텍스트로 처리 및 불필요한 괄호/따옴표 제거
            raw_text = response.text.strip()
            raw_text = re.sub(r'^```json\s*', '', raw_text)
            raw_text = re.sub(r'^```\s*', '', raw_text)
            raw_text = re.sub(r'```$', '', raw_text).strip()
            
            if raw_text.startswith('{') and '"answer"' in raw_text:
                match = re.search(r'"answer"\s*:\s*"(.*)"\s*}?$', raw_text, re.DOTALL)
                if match:
                    answer = match.group(1).strip()
                else:
                    answer = raw_text.replace('{"answer":', '').strip(' "\'{}\n\r\t')
            else:
                answer = raw_text
            
            if status == 0:
                save_chat_log(request.session_id, "bot", answer)
                save_to_chat_messages(request.session_id, answer, "I", "general")
                # Goalskill 분류: Part A, AI 응답 (JSON 파싱 실패 시)
                await classify_and_save(session_id=request.session_id, sender="I", part="A", text=answer)
            else:
                save_daily_log(request.session_id, "bot", answer)
                save_to_chat_messages(request.session_id, answer, "I", "condition")
                # Goalskill 분류: Part A', AI 응답 (JSON 파싱 실패 시)
                await classify_and_save(session_id=request.session_id, sender="I", part="A", text=answer)
            return {"answer": answer, "thinking_process": None}

    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))



# 2. 히스토리 불러오기 (mode 파라미터 제거)
@router.get("/history/{session_id}")
async def get_history(session_id: str):  # mode 제거
    try:
        rows = get_history_from_db(session_id)  # mode 제거
        return {"history": rows}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


# 3. 프론트엔드 로그 저장 (mode 파라미터 제거)
@router.post("/log")
async def log_message(req: LogRequest):
    try:
        save_chat_log(req.session_id, req.sender, req.message)  # req.mode 제거
        return {"status": "ok"}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

@router.get("/username/{session_id}")
async def get_username_api(session_id: str):
    username = get_username(session_id)
    return {"username": username}