"""분석 관련 MCP Tools."""

from __future__ import annotations

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from ..core.async_client import AsyncBigKindsClient
    from ..core.cache import MCPCache

# 전역 인스턴스
_client: AsyncBigKindsClient | None = None
_cache: MCPCache | None = None


def init_analysis_tools(client: AsyncBigKindsClient, cache: MCPCache) -> None:
    """분석 도구 초기화."""
    global _client, _cache
    _client = client
    _cache = cache


async def compare_keywords(
    keywords: list[str],
    start_date: str,
    end_date: str,
    group_by: str = "day",
) -> dict:
    """
    여러 키워드의 뉴스 트렌드를 비교 분석합니다.

    Args:
        keywords: 비교할 키워드 목록 (2-5개 권장)
        start_date: 검색 시작일 (YYYY-MM-DD)
        end_date: 검색 종료일 (YYYY-MM-DD)
        group_by: 집계 단위
            - "total": 전체 기간 총합
            - "day": 일별 집계 (최대 31일 권장)
            - "week": 주별 집계
            - "month": 월별 집계

    Returns:
        키워드 비교 결과:
            - keywords: 비교 키워드 목록
            - date_range: 분석 기간
            - comparisons: 키워드별 결과
                - keyword: 키워드
                - total_count: 총 기사 수
                - counts: 기간별 기사 수 (group_by != "total"인 경우)
                - rank: 순위 (기사 수 기준)
            - summary: 분석 요약
                - most_popular: 가장 많은 키워드
                - least_popular: 가장 적은 키워드
                - total_articles: 전체 기사 수

    Example:
        >>> result = await compare_keywords(
        ...     keywords=["AI", "반도체", "전기차"],
        ...     start_date="2025-12-01",
        ...     end_date="2025-12-15",
        ...     group_by="day"
        ... )
        >>> print(result["summary"]["most_popular"])
        {"keyword": "AI", "count": 15432}
    """
    if _client is None or _cache is None:
        raise RuntimeError("Analysis tools not initialized")

    # 입력 검증
    if not keywords or len(keywords) < 2:
        return {
            "success": False,
            "error": "INVALID_PARAMS",
            "message": "최소 2개 이상의 키워드가 필요합니다.",
        }

    if len(keywords) > 10:
        return {
            "success": False,
            "error": "INVALID_PARAMS",
            "message": "키워드는 최대 10개까지 지원합니다.",
        }

    # 각 키워드별로 get_article_count 호출
    from .search import get_article_count

    results = []
    for keyword in keywords:
        result = await get_article_count(
            keyword=keyword,
            start_date=start_date,
            end_date=end_date,
            group_by=group_by,
        )

        if result.get("success", False):
            results.append({
                "keyword": keyword,
                "total_count": result["total_count"],
                "counts": result.get("counts", []),
            })
        else:
            # 에러가 발생한 키워드는 0건으로 처리
            results.append({
                "keyword": keyword,
                "total_count": 0,
                "counts": [],
                "error": result.get("message", "조회 실패"),
            })

    # 기사 수 기준 정렬 및 순위 부여
    results.sort(key=lambda x: x["total_count"], reverse=True)
    for i, result in enumerate(results, 1):
        result["rank"] = i

    # 요약 정보
    total_articles = sum(r["total_count"] for r in results)
    most_popular = results[0] if results else None
    least_popular = results[-1] if results else None

    return {
        "success": True,
        "keywords": keywords,
        "date_range": f"{start_date} to {end_date}",
        "group_by": group_by,
        "comparisons": results,
        "summary": {
            "most_popular": {
                "keyword": most_popular["keyword"],
                "count": most_popular["total_count"],
            } if most_popular else None,
            "least_popular": {
                "keyword": least_popular["keyword"],
                "count": least_popular["total_count"],
            } if least_popular else None,
            "total_articles": total_articles,
            "average_count": total_articles // len(results) if results else 0,
        },
    }


