"""Trend analysis: period comparisons and drop detection."""

from __future__ import annotations

import logging

from src.models.data_models import SearchMetrics, TrendComparison

logger = logging.getLogger("seo_optimizer")

# Drop thresholds for alert detection
DROP_THRESHOLD_PCT = -20.0  # 20% drop triggers alert


def calculate_change_pct(current: float, previous: float) -> float:
    """Calculate percentage change from previous to current.

    Returns:
        Change as percentage (e.g., -25.0 means 25% decrease).
        Returns 0.0 if previous is 0.
    """
    if previous == 0:
        return 0.0
    return round(((current - previous) / previous) * 100, 2)


def compare_periods(
    current: SearchMetrics,
    previous: SearchMetrics,
    period_label: str,
) -> TrendComparison:
    """Compare two periods and produce a TrendComparison.

    Args:
        current: Metrics for the current period.
        previous: Metrics for the previous period.
        period_label: Human-readable label (e.g., "前日比", "7日比").

    Returns:
        TrendComparison with change percentages.
    """
    return TrendComparison(
        period_label=period_label,
        current=current,
        previous=previous,
        clicks_change_pct=calculate_change_pct(current.clicks, previous.clicks),
        impressions_change_pct=calculate_change_pct(
            current.impressions, previous.impressions
        ),
        ctr_change_pct=calculate_change_pct(current.ctr, previous.ctr),
        position_change=round(current.position - previous.position, 2),
    )


def detect_drops(
    trends: list[TrendComparison],
    site_name: str = "",
    threshold_pct: float = DROP_THRESHOLD_PCT,
) -> list[str]:
    """Check trends for significant drops.

    Args:
        trends: List of TrendComparison objects.
        site_name: Site name for logging.
        threshold_pct: Negative percentage threshold (e.g., -20.0).

    Returns:
        List of alert messages for detected drops.
    """
    alerts = []

    for trend in trends:
        if trend.clicks_change_pct <= threshold_pct:
            msg = (
                f"[{trend.period_label}] クリック数が急落: "
                f"{trend.previous.clicks} → {trend.current.clicks} "
                f"({trend.clicks_change_pct:+.1f}%)"
            )
            alerts.append(msg)
            logger.warning("[%s] %s", site_name, msg)

        if trend.impressions_change_pct <= threshold_pct:
            msg = (
                f"[{trend.period_label}] 表示回数が急落: "
                f"{trend.previous.impressions} → {trend.current.impressions} "
                f"({trend.impressions_change_pct:+.1f}%)"
            )
            alerts.append(msg)
            logger.warning("[%s] %s", site_name, msg)

        # Position increase (worse) by more than 2.0
        if trend.position_change > 2.0:
            msg = (
                f"[{trend.period_label}] 平均順位が悪化: "
                f"{trend.previous.position:.1f} → {trend.current.position:.1f} "
                f"({trend.position_change:+.1f})"
            )
            alerts.append(msg)
            logger.warning("[%s] %s", site_name, msg)

    if not alerts:
        logger.info("[%s] No significant drops detected", site_name)

    return alerts
