"""
AnyCost connection manager for auto-creating API connections.

Manages CloudZero billing connections for AnyCost Stream API uploads,
including auto-creation with timestamp-based naming.
"""

from datetime import datetime
from typing import Optional, List
import pytz

from .client import CloudZeroAPI, CloudZeroConnection


class AnyCostConnectionManager:
    """
    Manage CloudZero connections for AnyCost API uploads.

    Single Responsibility: Ensure connections exist for API uploads,
    creating them with timestamp IDs if needed.
    """

    def __init__(self, api_client: CloudZeroAPI):
        """
        Initialize with CloudZeroAPI client.

        Args:
            api_client: CloudZeroAPI instance for connection operations
        """
        self.api_client = api_client

    def ensure_connections(
        self,
        provider: str,
        count: int,
        s3_bucket_name: str,
        s3_root_folder: str,
        s3_org_folder: str,
        role_arn: str,
        external_id: str,
        connection_suffix: Optional[str] = None
    ) -> List[str]:
        """
        Ensure multiple connections exist for provider, creating if needed.

        Creates enumerated connections for rate limit distribution.

        Args:
            provider: Provider name
            count: Number of connections to create
            s3_bucket_name: S3 bucket name
            s3_root_folder: S3 root folder
            s3_org_folder: S3 organization folder
            role_arn: IAM role ARN
            external_id: IAM external ID
            connection_suffix: Optional suffix for named connections

        Returns:
            List of connection ID strings
        """
        connection_ids = []
        timestamp = self._generate_timestamp()

        for i in range(1, count + 1):
            conn_id = self._ensure_single_connection(
                provider, i, timestamp, s3_bucket_name, s3_root_folder,
                s3_org_folder, role_arn, external_id, connection_suffix
            )
            connection_ids.append(conn_id)

        return connection_ids

    def _ensure_single_connection(
        self,
        provider: str,
        number: int,
        timestamp: str,
        s3_bucket_name: str,
        s3_root_folder: str,
        s3_org_folder: str,
        role_arn: str,
        external_id: str,
        connection_suffix: Optional[str] = None
    ) -> str:
        """Ensure single connection exists, creating if needed."""
        connection_name = self._generate_connection_name(provider, number, timestamp, connection_suffix)

        # Build S3 folder path with suffix
        if connection_suffix:
            s3_provider_folder = f"{provider}-{connection_suffix}"
        else:
            s3_provider_folder = provider

        # Check if exists
        existing = self.api_client.get_billing_connection(connection_name)
        if existing:
            print(f"   ✓ Connection exists: {connection_name}")
            return existing["id"]

        # Create new
        print(f"   🔗 Creating connection: {connection_name}")
        connection = self._build_connection_config(
            provider, connection_name, s3_bucket_name, s3_root_folder,
            s3_org_folder, role_arn, external_id, s3_provider_folder
        )
        result = self.api_client.create_billing_connection(connection)
        print(f"   ✅ Connection created: {connection_name}")
        return result["id"]

    def _generate_connection_name(
        self,
        provider: str,
        number: int,
        timestamp: str,
        connection_suffix: Optional[str] = None
    ) -> str:
        """
        Generate connection name with optional suffix.

        Format without suffix: {provider}_api_{number}_{timestamp}
        Format with suffix: {provider}_{suffix}_api_{number}_{timestamp}

        Examples:
            No suffix: aws_api_0001_20251003-1550
            With suffix: aws_anomalies_api_0001_20251003-1550

        Args:
            provider: Provider name
            number: Connection number (1-indexed)
            timestamp: Timestamp string
            connection_suffix: Optional suffix (e.g., "Anomalies")

        Returns:
            Connection name string
        """
        provider_lower = provider.lower().replace(" ", "_")
        number_str = f"{number:04d}"

        if connection_suffix:
            suffix_normalized = connection_suffix.lower().replace("-", "_")
            return f"{provider_lower}_{suffix_normalized}_api_{number_str}_{timestamp}"
        else:
            return f"{provider_lower}_api_{number_str}_{timestamp}"

    def _generate_timestamp(self) -> str:
        """
        Generate timestamp in US Eastern timezone.

        Format: YYYYMMDD-HHMM
        Example: 20251003-1550

        Returns:
            Timestamp string
        """
        eastern = pytz.timezone("US/Eastern")
        now = datetime.now(eastern)
        return now.strftime("%Y%m%d-%H%M")

    def _build_connection_config(
        self,
        provider: str,
        connection_name: str,
        s3_bucket_name: str,
        s3_root_folder: str,
        s3_org_folder: str,
        role_arn: str,
        external_id: str,
        s3_provider_folder: Optional[str] = None
    ) -> CloudZeroConnection:
        """
        Build CloudZeroConnection configuration.

        Args:
            provider: Provider name
            connection_name: Generated connection name
            s3_bucket_name: S3 bucket name
            s3_root_folder: S3 root folder
            s3_org_folder: S3 org folder
            role_arn: IAM role ARN
            external_id: IAM external ID
            s3_provider_folder: S3 provider folder (e.g., "AWS" or "AWS-Anomalies")

        Returns:
            CloudZeroConnection object
        """
        cloud_provider = self._get_provider_display_name(provider)

        # Use provider folder if specified, otherwise default to provider name
        folder = s3_provider_folder if s3_provider_folder else provider
        s3_bucket_path = f"{s3_root_folder}/{s3_org_folder}/{folder}"

        return CloudZeroConnection(
            name=connection_name,
            cloud_provider=cloud_provider,
            s3_bucket_name=s3_bucket_name,
            s3_bucket_path=s3_bucket_path,
            role_arn=role_arn,
            external_id=external_id,
            is_enabled=True
        )

    def _get_provider_display_name(self, provider: str) -> str:
        """
        Get CloudZero API provider display name.

        Args:
            provider: Provider name

        Returns:
            CloudZero-compatible provider name
        """
        provider_mapping = {
            "AWS": "AWS.",  # CloudZero requires period for AWS
            "Azure": "Azure",
            "GCP": "GCP",
            "AWS Marketplace": "AWS Marketplace",
            "Snowflake": "Snowflake"
        }
        return provider_mapping.get(provider.upper(), provider)
