"""Exploration findings aggregation (探索发现聚合).

把探索会话的体验记录聚合成探索摘要：会话数、目标达成率、问题清单
（blockers / misled 按出现次数降序）、judge 复核结论（已就位才纳入；
findings 全量收各档发现，poor 档排前）。这是体验记录这条第一手证据线
进入报告 / 分析 / 导出三个出口前的唯一聚合口径；只含统计与问题清单，
不含全量对话。
"""

from collections import Counter
from typing import Any, Optional

from sqlmodel import Session

from agenteval.exploration.models import ExplorationSession

_RATING_SEVERITY = {"poor": 0, "acceptable": 1, "good": 2}


def _issue_list(counter: Counter) -> list[dict[str, Any]]:
    return [{"issue": issue, "count": count} for issue, count in counter.most_common()]


def summarize_exploration(sessions: list[ExplorationSession]) -> Optional[dict[str, Any]]:
    """聚合一组探索会话为探索摘要；无会话返回 None（缺则无痕）。"""
    if not sessions:
        return None

    with_experience = [s for s in sessions if s.experience is not None]
    blockers: Counter = Counter()
    misled: Counter = Counter()
    achieved = 0
    for session_obj in with_experience:
        experience = session_obj.experience
        if experience.get("goal_achieved"):
            achieved += 1
        blockers.update(experience.get("blockers") or [])
        misled.update(experience.get("misled") or [])

    judge = _summarize_judge_reviews(sessions)

    return {
        "session_count": len(sessions),
        "sessions_with_experience": len(with_experience),
        "goal_achieved_count": achieved,
        "goal_achievement_rate": round(achieved / len(with_experience), 4) if with_experience else None,
        "issues": _issue_list(blockers),
        "misled": _issue_list(misled),
        "judge_review": judge,
    }


def summarize_campaign_exploration(db_session: Session, campaign_id: str) -> Optional[dict[str, Any]]:
    """取数 + 聚合一步完成：报告 / 分析 / 导出三个出口共用的探索摘要取法。"""
    from agenteval.storage.repository import ExplorationSessionRepository

    return summarize_exploration(ExplorationSessionRepository(db_session).list_by_campaign(campaign_id))


def _summarize_judge_reviews(sessions: list[ExplorationSession]) -> Optional[dict[str, Any]]:
    """只纳入复核完成的会话；findings 全量收各档发现（poor 档排前），
    summaries 收复核总体结论。"""
    findings: list[dict[str, Any]] = []
    summaries: list[str] = []
    reviewed = 0
    for session_obj in sessions:
        review = session_obj.judge_review
        if not review or review.get("status") != "completed":
            continue
        reviewed += 1
        if review.get("summary"):
            summaries.append(str(review["summary"]))
        for item in review.get("dimensions") or []:
            findings.append(
                {
                    "dimension": item.get("dimension"),
                    "rating": item.get("rating"),
                    "comment": item.get("comment") or "",
                }
            )
    if reviewed == 0:
        return None
    findings.sort(key=lambda f: _RATING_SEVERITY.get(f["rating"], len(_RATING_SEVERITY)))
    return {"reviewed_sessions": reviewed, "findings": findings, "summaries": summaries}
