from sqlalchemy import create_engine
from datetime import datetime, timedelta
from sqlalchemy.orm import Session
from sqlalchemy.pool import StaticPool
from types import SimpleNamespace

from app.api.admin_agent_records import attention_list, retrieval_logs
from app.api.admin_records import ai_logs, chat_detail, chat_messages, question_insights, refresh_question_insights
from app.api.admin_users import list_users, user_operation_detail, user_topic_options
from app.models import Base
from app.models.chat import ChatMessage, ChatSession, TopicSession
from app.models.growth import TopicSummary
from app.models.insight import QuestionInsightCleanedQuestion
from app.models.knowledge import HumanAttentionRecord, KnowledgeRetrievalLog
from app.models.logs import AiRequestLog
from app.models.user import User


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


def test_user_list_uses_database_pagination():
    with _database() as db:
        db.add_all([
            User(id=i + 1, phone=f"1380000{i:04d}", name=f"学员{i}", daily_chat_limit=10)
            for i in range(25)
        ])
        db.commit()
        response = list_users(keyword="", page=2, pageSize=10, db=db, current_admin=object())
        assert response["data"]["total"] == 25
        assert response["data"]["page"] == 2
        assert len(response["data"]["items"]) == 10


def test_agent_preview_topic_options_are_lightweight_and_paginated():
    with _database() as db:
        user = User(id=1, phone="13800000000", name="学员", daily_chat_limit=10)
        db.add(user)
        topics = [
            TopicSession(
                id=index + 1,
                user_id=1,
                chat_session_id=100 + index,
                title=f"主题{index + 1}",
                core_question=f"核心问题{index + 1}",
                message_count=index,
            )
            for index in range(12)
        ]
        db.add_all(topics)
        db.flush()
        db.add(TopicSummary(topic_session_id=topics[-1].id, user_id=1, summary="只用于判断有无摘要", status="success"))
        db.commit()

        response = user_topic_options(1, keyword="", page=2, pageSize=10, db=db, current_admin=object())

        data = response["data"]
        assert data["total"] == 12
        assert data["page"] == 2
        assert len(data["items"]) == 2
        assert all("summary" not in item for item in data["items"])
        assert all("summaryAvailable" in item for item in data["items"])

        detail = user_operation_detail(1, db=db, current_admin=object())["data"]
        assert detail["user"]["id"] == 1
        assert detail["metrics"]["totalTopics"] == 12

        searched = user_topic_options(1, keyword="核心问题12", page=1, pageSize=10, db=db, current_admin=object())["data"]
        assert searched["total"] == 1
        assert searched["items"][0]["title"] == "主题12"


def test_ai_log_page_does_not_load_large_detail_fields():
    with _database() as db:
        db.add_all([
            AiRequestLog(status="success", prompt="p" * 5000, retrieved_chunks='[{"content":"large"}]')
            for _ in range(23)
        ])
        db.commit()
        response = ai_logs(sessionId=None, userId=None, status="", page=2, pageSize=10, db=db, current_admin=object())
        assert response["data"]["total"] == 23
        assert len(response["data"]["items"]) == 10
        assert all(item["retrievedChunks"] == [] for item in response["data"]["items"])


def test_chat_detail_messages_are_paginated():
    with _database() as db:
        user = User(id=1, phone="13800000000", name="学员", daily_chat_limit=10)
        session = ChatSession(id=1, user_id=1, title="长会话", message_count=25)
        db.add_all([user, session])
        db.add_all([
            ChatMessage(id=index + 1, session_id=1, user_id=1, role="user", content=f"消息{index + 1}")
            for index in range(25)
        ])
        db.commit()

        response = chat_detail(1, messagePage=2, messagePageSize=10, db=db, current_admin=object())

        data = response["data"]
        assert data["session"]["messageCount"] == 25
        assert data["messagesPage"]["total"] == 25
        assert data["messagesPage"]["page"] == 2
        assert len(data["messages"]) == 10
        assert data["messages"][0]["content"] == "消息11"


