from __future__ import annotations

import asyncio

import pytest
from fastapi import HTTPException
from sqlalchemy import create_engine
from sqlalchemy.orm import Session
from sqlalchemy.pool import StaticPool

from app.models import Base
from app.models.chat import ChatMessage, ChatSession, TopicSession
from app.models.entitlement import EntitlementPlan
from app.models.growth import TopicSummary, UserGrowthProfile
from app.models.user import User
from app.schemas.admin import AgentDebugRequest
from app.services.agent_debug_service import AgentDebugService


def _db() -> Session:
    engine = create_engine("sqlite:///:memory:", connect_args={"check_same_thread": False}, poolclass=StaticPool)
    Base.metadata.create_all(engine)
    return Session(engine)


def test_agent_debug_can_simulate_user_growth_profile_context():
    with _db() as db:
        user = User(id=1, phone="13800000001", name="测试学员", daily_chat_limit=100, daily_chat_used=0)
        db.add(user)
        db.add(
            EntitlementPlan(
                id=10,
                name="深度陪伴版",
                plan_type="deep",
                monthly_topic_limit=90,
                enable_growth_profile=1,
                status=1,
            )
        )
        db.add(
            UserGrowthProfile(
                user_id=1,
                schema_version=2,
                recent_review="最近谈到表达时不知道怎么回到当下。",
                current_focus="表达时先看见当下",
                profile_text="旧版画像不得注入",
            )
        )
        db.commit()

        result = asyncio.run(
            AgentDebugService.build_result(
                db,
                AgentDebugRequest(
                    promptContent="你是测试 Agent",
                    modelId=1,
                    userId=1,
                    question="我又表达不出来了怎么办",
                ),
            )
        )

        rendered = "\n".join(item["content"] for item in result.messages)
        assert "[近期实修回顾]" in rendered
        assert "表达时先看见当下" in rendered
        assert "旧版画像不得注入" not in rendered
        assert result.tool_trace[0]["tool"] == "load_debug_user_context"
        assert result.tool_trace[0]["response"]["recentPracticeReviewUsed"] is True
        assert "[当前产品权益]" in rendered


def test_agent_debug_loads_selected_topic_history_summary_and_permissions():
    with _db() as db:
        user = User(id=1, phone="13800000001", name="测试学员", daily_chat_limit=100, daily_chat_used=0)
        session = ChatSession(id=20, user_id=1, title="表达障碍", message_count=2, is_deleted=0)
        topic = TopicSession(
            id=30,
            user_id=1,
            chat_session_id=20,
            title="表达障碍练习",
            core_question="我在面对领导时不敢表达",
            status="completed",
            message_count=2,
        )
        db.add_all(
            [
                user,
                session,
                topic,
                EntitlementPlan(
                    id=10,
                    name="深度陪伴版",
                    plan_type="deep",
                    monthly_topic_limit=90,
                    enable_growth_profile=1,
                    allow_help_card=1,
                    allow_share_draft=0,
                    status=1,
                ),
                UserGrowthProfile(
                    user_id=1,
                    schema_version=2,
                    recent_review="最近谈到面对领导时不敢表达。",
                    current_focus="面对领导时的当下表达",
                    profile_text="",
                ),
                ChatMessage(
                    id=100,
                    session_id=20,
                    topic_session_id=30,
                    user_id=1,
                    role="user",
                    content="我又不敢说话了",
                ),
                ChatMessage(
                    id=101,
                    session_id=20,
                    topic_session_id=30,
                    user_id=1,
                    role="assistant",
                    content="先观察当下的身体感受。",
                ),
                TopicSummary(
                    topic_session_id=30,
                    user_id=1,
                    summary="学员正在观察面对权威时的紧绷。",
                    main_events="面对领导时如何表达",
                    emotions="害怕",
                    body_feelings="心口紧",
                    status="success",
                ),
            ]
        )
        db.commit()

        result = asyncio.run(
            AgentDebugService.build_result(
                db,
                AgentDebugRequest(
                    promptContent="你是测试 Agent",
                    modelId=1,
                    userId=1,
                    topicSessionId=30,
                    question="那我现在怎么继续？",
                    history=[{"role": "user", "content": "我想继续刚才的主题"}],
                ),
            )
        )

        rendered = "\n".join(item["content"] for item in result.messages)
        assert "[当前对话主题]" in rendered
        assert "[所选主题摘要]" in rendered
        assert "本次关注：面对领导时如何表达" in rendered
        assert "情绪：害怕" not in rendered
        assert "身体感受：心口紧" not in rendered
        assert "我又不敢说话了" in rendered
        assert "我想继续刚才的主题" in rendered
        assert "老师求助卡：可由学员主动生成" in rendered
        assert "班级分享稿：当前权益不可生成" in rendered
        context_response = result.tool_trace[0]["response"]
        assert context_response["topic"]["id"] == 30
        assert context_response["topic"]["loadedHistoryCount"] == 2
        assert context_response["topic"]["summaryUsed"] is True


def test_agent_debug_rejects_topic_from_another_user():
    with _db() as db:
        db.add_all(
            [
                User(id=1, phone="13800000001", name="学员A", daily_chat_limit=100, daily_chat_used=0),
                User(id=2, phone="13800000002", name="学员B", daily_chat_limit=100, daily_chat_used=0),
                ChatSession(id=20, user_id=2, title="B的会话", message_count=0, is_deleted=0),
                TopicSession(id=30, user_id=2, chat_session_id=20, title="B的主题", core_question="B的问题"),
            ]
        )
        db.commit()

        with pytest.raises(HTTPException) as exc:
            asyncio.run(
                AgentDebugService.build_result(
                    db,
                    AgentDebugRequest(
                        promptContent="你是测试 Agent",
                        modelId=1,
                        userId=1,
                        topicSessionId=30,
                        question="继续这个主题",
                    ),
                )
            )

        assert exc.value.status_code == 400
        assert exc.value.detail == "所选主题不属于当前模拟学员"
