"""Input validation utilities for scorecard operations."""

from __future__ import annotations

from datetime import UTC, datetime, timedelta
from typing import TYPE_CHECKING

from dashboard.services.scorecard.types import TRACKED_AGENTS, PeriodType

if TYPE_CHECKING:
    from infrastructure.events.bus import Event


def is_tracked_agent(actor: str) -> bool:
    """Check if an actor is a tracked agent."""
    return actor.lower() in TRACKED_AGENTS


def extract_actor_from_event(event: Event) -> str:
    """Extract the actor/agent from an event."""
    # Try data fields first
    if "actor" in event.data:
        return event.data["actor"]
    if "agent_id" in event.data:
        return event.data["agent_id"]
    # Fall back to source
    return event.source


def get_period_bounds(
    period_type: PeriodType, reference_date: datetime | None = None
) -> tuple[datetime, datetime]:
    """Calculate start and end timestamps for a period.

    Args:
        period_type: daily or weekly
        reference_date: The date to calculate from (defaults to now)

    Returns:
        Tuple of (period_start, period_end) in UTC
    """
    if reference_date is None:
        reference_date = datetime.now(UTC)

    # Normalize to start of day
    end = reference_date.replace(hour=0, minute=0, second=0, microsecond=0)

    if period_type == PeriodType.daily:
        start = end - timedelta(days=1)
    else:  # weekly
        start = end - timedelta(days=7)

    return start, end


def validate_period_type(period: str) -> PeriodType:
    """Validate and convert a period string to PeriodType.

    Args:
        period: The period string to validate

    Returns:
        PeriodType enum value

    Raises:
        ValueError: If the period string is invalid
    """
    try:
        return PeriodType(period.lower())
    except ValueError as exc:
        raise ValueError(f"Invalid period '{period}'. Use 'daily' or 'weekly'.") from exc
