"""
Connection management utilities for CloudZero billing connections.

Provides helper functions for connection naming, creation, and validation
following patterns from cz-demo-tools.
"""

import os
from typing import Dict, List
from .client import CloudZeroConnection


def generate_provider_connection_name(provider: str) -> str:
    """
    Generate a provider connection name in the format: aws_bc_0001, azure_bc_0001, etc.
    
    Args:
        provider: Provider name (AWS, Azure, GCP, AWS Marketplace, etc.)
        
    Returns:
        Generated connection name (always uses bc_0001 format, spaces become underscores)
    """
    # Convert to lowercase and replace spaces with underscores
    clean_provider = provider.lower().replace(' ', '_')
    return f"{clean_provider}_bc_0001"


def get_provider_display_name(provider: str) -> str:
    """
    Get the correct display name for a provider.
    
    Args:
        provider: Provider name (AWS, Azure, GCP)
        
    Returns:
        Correct display name for CloudZero API
    """
    provider_mapping = {
        "AWS": "AWS.",  # Must have period for data quality
        "Azure": "Azure",
        "GCP": "GCP"
    }
    
    return provider_mapping.get(provider.upper(), provider)


def create_cloudzero_connection(
    provider: str,
    s3_bucket_name: str,
    s3_root_folder: str,
    s3_org_folder: str,
    role_arn: str,
    external_id: str
) -> CloudZeroConnection:
    """
    Create a CloudZeroConnection object for a provider.
    
    Args:
        provider: Provider name (AWS, Azure, GCP)
        s3_bucket_name: S3 bucket name
        s3_root_folder: S3 root folder
        s3_org_folder: S3 organization folder
        role_arn: AWS IAM role ARN
        external_id: AWS IAM external ID
        
    Returns:
        CloudZeroConnection object
    """
    connection_name = generate_provider_connection_name(provider)
    display_name = get_provider_display_name(provider)
    s3_bucket_path = f"{s3_root_folder}/{s3_org_folder}/{provider}"
    
    return CloudZeroConnection(
        name=connection_name,
        cloud_provider=display_name,
        s3_bucket_name=s3_bucket_name,
        s3_bucket_path=s3_bucket_path,
        role_arn=role_arn,
        external_id=external_id,
        is_enabled=True
    )


def validate_cloudzero_config() -> Dict[str, str]:
    """
    Validate CloudZero configuration from environment variables.
    
    Returns:
        Dictionary with validated configuration
        
    Raises:
        ValueError: If required configuration is missing
    """
    required_vars = {
        "CZ_ORG_API_KEY": os.environ.get("CZ_ORG_API_KEY"),
        "AWS_IAM_ROLE_ARN": os.environ.get("AWS_IAM_ROLE_ARN"),
        "AWS_IAM_EXTERNAL_ID": os.environ.get("AWS_IAM_EXTERNAL_ID")
    }
    
    missing_vars = [var for var, value in required_vars.items() if not value]
    
    if missing_vars:
        raise ValueError(
            f"Missing required CloudZero configuration: {', '.join(missing_vars)}\n"
            f"Please set these environment variables in your ~/.czbillgen/.env file"
        )
    
    return {var: value for var, value in required_vars.items() if value}


def get_org_api_key(org_name: str) -> str:
    """
    Get organization-specific API key from environment variables.
    
    Args:
        org_name: Organization name
        
    Returns:
        API key for the organization
        
    Raises:
        ValueError: If API key not found
    """
    # Try org-specific key first
    org_key_var = f"CZ_ORG_API_KEY_{org_name.upper()}"
    org_api_key = os.environ.get(org_key_var)
    
    if org_api_key:
        return org_api_key
    
    # Fall back to generic key
    generic_api_key = os.environ.get("CZ_ORG_API_KEY")
    if generic_api_key:
        return generic_api_key
    
    # No key found
    raise ValueError(
        f"No CloudZero API key found for organization '{org_name}'. "
        f"Please set {org_key_var} or CZ_ORG_API_KEY in your ~/.czbillgen/.env file"
    )


class ConnectionManager:
    """
    High-level connection management for czbillgen upload operations.
    
    Provides simplified interface for connection validation and auto-creation
    during upload operations.
    """
    
    def __init__(self, api_key: str):
        """
        Initialize connection manager.
        
        Args:
            api_key: CloudZero API key
        """
        from .client import CloudZeroAPI
        self.api = CloudZeroAPI(api_key)
    
    def validate_connections_exist(self, providers: List[str]) -> Dict[str, bool]:
        """
        Validate that connections exist for all specified providers.
        
        Args:
            providers: List of provider names
            
        Returns:
            Dictionary mapping provider names to existence status
        """
        results = {}
        
        for provider in providers:
            connection = self.api.find_enabled_bucket_connection(provider)
            results[provider] = connection is not None
            
        return results
    
    def ensure_all_connections(self, providers: List[str], s3_config: Dict[str, str]) -> Dict[str, Dict]:
        """
        Ensure all required connections exist, creating them if necessary.
        
        Args:
            providers: List of provider names
            s3_config: S3 configuration with bucket details
            
        Returns:
            Dictionary mapping provider names to connection details
        """
        # Validate AWS IAM configuration
        aws_iam_role = os.environ.get("AWS_IAM_ROLE_ARN")
        aws_iam_external_id = os.environ.get("AWS_IAM_EXTERNAL_ID")
        
        if not aws_iam_role or not aws_iam_external_id:
            missing = []
            if not aws_iam_role:
                missing.append("AWS_IAM_ROLE_ARN")
            if not aws_iam_external_id:
                missing.append("AWS_IAM_EXTERNAL_ID")
            raise ValueError(
                f"Missing required AWS IAM configuration: {', '.join(missing)}\n"
                f"Please set these environment variables in your ~/.czbillgen/.env file"
            )
        
        # Ensure connections for all providers
        return self.api.ensure_provider_bucket_connections(
            providers=providers,
            s3_bucket_name=s3_config["bucket_name"],
            s3_root_folder=s3_config["root_folder"],
            s3_org_folder=s3_config["org_folder"],
            role_arn=aws_iam_role,
            external_id=aws_iam_external_id
        )