"""Configuration classes for unit metrics generation."""

from dataclasses import dataclass
from pathlib import Path
from typing import (
    Dict,
    List,
    Literal,
    Optional,
)

import yaml

from ..patterns import (
    AnomalyConfig,
    MetricScale,
    SeasonalityConfig,
    TrendConfig,
)


@dataclass
class DataConfig:
    """Configuration for individual metric data generation."""

    name: str
    start_date: str
    end_date: str
    scale: str  # Will be converted to MetricScale enum
    group_filters: Dict[str, List[str]] | None = None
    frequency: Literal["D", "M"] = "D"
    variance_factor: float = 0.2
    seasonality: Optional[dict] = None  # Will be converted to SeasonalityConfig
    trend: Optional[dict] = None  # Will be converted to TrendConfig
    anomaly: Optional[dict] = None  # Will be converted to AnomalyConfig

    def __post_init__(self):
        """Convert string/dict values to appropriate types."""
        # Convert scale string to MetricScale enum
        if isinstance(self.scale, str):
            self.scale = MetricScale[self.scale.upper()]

        # Convert seasonality dict to SeasonalityConfig
        if self.seasonality and isinstance(self.seasonality, dict):
            self.seasonality = SeasonalityConfig(**self.seasonality)

        # Convert trend dict to TrendConfig
        if self.trend and isinstance(self.trend, dict):
            self.trend = TrendConfig(**self.trend)

        # Convert anomaly dict to AnomalyConfig
        if self.anomaly and isinstance(self.anomaly, dict):
            self.anomaly = AnomalyConfig(**self.anomaly)


@dataclass
class UnitMetricsConfig:
    """Main configuration container for unit metrics generation."""

    metrics: List[DataConfig]

    @classmethod
    def from_yaml(cls, yaml_path: Path) -> "UnitMetricsConfig":
        """Load configuration from YAML file."""
        with open(yaml_path) as f:
            data = yaml.safe_load(f)

        metrics = []
        for metric_data in data.get("metrics", []):
            metrics.append(DataConfig(**metric_data))

        return cls(metrics=metrics)

    def validate(self) -> None:
        """Validate the configuration."""
        if not self.metrics:
            raise ValueError("At least one metric must be defined")

        for metric in self.metrics:
            if not metric.name:
                raise ValueError("Metric name is required")
            if metric.variance_factor <= 0:
                raise ValueError(
                    f"Variance factor must be positive for metric '{metric.name}'"
                )
            if metric.frequency not in ["D", "M"]:
                raise ValueError(
                    f"Frequency must be 'D' or 'M' for metric '{metric.name}'"
                )
