"""
Core Profile System for CloudZero Billing Generator

Simplified, high-value profile system with standard parameter interfaces.
Contains 5 essential variance profiles and 5 essential anomaly profiles
that cover all major business scenarios without complexity overhead.

Profile Selection Criteria:
- Maximum distinctiveness for demo purposes
- Obvious visibility at multiple time granularities
- Compelling business narratives across different industries
- KISS principle alignment - simple but powerful

All profiles implement complete standard parameter interfaces to enable
consistent development and easy maintenance.
"""

from dataclasses import dataclass
from typing import Any, Dict, List


@dataclass
class VarianceProfile:
    """Standard variance profile with complete parameter interface."""

    # Profile metadata
    name: str
    description: str

    # Basic variance levels (0.0-1.5 range)
    hourly_variance: float = 0.2
    daily_variance: float = 0.4
    weekly_variance: float = 0.6
    monthly_variance: float = 0.8
    phase_jitter: float = 0.5

    # Timing patterns (ENHANCED)
    timing: str = (
        "always_on"  # "business_hours", "weekend_heavy", "always_on", "night_shift"
    )
    business_hours_multiplier: float = 1.0  # Variance during M-F 9-5
    off_hours_multiplier: float = 1.0  # Variance during nights/weekends
    weekend_multiplier: float = 1.0  # Weekend-specific adjustment

    # Seasonal mathematics (ENHANCED)
    seasonal_amplitude: float = 0.0  # Strength of seasonal effect (0.0-1.0)
    seasonal_phase: float = 0.0  # Phase shift in seasonal cycle (0.0-1.0)
    seasonal_period: str = "weekly"  # "weekly", "monthly", "quarterly", "yearly"
    use_seasonal_math: bool = False  # True = sine wave patterns, False = flat variance

    # Growth patterns (ENHANCED)
    growth_rate: float = 0.0  # Monthly growth rate (0.05 = 5% per month)
    growth_type: str = "none"  # "linear", "exponential", "none"


@dataclass
class AnomalyProfile:
    """Standard anomaly profile with complete parameter interface."""

    # Profile metadata
    name: str
    description: str

    # Basic anomaly settings
    interval_days: int = 90  # Days between anomaly events
    intensity: float = 0.8  # Magnitude multiplier (0.1-8.0 range)
    duration_hours: int = 72  # Duration in hours (1-999)
    timing: str = "random"  # "random", "business_hours", "monthly_end", "quarterly", "ninety_day_cycle"

    # Anomaly type behavior (ENHANCED)
    anomaly_type: str = "spike"  # "spike", "dip", "step_up", "step_down", "irregular"
    frequency: float = 0.1  # Probability of occurrence (0.0-1.0)

    # Pattern-specific timing (ENHANCED)
    business_hours_bias: float = 0.5  # Fraction of anomalies during business hours
    quarter_end_bias: float = 0.5  # Increased likelihood at quarter end
    month_end_bias: float = 0.5  # Increased likelihood at month end

    # Story-driven behavior (ENHANCED)
    cost_optimization_factor: float = 0.5  # Cost reduction for step_down anomalies
    scaling_factor: float = 2.0  # Cost increase for step_up anomalies
    emergency_multiplier: float = 1.0  # Additional multiplier for security incidents


