from typing import Dict, List, Optional
"""
Data models for dataset size analysis.
"""

from dataclasses import dataclass
from datetime import datetime


@dataclass
class ProviderMetrics:
    """Per-provider dataset metrics."""

    provider: str
    max_monthly_line_items: int
    min_monthly_line_items: int
    total_months: int
    unique_billing_combinations: int
    cost_tier: str
    required_connections: int
    estimated_upload_duration_hours: float

    def summary(self) -> str:
        """Human-readable summary of provider metrics."""
        return (
            f"{self.provider}: {self.max_monthly_line_items:,} line items/month "
            f"({self.cost_tier} scale, {self.required_connections} connections)"
        )


@dataclass
class DatasetMetrics:
    """Comprehensive dataset size metrics."""

    provider_breakdown: Dict[str, ProviderMetrics]
    total_line_items: int
    cost_tier_classification: Dict[str, str]
    connection_requirements: Dict[str, int]
    memory_estimate_mb: float
    tenant_multiplication_factor: int = 1
    analysis_timestamp: str = None
    stage_name: Optional[str] = None

    def __post_init__(self):
        """Set analysis timestamp if not provided."""
        if self.analysis_timestamp is None:
            self.analysis_timestamp = datetime.utcnow().isoformat()

    @property
    def overall_cost_tier(self) -> str:
        """Overall cost tier based on highest provider tier."""
        tier_priority = {"Demo": 0, "CloudZero": 1, "Large": 2, "Largest": 3}
        if not self.cost_tier_classification:
            return "Demo"

        highest_tier = max(
            self.cost_tier_classification.values(),
            key=lambda tier: tier_priority.get(tier, 0),
        )
        return highest_tier

    @property
    def total_connections_required(self) -> int:
        """Total connections required across all providers."""
        return sum(self.connection_requirements.values())

    def summary(self) -> str:
        """Human-readable summary of dataset metrics."""
        provider_summaries = [
            metrics.summary() for metrics in self.provider_breakdown.values()
        ]

        summary_lines = [
            f"Dataset Analysis ({self.stage_name or 'Unknown Stage'}):",
            f"  Total Line Items: {self.total_line_items:,}",
            f"  Overall Cost Tier: {self.overall_cost_tier}",
            f"  Total Connections: {self.total_connections_required}",
            f"  Memory Estimate: {self.memory_estimate_mb:.1f} MB",
        ]

        if self.tenant_multiplication_factor > 1:
            summary_lines.append(
                f"  Cost Factor: {self.tenant_multiplication_factor}x CloudZero tenants"
            )

        summary_lines.append("  Provider Breakdown:")
        for provider_summary in provider_summaries:
            summary_lines.append(f"    {provider_summary}")

        return "\n".join(summary_lines)


@dataclass
class CostImpactAnalysis:
    """Business cost impact analysis."""

    overall_tier: str
    cost_multiplication_factor: int
    ingest_speed_category: str
    optimization_recommendations: List[str]
    moderate_warnings: List[str]
    benefits: List[str]

    def summary(self) -> str:
        """Human-readable cost impact summary."""
        lines = [
            "Cost Impact Analysis:",
            f"  Cost Tier: {self.overall_tier}",
            f"  Ingest Speed: {self.ingest_speed_category}",
        ]

        if self.cost_multiplication_factor > 1:
            lines.append(
                f"  Cost Factor: {self.cost_multiplication_factor}x (multiple tenants)"
            )

        if self.benefits:
            lines.append("  Benefits:")
            for benefit in self.benefits:
                lines.append(f"    • {benefit}")

        if self.moderate_warnings:
            lines.append("  Considerations:")
            for warning in self.moderate_warnings:
                lines.append(f"    ⚠️  {warning}")

        if self.optimization_recommendations:
            lines.append("  Optimization Options:")
            for rec in self.optimization_recommendations:
                lines.append(f"    💡 {rec}")

        return "\n".join(lines)