def test_chat_messages_endpoint_returns_only_message_page():
    with _database() as db:
        user = User(id=1, phone="13800000000", name="学员", daily_chat_limit=10)
        session = ChatSession(id=1, user_id=1, title="长会话", message_count=12)
        db.add_all([user, session])
        db.add_all([
            ChatMessage(id=index + 1, session_id=1, user_id=1, role="user", content=f"消息{index + 1}")
            for index in range(12)
        ])
        db.add(AiRequestLog(session_id=1, status="success", prompt="p" * 5000, retrieved_chunks='[{"content":"large"}]'))
        db.commit()

        response = chat_messages(1, page=2, pageSize=10, db=db, current_admin=object())

        data = response["data"]
        assert data["total"] == 12
        assert len(data["items"]) == 2
        assert data["items"][0]["content"] == "消息11"
        assert "aiLogs" not in data


def test_retrieval_and_attention_lists_are_paginated():
    with _database() as db:
        for index in range(21):
            db.add(KnowledgeRetrievalLog(
                question=f"q{index}", catalog_snapshot="[]", catalog_hash=str(index),
                safety_rule_version="v1", status="success",
            ))
            db.add(HumanAttentionRecord(
                session_id=index + 1, message_id=index + 1, user_id=index + 1,
                trigger_message="test", problem_summary="test", trigger_reason="test",
                priority="normal", status="pending",
            ))
        db.commit()
        retrieval = retrieval_logs(
            sessionId=None, knowledgeId=None, knowledgeCalled=None, statusValue="", attentionCreated=None,
            page=3, pageSize=10, db=db, current_admin=object(),
        )["data"]
        attention = attention_list(priority="", statusValue="", page=3, pageSize=10, db=db, current_admin=object())["data"]
        assert retrieval["total"] == attention["total"] == 21
        assert len(retrieval["items"]) == len(attention["items"]) == 1


def test_question_insights_clean_and_cluster_similar_user_questions():
    with _database() as db:
        user_a = User(id=1, phone="13800000000", name="学员A", daily_chat_limit=10)
        user_b = User(id=2, phone="13800000001", name="学员B", daily_chat_limit=10)
        session_a = ChatSession(id=1, user_id=1, title="问题", message_count=3)
        session_b = ChatSession(id=2, user_id=2, title="问题", message_count=2)
        now = datetime(2026, 7, 31, 10, 0, 0)
        db.add_all([user_a, user_b, session_a, session_b])
        db.add_all(
            [
                ChatMessage(id=1, session_id=1, user_id=1, role="user", content="老师你好，心光有哪些作业？", created_at=now),
                ChatMessage(id=2, session_id=1, user_id=1, role="assistant", content="回答", created_at=now + timedelta(seconds=1)),
                ChatMessage(id=3, session_id=2, user_id=2, role="user", content="请问心光都有什么功课", created_at=now + timedelta(minutes=1)),
                ChatMessage(id=4, session_id=2, user_id=2, role="user", content="谢谢老师", created_at=now + timedelta(minutes=2)),
                ChatMessage(id=5, session_id=1, user_id=1, role="user", content="1、回放在哪里看？\n2、上课链接在哪", created_at=now + timedelta(minutes=3)),
            ]
        )
        db.add(AiRequestLog(session_id=1, user_id=1, status="SUCCESS", prompt="用户问题：心光有哪些作业？", knowledge_hit=0))
        db.commit()

        first_refresh = refresh_question_insights(
            dateFrom=None,
            dateTo=None,
            maxMessages=100,
            db=db,
            current_admin=SimpleNamespace(id=1),
        )["data"]
        second_refresh = refresh_question_insights(
            dateFrom=None,
            dateTo=None,
            maxMessages=100,
            db=db,
            current_admin=SimpleNamespace(id=1),
        )["data"]
        response = question_insights(
            dateFrom=None,
            dateTo=None,
            minCount=2,
            maxMessages=100,
            page=1,
            pageSize=10,
            db=db,
            current_admin=object(),
        )

        data = response["data"]
        assert first_refresh["processedMessages"] == 4
        assert first_refresh["acceptedQuestions"] == 4
        assert first_refresh["filteredMessages"] == 1
        assert second_refresh["processedMessages"] == 0
        assert db.query(QuestionInsightCleanedQuestion).count() == 5
        assert data["summary"]["scannedMessages"] == 4
        assert data["summary"]["filteredMessages"] == 1
        assert data["summary"]["cleanedQuestions"] == 4
        assert data["total"] == 1
        assert data["items"][0]["count"] == 2
        assert "心光" in data["items"][0]["title"]
        assert data["items"][0]["userCount"] == 2
        assert data["items"][0]["category"] == "homework"
        assert data["items"][0]["noHitCount"] == 1
        assert data["items"][0]["needsKnowledgeFollowUp"] is True