# Simplified Variance Profiles (5 High-Value Profiles)
CORE_VARIANCE_PROFILES = {
    "gradual_variance_buildup": VarianceProfile(
        name="gradual_variance_buildup",
        description="Increasing variance from hourly to monthly (perfect for CloudZero demos)",
        hourly_variance=0.2,
        daily_variance=0.5,
        weekly_variance=0.8,
        monthly_variance=1.2,
        phase_jitter=0.6,
        timing="always_on",
        seasonal_amplitude=0.3,
        seasonal_period="monthly",
        use_seasonal_math=True,
        growth_type="none",
    ),
    "analytics_workload": VarianceProfile(
        name="analytics_workload",
        description="Burst patterns for data processing and ML workloads",
        hourly_variance=0.8,
        daily_variance=1.0,
        weekly_variance=0.4,
        monthly_variance=0.7,
        phase_jitter=0.9,
        timing="always_on",
        seasonal_amplitude=0.4,
        seasonal_period="daily",
        use_seasonal_math=True,
        growth_type="none",
    ),
    "holiday_seasonal": VarianceProfile(
        name="holiday_seasonal",
        description="Higher usage during holiday seasons (retail/e-commerce)",
        hourly_variance=0.5,
        daily_variance=0.7,
        weekly_variance=0.6,
        monthly_variance=0.9,
        phase_jitter=0.6,
        timing="always_on",
        seasonal_amplitude=0.6,
        seasonal_phase=0.9,  # Peak in Q4
        seasonal_period="yearly",
        use_seasonal_math=True,
        growth_rate=0.03,
        growth_type="linear",
    ),
    "quarter_end_surge": VarianceProfile(
        name="quarter_end_surge",
        description="Large spikes at quarter ends",
        hourly_variance=0.4,
        daily_variance=0.6,
        weekly_variance=0.8,
        monthly_variance=1.0,
        phase_jitter=0.4,
        timing="always_on",
        seasonal_amplitude=0.5,
        seasonal_phase=0.95,  # Peak at quarter end
        seasonal_period="quarterly",
        use_seasonal_math=True,
        growth_type="none",
    ),
    "weekend_spike_cycles": VarianceProfile(
        name="weekend_spike_cycles",
        description="Higher variance on weekends with chaotic patterns",
        hourly_variance=0.6,
        daily_variance=0.8,
        weekly_variance=0.4,
        monthly_variance=0.6,
        phase_jitter=1.0,
        timing="weekend_heavy",
        business_hours_multiplier=0.5,
        off_hours_multiplier=1.2,
        weekend_multiplier=1.8,
        seasonal_amplitude=0.4,
        seasonal_period="weekly",
        use_seasonal_math=True,
        growth_type="none",
    ),
}


# Simplified Anomaly Profiles (5 High-Value Profiles)
CORE_ANOMALY_PROFILES = {
    "random_mega_burst": AnomalyProfile(
        name="random_mega_burst",
        description="Unpredictable 100-500x spikes with exponential decay over 1-3 days",
        interval_days=60,
        intensity=250.0,  # 250x average magnitude (100-500x range)
        duration_hours=48,  # 1-3 days average
        timing="random",
        anomaly_type="spike",
        frequency=0.002,  # 0.2% daily probability
        emergency_multiplier=2.0,
    ),
    "infrastructure_scaling_up": AnomalyProfile(
        name="infrastructure_scaling_up",
        description="Migration to larger instances that creates permanent cost increase",
        interval_days=30,
        intensity=1.75,  # 175% of original (75% increase)
        duration_hours=999,  # Permanent baseline shift
        timing="random",
        anomaly_type="step_up",
        frequency=0.03,  # 3% monthly probability
        scaling_factor=1.75,
    ),
    "end_period_rush": AnomalyProfile(
        name="end_period_rush",
        description="Month/quarter-end processing surge with random timing in end window",
        interval_days=30,
        intensity=8.0,  # 8x average magnitude (5-12x range)
        duration_hours=60,  # 2-3 days average
        timing="month_end_window",  # Random point within last week
        anomaly_type="spike",
        frequency=0.80,  # 80% probability in end window
        month_end_bias=0.9,
        business_hours_bias=0.7,
    ),
    "immediate_cliff_drop": AnomalyProfile(
        name="immediate_cliff_drop",
        description="Instant 90% cost reduction followed by gradual recovery",
        interval_days=45,
        intensity=0.10,  # Drop to 10% of normal (90% reduction)
        duration_hours=8,  # 6-12 hour recovery average
        timing="random",
        anomaly_type="step_down",
        frequency=0.005,  # 0.5% daily probability
        cost_optimization_factor=0.10,
    ),
    "brief_extreme_event": AnomalyProfile(
        name="brief_extreme_event",
        description="Very high magnitude (30-80x) for very short duration (15min-2hrs)",
        interval_days=15,
        intensity=55.0,  # 55x average magnitude (30-80x range)
        duration_hours=1.0,  # 15min-2hrs average
        timing="random",
        anomaly_type="spike",
        frequency=0.01,  # 1% daily probability
        emergency_multiplier=1.2,
    ),
}


def get_variance_profile(profile_name: str) -> VarianceProfile:
    """Get variance profile with strict validation."""
    if profile_name not in CORE_VARIANCE_PROFILES:
        available_profiles = list(CORE_VARIANCE_PROFILES.keys())
        raise ValueError(
            f"Unknown variance profile: '{profile_name}'. "
            f"Available profiles: {available_profiles}"
        )
    return CORE_VARIANCE_PROFILES[profile_name]


