"""
Data models for time-shifting operations.

Defines configuration and result models for S3-to-S3 date transformation.
"""

from dataclasses import dataclass, field
from typing import List, Optional, Dict


@dataclass
class TimeShiftConfig:
    """
    Configuration for time-shift operation.

    Defines source/target months, organizations, and providers
    for transforming existing billing data to new time periods.

    Note: S3 bucket is read from ~/.czbg/.env (CZBILLGEN_S3_BUCKET)
          S3 root folder is hard-coded as "piedpiper-custom-billing"
    """

    # Source month (31-day month, auto-selected if not specified)
    source_month: Optional[str] = None

    # Target months (explicit list)
    target_months: Optional[List[str]] = None

    # Target range (e.g., "2026-01:2026-12")
    target_range: Optional[str] = None

    # Providers to process
    providers: List[str] = field(default_factory=list)

    # Organizations with API token mappings
    organizations: Dict[str, Dict[str, str]] = field(default_factory=dict)

    def __post_init__(self):
        """Validate required fields after initialization."""
        if not self.providers:
            raise ValueError("providers list cannot be empty")

        if not self.organizations:
            raise ValueError("organizations dict cannot be empty")

        if not self.target_months and not self.target_range:
            raise ValueError(
                "Must specify either target_months or target_range"
            )


@dataclass
class TransformStats:
    """Statistics for a single file transformation."""

    records_input: int = 0
    records_output: int = 0
    file_size_bytes: int = 0
    processing_time_sec: float = 0.0

    @property
    def records_filtered(self) -> int:
        """Number of records filtered out."""
        return self.records_input - self.records_output

    @property
    def filter_rate(self) -> float:
        """Percentage of records filtered."""
        if self.records_input == 0:
            return 0.0
        return (self.records_filtered / self.records_input) * 100


@dataclass
class DropCopyResult:
    """Result of copying and transforming a single drop."""

    org: str
    provider: str
    source_month: str
    target_month: str
    source_billing_period: Optional[str] = None
    target_billing_period: Optional[str] = None
    source_drop_id: Optional[str] = None
    target_drop_id: Optional[str] = None
    files_copied: int = 0
    total_records: int = 0
    total_bytes: int = 0
    processing_time_sec: float = 0.0
    success: bool = True
    error_message: Optional[str] = None


@dataclass
class TimeShiftResult:
    """Overall result of time-shift operation."""

    job_id: str
    source_month: str
    target_months: List[str]
    organizations: List[str]
    providers: List[str]
    drops_processed: int = 0
    drops_failed: int = 0
    total_records: int = 0
    total_bytes: int = 0
    total_time_sec: float = 0.0
    drop_results: List[DropCopyResult] = field(default_factory=list)

    @property
    def success_rate(self) -> float:
        """Percentage of drops successfully processed."""
        total = self.drops_processed + self.drops_failed
        if total == 0:
            return 0.0
        return (self.drops_processed / total) * 100

    @property
    def avg_time_per_drop(self) -> float:
        """Average processing time per drop in seconds."""
        if self.drops_processed == 0:
            return 0.0
        return self.total_time_sec / self.drops_processed
