"""KPI aggregation and threshold checking."""

from __future__ import annotations

import logging

from src.config.settings import KPIThresholds
from src.models.data_models import KPIAlert, SearchMetrics

logger = logging.getLogger("seo_optimizer")


def check_kpi_thresholds(
    metrics: SearchMetrics,
    thresholds: KPIThresholds,
    site_name: str = "",
) -> list[KPIAlert]:
    """Check metrics against KPI thresholds and return alerts for violations.

    Args:
        metrics: Current search metrics.
        thresholds: KPI threshold configuration.
        site_name: Site display name for log messages.

    Returns:
        List of KPIAlert for each threshold violation.
    """
    alerts = []

    if metrics.clicks < thresholds.min_clicks:
        alert = KPIAlert(
            metric_name="clicks",
            current_value=metrics.clicks,
            threshold_value=thresholds.min_clicks,
            message=f"クリック数が閾値を下回っています: {metrics.clicks} < {thresholds.min_clicks}",
        )
        alerts.append(alert)
        logger.warning("[%s] %s", site_name, alert.message)

    if metrics.impressions < thresholds.min_impressions:
        alert = KPIAlert(
            metric_name="impressions",
            current_value=metrics.impressions,
            threshold_value=thresholds.min_impressions,
            message=f"表示回数が閾値を下回っています: {metrics.impressions} < {thresholds.min_impressions}",
        )
        alerts.append(alert)
        logger.warning("[%s] %s", site_name, alert.message)

    if metrics.ctr < thresholds.min_ctr:
        alert = KPIAlert(
            metric_name="ctr",
            current_value=metrics.ctr,
            threshold_value=thresholds.min_ctr,
            message=(
                f"CTRが閾値を下回っています: {metrics.ctr:.2%} < {thresholds.min_ctr:.2%}"
            ),
        )
        alerts.append(alert)
        logger.warning("[%s] %s", site_name, alert.message)

    if metrics.position > thresholds.max_position:
        alert = KPIAlert(
            metric_name="position",
            current_value=metrics.position,
            threshold_value=thresholds.max_position,
            message=(
                f"平均順位が閾値を超えています: {metrics.position:.1f} > {thresholds.max_position:.1f}"
            ),
        )
        alerts.append(alert)
        logger.warning("[%s] %s", site_name, alert.message)

    if not alerts:
        logger.info("[%s] All KPIs within thresholds", site_name)

    return alerts


def calculate_index_rate(checked: int, indexed: int) -> float:
    """Calculate index rate from checked and indexed counts."""
    if checked == 0:
        return 0.0
    return round(indexed / checked, 4)


def check_index_rate(
    checked: int,
    indexed: int,
    thresholds: KPIThresholds,
    site_name: str = "",
) -> KPIAlert | None:
    """Check index rate against threshold. Returns alert if below threshold."""
    rate = calculate_index_rate(checked, indexed)

    if rate < thresholds.min_index_rate:
        alert = KPIAlert(
            metric_name="index_rate",
            current_value=rate,
            threshold_value=thresholds.min_index_rate,
            message=(
                f"インデックス率が閾値を下回っています: {rate:.1%} < {thresholds.min_index_rate:.1%} "
                f"({indexed}/{checked}ページ)"
            ),
        )
        logger.warning("[%s] %s", site_name, alert.message)
        return alert

    return None
