"""MCP tool for getting custom report summary with aggregation.

This module implements the get_custom_report_summary tool following the service
layer pattern (ADR-006). The tool is a thin wrapper that:
1. Validates input with Pydantic
2. Extracts dependencies from server context (ADR-007)
3. Delegates to CustomReportService
4. Converts exceptions to user-friendly error format
"""

from typing import Annotated, Any, cast

from fastmcp import Context
from fastmcp.exceptions import ToolError
from pydantic import Field

from testio_mcp.server import ServerContext, mcp
from testio_mcp.services.custom_report_service import CustomReportService
from testio_mcp.utilities.parsing import parse_int_list_input, parse_list_input


@mcp.tool()
async def get_custom_report_summary(
    ctx: Context,
    test_ids: Annotated[
        list[int] | str | int,
        Field(
            description=(
                "Test IDs to aggregate reports for (required). "
                "Accepts: list [147162, 147163], single int 147162, "
                "comma-separated string '147162,147163'"
            ),
            examples=[[147162], "147162", "147162,147163"],
        ),
    ],
    group_by: Annotated[
        list[str] | str | None,
        Field(
            description=(
                "Fields to group by for cross-tabulation (max 2). "
                "Accepts: list ['course', 'intent'], comma-separated 'course,intent'"
            ),
            examples=[["course"], "course,intent"],
        ),
    ] = None,
    fields: Annotated[
        list[str] | str | None,
        Field(
            description=(
                "Specific report fields to include (defaults to all). "
                "Accepts: list ['accuracy', 'guardrails'], comma-separated 'accuracy,guardrails'"
            ),
            examples=[["accuracy", "guardrails"], "accuracy,guardrails"],
        ),
    ] = None,
) -> dict[str, Any]:
    """Aggregate custom report fields across test cycles.

    For each field, auto-detects type:
    - Numeric (>80% parseable as float): avg, min, max, distribution
    - Categorical (<=20 unique values): value counts
    - Text (everything else): count only, excluded from summary

    group_by supports cross-tabulation, e.g.:
    - group_by=["course"] -> per-course breakdown
    - group_by=["course", "intent"] -> course x intent matrix
    - group_by=["test"] -> per-test-cycle breakdown
    - group_by=["test", "course"] -> test x course matrix

    Returns structured summary suitable for executive report generation.
    """
    # Parse inputs
    parsed_test_ids = parse_int_list_input(test_ids)
    if not parsed_test_ids:
        raise ToolError(
            "❌ test_ids is required\n"
            "ℹ️  Provide at least one test ID\n"
            "💡 Use list_tests to find test IDs"
        )

    parsed_group_by = parse_list_input(group_by)
    if parsed_group_by and len(parsed_group_by) > 2:
        raise ToolError(
            "❌ group_by supports at most 2 dimensions\n"
            "ℹ️  Too many group_by fields provided\n"
            "💡 Use 1-2 fields, e.g. group_by=['course', 'intent']"
        )

    parsed_fields = parse_list_input(fields)

    # Create service with managed AsyncSession lifecycle
    assert ctx.request_context is not None
    server_ctx = cast(ServerContext, ctx.request_context.lifespan_context)
    cache = server_ctx["cache"]

    async with cache.async_session_maker() as session:
        service = CustomReportService(
            session=session,
            customer_id=cache.customer_id,
        )

        try:
            return await service.get_summary(
                test_ids=parsed_test_ids,
                group_by=parsed_group_by,
                fields=parsed_fields,
            )
        except Exception as e:
            raise ToolError(
                f"❌ Unexpected error: {str(e)}\n"
                f"ℹ️  An error occurred while aggregating custom reports\n"
                f"💡 Please try again or contact support if the problem persists"
            ) from e