def get_anomaly_profile(profile_name: str) -> AnomalyProfile:
    """Get anomaly profile with strict validation."""
    if profile_name not in CORE_ANOMALY_PROFILES:
        available_profiles = list(CORE_ANOMALY_PROFILES.keys())
        raise ValueError(
            f"Unknown anomaly profile: '{profile_name}'. "
            f"Available profiles: {available_profiles}"
        )
    return CORE_ANOMALY_PROFILES[profile_name]


def list_variance_profiles() -> List[str]:
    """List all available variance profile names."""
    return list(CORE_VARIANCE_PROFILES.keys())


def list_anomaly_profiles() -> List[str]:
    """List all available anomaly profile names."""
    return list(CORE_ANOMALY_PROFILES.keys())


def validate_profile_exists(profile_name: str, profile_type: str) -> bool:
    """Validate that the specified profile exists. Fail fast if not found."""
    try:
        if profile_type == "variance":
            get_variance_profile(profile_name)
        elif profile_type == "anomaly":
            get_anomaly_profile(profile_name)
        else:
            raise ValueError(
                f"Unknown profile type: '{profile_type}'. Must be 'variance' or 'anomaly'."
            )
        return True
    except ValueError:
        # Re-raise the error with context
        raise


def get_variance_config(profile_name: str) -> Dict[str, Any]:
    """Get variance configuration as dictionary with standard parameter interface."""
    profile = get_variance_profile(profile_name)

    return {
        # Basic variance levels
        "hourly_variance": profile.hourly_variance,
        "daily_variance": profile.daily_variance,
        "weekly_variance": profile.weekly_variance,
        "monthly_variance": profile.monthly_variance,
        "phase_jitter": profile.phase_jitter,
        # Timing patterns
        "timing": profile.timing,
        "business_hours_multiplier": profile.business_hours_multiplier,
        "off_hours_multiplier": profile.off_hours_multiplier,
        "weekend_multiplier": profile.weekend_multiplier,
        # Seasonal mathematics
        "seasonal_amplitude": profile.seasonal_amplitude,
        "seasonal_phase": profile.seasonal_phase,
        "seasonal_period": profile.seasonal_period,
        "use_seasonal_math": profile.use_seasonal_math,
        # Growth patterns
        "growth_rate": profile.growth_rate,
        "growth_type": profile.growth_type,
    }


def get_anomaly_config(profile_name: str) -> Dict[str, Any]:
    """Get anomaly configuration as dictionary with standard parameter interface."""
    profile = get_anomaly_profile(profile_name)

    return {
        # Basic anomaly settings
        "interval_days": profile.interval_days,
        "intensity": profile.intensity,
        "duration_hours": profile.duration_hours,
        "timing": profile.timing,
        # Anomaly type behavior
        "anomaly_type": profile.anomaly_type,
        "frequency": profile.frequency,
        # Pattern-specific timing
        "business_hours_bias": profile.business_hours_bias,
        "quarter_end_bias": profile.quarter_end_bias,
        "month_end_bias": profile.month_end_bias,
        # Story-driven behavior
        "cost_optimization_factor": profile.cost_optimization_factor,
        "scaling_factor": profile.scaling_factor,
        "emergency_multiplier": profile.emergency_multiplier,
    }


def get_profile_info(profile_name: str, profile_type: str) -> Dict[str, Any]:
    """Get complete profile information including metadata."""
    if profile_type == "variance":
        profile = get_variance_profile(profile_name)
        config = get_variance_config(profile_name)
    elif profile_type == "anomaly":
        profile = get_anomaly_profile(profile_name)
        config = get_anomaly_config(profile_name)
    else:
        raise ValueError(f"Unknown profile type: '{profile_type}'")

    return {
        "name": profile.name,
        "description": profile.description,
        "type": profile_type,
        "config": config,
    }


# Compatibility layer for existing pipeline converter functions
def convert_variance_profile_for_pipeline(profile_name: str) -> Dict[str, Any]:
    """Convert variance profile to pipeline format (maintains existing interface)."""
    profile = get_variance_profile(profile_name)

    return {
        "description": profile.description,
        "category": "core",
        "pattern_type": "enhanced_variance",
        "variance_config": get_variance_config(profile_name),
    }


def convert_anomaly_profile_for_pipeline(profile_name: str) -> Dict[str, Any]:
    """Convert anomaly profile to pipeline format (maintains existing interface)."""
    profile = get_anomaly_profile(profile_name)

    return {
        "description": profile.description,
        "category": "core",
        "anomaly_type": profile.anomaly_type,
        **get_anomaly_config(profile_name),
    }