async def smart_sample(
    keyword: str,
    start_date: str,
    end_date: str,
    sample_size: int = 100,
    strategy: str = "stratified",
) -> dict:
    """
    대용량 검색 결과에서 대표 샘플을 추출합니다.

    Args:
        keyword: 검색 키워드
        start_date: 검색 시작일 (YYYY-MM-DD)
        end_date: 검색 종료일 (YYYY-MM-DD)
        sample_size: 추출할 샘플 수 (기본값: 100, 최대: 500)
        strategy: 샘플링 전략
            - "stratified": 기간별 균등 분포 (기본값)
            - "latest": 최신 기사 우선
            - "random": 무작위 샘플링

    Returns:
        샘플링 결과:
            - success: 성공 여부
            - keyword: 검색 키워드
            - total_count: 전체 기사 수
            - sample_size: 추출된 샘플 수
            - strategy: 사용된 전략
            - articles: 샘플 기사 목록
            - coverage: 샘플링 커버리지 정보

    Example:
        대용량 데이터(112만 건)에서 대표 100건 추출:
        >>> result = await smart_sample(
        ...     keyword="이재명",
        ...     start_date="2005-01-01",
        ...     end_date="2025-12-15",
        ...     sample_size=100,
        ...     strategy="stratified"
        ... )
        >>> print(f"{result['total_count']}건 → {result['sample_size']}건")
    """
    if _client is None or _cache is None:
        raise RuntimeError("Analysis tools not initialized")

    # 입력 검증
    if sample_size > 500:
        return {
            "success": False,
            "error": "INVALID_PARAMS",
            "message": "sample_size는 최대 500까지 지원합니다.",
        }

    from .search import search_news, get_article_count

    # 1단계: 전체 기사 수 확인
    count_result = await get_article_count(
        keyword=keyword,
        start_date=start_date,
        end_date=end_date,
        group_by="total",
    )

    if not count_result.get("success", False):
        return count_result  # 에러 반환

    total_count = count_result["total_count"]

    # 2단계: 전략별 샘플링
    if strategy == "stratified":
        # 기간을 균등 분할하여 샘플링
        from datetime import datetime, timedelta

        start = datetime.strptime(start_date, "%Y-%m-%d")
        end = datetime.strptime(end_date, "%Y-%m-%d")
        total_days = (end - start).days + 1

        # 샘플 구간 수 (최대 20개 구간)
        num_intervals = min(20, sample_size // 5)
        samples_per_interval = sample_size // num_intervals

        articles = []
        for i in range(num_intervals):
            # 구간 계산
            interval_days = total_days // num_intervals
            interval_start = start + timedelta(days=i * interval_days)
            interval_end = start + timedelta(days=(i + 1) * interval_days - 1)
            if i == num_intervals - 1:
                interval_end = end  # 마지막 구간은 끝까지

            # 구간별 검색
            result = await search_news(
                keyword=keyword,
                start_date=interval_start.strftime("%Y-%m-%d"),
                end_date=interval_end.strftime("%Y-%m-%d"),
                page_size=samples_per_interval,
                sort_by="date",
            )

            if result.get("success", False):
                articles.extend(result["articles"])

    elif strategy == "latest":
        # 최신 기사 우선
        result = await search_news(
            keyword=keyword,
            start_date=start_date,
            end_date=end_date,
            page_size=sample_size,
            sort_by="date",
        )

        if not result.get("success", False):
            return result

        articles = result["articles"]

    elif strategy == "random":
        # 무작위 페이지에서 샘플링
        import random

        page_size = 20
        max_pages = min(total_count // page_size, 50)  # 최대 50페이지

        articles = []
        pages_to_sample = random.sample(range(1, max_pages + 1), min(sample_size // page_size, max_pages))

        for page in pages_to_sample:
            result = await search_news(
                keyword=keyword,
                start_date=start_date,
                end_date=end_date,
                page=page,
                page_size=page_size,
                sort_by="date",
            )

            if result.get("success", False):
                articles.extend(result["articles"])

    else:
        return {
            "success": False,
            "error": "INVALID_PARAMS",
            "message": f"지원하지 않는 전략: {strategy}",
        }

    # 중복 제거 (news_id 기준)
    seen_ids = set()
    unique_articles = []
    for article in articles:
        news_id = article.get("news_id")
        if news_id and news_id not in seen_ids:
            seen_ids.add(news_id)
            unique_articles.append(article)

    return {
        "success": True,
        "keyword": keyword,
        "date_range": f"{start_date} to {end_date}",
        "total_count": total_count,
        "sample_size": len(unique_articles),
        "strategy": strategy,
        "articles": unique_articles[:sample_size],  # 요청 크기만큼만 반환
        "coverage": {
            "ratio": len(unique_articles) / total_count if total_count > 0 else 0,
            "description": f"{total_count:,}건 중 {len(unique_articles):,}건 샘플링",
        },
    }


def cache_stats() -> dict:
    """
    캐시 통계 정보를 조회합니다.

    Returns:
        캐시 통계:
            - search: 검색 캐시 통계
                - size: 현재 크기
                - maxsize: 최대 크기
                - usage_percent: 사용률
            - article: 기사 캐시 통계
            - count: 카운트 캐시 통계
            - generic: 일반 캐시 통계
            - url: URL 매핑 캐시 통계

    Example:
        >>> stats = cache_stats()
        >>> print(f"검색 캐시 사용률: {stats['search']['usage_percent']:.1f}%")
    """
    if _cache is None:
        raise RuntimeError("Analysis tools not initialized")

    raw_stats = _cache.stats()

    # 사용률 계산
    def add_usage(stat):
        size = stat["size"]
        maxsize = stat["maxsize"]
        stat["usage_percent"] = (size / maxsize * 100) if maxsize > 0 else 0
        return stat

    return {
        "search": add_usage(raw_stats["search"]),
        "article": add_usage(raw_stats["article"]),
        "count": add_usage(raw_stats["count"]),
        "generic": add_usage(raw_stats["generic"]),
    }
