"""Metrics API 집계 · 보고서 생성 도구."""

import json
import logging
from datetime import datetime, timedelta, timezone
from pathlib import Path

from langchain.tools import tool

import sentinel.config as config
from sentinel.schema import ToolResult

# 하위 호환: report_service.py 등에서 이 모듈에서 import하던 것들을 유지
from sentinel.services.reporting import (  # noqa: F401
    REPORT_HTML_PROMPT,
    REPORT_MD_PROMPT,
    collect_report_data,
    load_template,
    strip_code_fence,
)

logger = logging.getLogger("sentinel.tools.metrics")


def _default_range(days_back: int = 7):
    """기본 날짜 범위를 반환합니다."""
    now = datetime.now(timezone.utc)
    return (
        (now - timedelta(days=days_back)).strftime("%Y-%m-%dT%H:%M:%SZ"),
        now.strftime("%Y-%m-%dT%H:%M:%SZ"),
    )


@tool
def query_metrics(
    view: str = "traces",
    metrics: str = "count,totalCost,latency",
    group_by: str = "name",
    period: str = "day",
    from_ts: str = "",
    to_ts: str = "",
    filter_name: str = "",
    filter_user_id: str = "",
    filter_environment: str = "",
    filter_release: str = "",
    filter_model: str = "",
) -> str:
    """Langfuse Metrics API로 집계 분석을 수행합니다.

    Args:
        view: 조회 대상 (traces, observations, scores-numeric)
        metrics: 집계 지표 (쉼표 구분: count, totalCost, latency, totalTokens)
        group_by: 그룹핑 차원 (name, environment, model 등)
        period: 시간 단위 (hour, day, week, month)
        from_ts: 시작 날짜 (ISO8601, 비우면 최근 7일)
        to_ts: 종료 날짜 (ISO8601, 비우면 현재)
        filter_name: 트레이스 이름 필터
        filter_user_id: 사용자 ID 필터
        filter_environment: 환경 필터 (e.g. production, staging)
        filter_release: 릴리스 필터
        filter_model: 모델 필터
    """
    if not from_ts or not to_ts:
        default_from, default_to = _default_range(7)
        from_ts = from_ts or default_from
        to_ts = to_ts or default_to

    agg_map = {
        "count": "count",
        "totalCost": "sum",
        "latency": "p50",
        "totalTokens": "sum",
    }
    metric_list = [
        {"measure": m.strip(), "aggregation": agg_map.get(m.strip(), "sum")}
        for m in metrics.split(",")
    ]

    q: dict = {
        "view": view,
        "dimensions": [{"field": group_by}],
        "metrics": metric_list,
        "timeDimension": {"granularity": period},
        "fromTimestamp": from_ts,
        "toTimestamp": to_ts,
        "filters": [],
        "orderBy": [],
        "rowLimit": 100,
    }
    if filter_name:
        q["filters"].append(
            {"column": "name", "operator": "equals", "value": filter_name, "type": "string"}
        )
    if filter_user_id:
        q["filters"].append(
            {"column": "userId", "operator": "equals", "value": filter_user_id, "type": "string"}
        )
    if filter_environment:
        q["filters"].append(
            {"column": "environment", "operator": "equals", "value": filter_environment, "type": "string"}
        )
    if filter_release:
        q["filters"].append(
            {"column": "release", "operator": "equals", "value": filter_release, "type": "string"}
        )
    if filter_model:
        q["filters"].append(
            {"column": "model", "operator": "equals", "value": filter_model, "type": "string"}
        )

    try:
        result = config.get_lf_client().api.metrics.metrics(query=json.dumps(q))
    except Exception as e:
        logger.exception("Metrics API 호출 실패")
        return ToolResult.fail(f"Langfuse Metrics API 오류: {e}").to_json()
    return ToolResult.ok(
        data=result,
        summary="Metrics API 조회 완료",
    ).to_json()


@tool
def generate_report(
    period: str = "daily",
    from_ts: str = "",
    to_ts: str = "",
    output_html: bool = False,
) -> str:
    """일간/주간/월간 LLMOps 보고서를 생성합니다. MD는 항상 저장되며 HTML은 옵션입니다.

    Args:
        period: 보고서 주기 (daily, weekly, monthly)
        from_ts: 시작 날짜 (ISO8601, 비우면 자동 계산)
        to_ts: 종료 날짜 (ISO8601, 비우면 오늘)
        output_html: True이면 HTML 보고서도 추가 생성
    """
    from sentinel.services.report_service import ReportService

    try:
        svc = ReportService()
        result = svc.generate(
            period=period,
            from_ts=from_ts,
            to_ts=to_ts,
            output_html=output_html,
        )
    except Exception as e:
        logger.exception("보고서 생성 실패")
        return ToolResult.fail(f"보고서 생성 실패: {e}").to_json()

    saved = [result.md_path]
    if result.html_path:
        saved.append(result.html_path)

    md_content = Path(result.md_path).read_text(encoding="utf-8")
    return ToolResult.ok(
        data={"paths": saved, "content": md_content},
        summary="보고서 저장 완료: " + ", ".join(saved),
    ).to_json()
