from typing import Dict, Optional
"""
Provider month tracking for detailed progress visibility.
"""

import time

from .core import FailSafeLogger
from .performance import PerformanceLogger


class ProviderMonthLogger:
    """
    Specialized logger for tracking provider month progress.

    Provides detailed visibility into data generation across provider/month combinations.
    """

    def __init__(self, logger: FailSafeLogger):
        self.logger = logger
        self.perf_logger = PerformanceLogger(logger)
        self._active_months = {}  # Track timing for in-progress months

    def start_provider_month(
        self,
        provider: str,
        month: str,
        target_cost: Optional[float] = None,
        target_rows: Optional[int] = None,
        **context,
    ):
        """Log the start of provider month processing."""
        month_key = f"{provider}/{month}"
        self._active_months[month_key] = {
            "start_time": time.time(),
            "provider": provider,
            "month": month,
            "target_cost": target_cost,
            "target_rows": target_rows,
        }

        start_context = {"provider": provider, "month": month}
        if target_cost is not None:
            start_context["target_cost"] = target_cost
        if target_rows is not None:
            start_context["target_rows"] = target_rows
        start_context.update(context)

        self.logger.info("Provider month started", **start_context)

    def complete_provider_month(
        self,
        provider: str,
        month: str,
        actual_cost: Optional[float] = None,
        actual_rows: Optional[int] = None,
        **context,
    ):
        """Log the completion of provider month processing."""
        month_key = f"{provider}/{month}"

        # Calculate duration if we tracked the start
        duration_ms = None
        if month_key in self._active_months:
            start_info = self._active_months.pop(month_key)
            duration_ms = (time.time() - start_info["start_time"]) * 1000

        complete_context = {"provider": provider, "month": month}
        if actual_cost is not None:
            complete_context["actual_cost"] = actual_cost
        if actual_rows is not None:
            complete_context["actual_rows"] = actual_rows
        if duration_ms is not None:
            complete_context["duration_ms"] = duration_ms
        complete_context.update(context)

        # Log completion
        if duration_ms is not None:
            formatted_duration = self.perf_logger._format_duration(duration_ms)
            self.logger.info(
                f"Provider month completed in {formatted_duration}", **complete_context
            )
        else:
            self.logger.info("Provider month completed", **complete_context)

    def log_provider_month_progress(
        self,
        provider: str,
        month: str,
        progress_pct: float,
        current_rows: Optional[int] = None,
        current_cost: Optional[float] = None,
        **context,
    ):
        """Log progress update for a provider month."""
        progress_context = {
            "provider": provider,
            "month": month,
            "progress_pct": progress_pct,
        }
        if current_rows is not None:
            progress_context["current_rows"] = current_rows
        if current_cost is not None:
            progress_context["current_cost"] = current_cost
        progress_context.update(context)

        self.logger.debug(
            f"Provider month progress: {progress_pct:.1f}%", **progress_context
        )

    def log_provider_month_batch(
        self,
        provider: str,
        month: str,
        batch_size: int,
        batch_cost: Optional[float] = None,
        **context,
    ):
        """Log a batch of data processed for a provider month."""
        batch_context = {"provider": provider, "month": month, "batch_size": batch_size}
        if batch_cost is not None:
            batch_context["batch_cost"] = batch_cost
        batch_context.update(context)

        self.logger.debug("Provider month batch processed", **batch_context)

    def log_provider_month_error(
        self, provider: str, month: str, error: str, **context
    ):
        """Log an error during provider month processing."""
        error_context = {"provider": provider, "month": month, "error": error}
        error_context.update(context)

        self.logger.error(f"Provider month error: {error}", **error_context)

    def log_provider_summary(
        self,
        provider: str,
        total_months: int,
        total_cost: Optional[float] = None,
        total_rows: Optional[int] = None,
        duration_ms: Optional[float] = None,
        **context,
    ):
        """Log summary for all months of a provider."""
        summary_context = {"provider": provider, "total_months": total_months}
        if total_cost is not None:
            summary_context["total_cost"] = total_cost
        if total_rows is not None:
            summary_context["total_rows"] = total_rows
        if duration_ms is not None:
            summary_context["duration_ms"] = duration_ms
        summary_context.update(context)

        if duration_ms is not None:
            formatted_duration = self.perf_logger._format_duration(duration_ms)
            self.logger.info(
                f"Provider completed: {total_months} months in {formatted_duration}",
                **summary_context,
            )
        else:
            self.logger.info(
                f"Provider completed: {total_months} months", **summary_context
            )

    def get_active_months(self) -> Dict[str, dict]:
        """Get information about currently active provider months."""
        return self._active_months.copy()

    def cleanup_stale_months(self, max_age_seconds: float = 3600):
        """Clean up tracking for months that have been active too long."""
        current_time = time.time()
        stale_keys = []

        for month_key, info in self._active_months.items():
            if current_time - info["start_time"] > max_age_seconds:
                stale_keys.append(month_key)

        for key in stale_keys:
            stale_info = self._active_months.pop(key)
            self.logger.warning(
                "Cleaned up stale provider month tracking",
                provider=stale_info["provider"],
                month=stale_info["month"],
                age_seconds=current_time - stale_info["start_time"],
            )
