"""Scorecard type definitions and data classes."""

from __future__ import annotations

from dataclasses import dataclass, field
from enum import StrEnum
from typing import Any


class PeriodType(StrEnum):
    """Scorecard reporting period type."""

    daily = "daily"
    weekly = "weekly"


# Bot/agent usernames to track
TRACKED_AGENTS = frozenset({"hermes", "kimi", "manus", "claude", "gemini"})


@dataclass
class AgentMetrics:
    """Raw metrics collected for an agent over a period."""

    agent_id: str
    issues_touched: set[int] = field(default_factory=set)
    prs_opened: set[int] = field(default_factory=set)
    prs_merged: set[int] = field(default_factory=set)
    tests_affected: set[str] = field(default_factory=set)
    tokens_earned: int = 0
    tokens_spent: int = 0
    commits: int = 0
    comments: int = 0

    @property
    def pr_merge_rate(self) -> float:
        """Calculate PR merge rate (0.0 - 1.0)."""
        opened = len(self.prs_opened)
        if opened == 0:
            return 0.0
        return len(self.prs_merged) / opened


@dataclass
class ScorecardSummary:
    """A generated scorecard with narrative summary."""

    agent_id: str
    period_type: PeriodType
    period_start: datetime
    period_end: datetime
    metrics: AgentMetrics
    narrative_bullets: list[str] = field(default_factory=list)
    patterns: list[str] = field(default_factory=list)

    def to_dict(self) -> dict[str, Any]:
        """Convert scorecard to dictionary for JSON serialization."""
        return {
            "agent_id": self.agent_id,
            "period_type": self.period_type.value,
            "period_start": self.period_start.isoformat(),
            "period_end": self.period_end.isoformat(),
            "metrics": {
                "issues_touched": len(self.metrics.issues_touched),
                "prs_opened": len(self.metrics.prs_opened),
                "prs_merged": len(self.metrics.prs_merged),
                "pr_merge_rate": round(self.metrics.pr_merge_rate, 2),
                "tests_affected": len(self.tests_affected),
                "commits": self.metrics.commits,
                "comments": self.metrics.comments,
                "tokens_earned": self.metrics.tokens_earned,
                "tokens_spent": self.metrics.tokens_spent,
                "token_net": self.metrics.tokens_earned - self.metrics.tokens_spent,
            },
            "narrative_bullets": self.narrative_bullets,
            "patterns": self.patterns,
        }

    @property
    def tests_affected(self) -> set[str]:
        """Alias for metrics.tests_affected."""
        return self.metrics.tests_affected


# Import datetime here to avoid issues with forward references
from datetime import datetime  # noqa: E402
