"""
Data upload commands using S3-based multi-org approach.
"""

import sys
from pathlib import Path
from typing import Optional

import typer
from rich.console import Console

from ...upload.s3.config import UploadConfig
from ...upload.s3.orchestrator import S3UploadOrchestrator

console = Console()

def upload_generated(
    config: str = typer.Option(..., "--config", help="Upload configuration file (YAML)"),
    dry_run: bool = typer.Option(False, "--dry-run", help="Dry run mode - validate config and show what would be uploaded"),
    recreate_connections: bool = typer.Option(False, "--recreate-connections", help="Delete and recreate CloudZero connections for optimized first ingest"),
    verbose: bool = typer.Option(False, "--verbose", help="Verbose output with detailed progress"),
) -> None:
    """
    Upload generated datasets to CloudZero S3 for multiple organizations.
    
    Loads a generated dataset from S3 storage and uploads it to CloudZero S3 buckets
    for multiple organizations with proper CBF formatting, drop ID management,
    and manifest handling.
    
    Example configuration file:
    
    upload_config:
      dataset_name: "2025-01-15_14-30-22"
      months: ["2024-07", "2024-08"]
      organizations:
        - name: "TradeShow"
          api_token_env: "CLOUDZERO_TRADESHOW_API_TOKEN"
          providers:
            AWS:
              months: ["2024-07", "2024-08"]
            GCP: null
          connections:
            AWS: ["tradeshow-aws-connection-1"]
            GCP: ["tradeshow-gcp-connection-1"]
    """
    try:
        # FAIL FAST: Validate AWS credentials before any work
        from ...services.environment_service import EnvironmentService
        env_service = EnvironmentService()
        env_service.validate_aws_credentials_and_access()
        
    except ValueError as e:
        console.print(f"❌ {str(e)}")
        raise typer.Exit(1)
    
    try:
        # Load and validate configuration
        config_path = Path(config)
        if not config_path.exists():
            console.print(f"❌ Configuration file not found: {config}", style="red")
            raise typer.Exit(1)
        
        console.print(f"📋 Loading upload configuration: {config_path}")
        upload_config = UploadConfig.from_yaml(config_path)
        
        # Display configuration summary  
        mode_text = "RECREATE & UPLOAD" if recreate_connections and not dry_run else "DRY RUN" if dry_run else "UPLOAD"
        console.print(f"🚀 {mode_text} Configuration:")
        console.print(f"   Dataset: {upload_config.dataset_name}")
        console.print(f"   Stage Discovery: Automatic (discount > usage > metadata > k8s > generate)")
        console.print(f"   Organizations: {len(upload_config.organizations)}")
        
        if recreate_connections:
            console.print("🔄 Recreate connections enabled - optimizes CloudZero first ingest")
        
        if verbose:
            if upload_config.months:
                console.print(f"   Global months: {upload_config.months}")
            if upload_config.providers:
                console.print(f"   Global providers: {upload_config.providers}")
            for org in upload_config.organizations:
                console.print(f"     • {org.name} - Providers: {org.providers}")
                if org.months:
                    console.print(f"       Months override: {org.months}")
                if org.stage_overrides:
                    console.print(f"       Stage overrides: {org.stage_overrides}")
        
        if dry_run:
            if recreate_connections:
                console.print("🧪 DRY RUN MODE - Showing connection recreation impact")
            else:
                console.print("🧪 DRY RUN MODE - Validation only, no files will be uploaded")
        
        # Create orchestrator and execute upload
        orchestrator = S3UploadOrchestrator(upload_config)
        
        # Handle recreate connections workflow
        if recreate_connections:
            if dry_run:
                console.print(f"\n🔍 Analyzing connection recreation impact...")
                result = orchestrator.show_recreate_plan()
            else:
                # Confirm destructive operation
                console.print("\n⚠️  Connection Recreation Impact:")
                console.print("   • Will delete existing CloudZero connections")
                console.print("   • Will delete org provider folders in S3")
                console.print("   • Source datasets in czbillgen/ will be preserved")
                console.print("   • Connections will be recreated for optimized first ingest")
                
                if not typer.confirm("\nContinue with connection recreation?"):
                    console.print("❌ Operation cancelled by user")
                    raise typer.Exit(0)
                
                console.print(f"\n🔄 Starting connection recreation and upload...")
                result = orchestrator.recreate_and_upload()
        else:
            # Normal upload workflow
            if dry_run:
                console.print(f"\n🧪 Starting validation process...")
            else:
                console.print(f"\n🚀 Starting upload process...")
            result = orchestrator.upload_dataset_to_orgs(dry_run=dry_run)
        
        # Display results
        mode_text = "Validation" if dry_run else "Upload"
        console.print(f"\n🎯 {mode_text} Results:")
        console.print(f"   Status: {result['status']}")
        console.print(f"   Dataset: {result['dataset']}")
        console.print(f"   Organizations: {result['organizations_successful']}/{result['organizations_processed']} successful")
        
        if verbose or result['status'] != 'success':
            console.print(f"\n📊 Detailed Results:")
            for org_name, org_result in result["results"].items():
                status_icon = "✅" if org_result["status"] == "success" else "❌"
                console.print(f"   {status_icon} {org_name}: {org_result['status']}")
                
                if org_result["status"] == "success":
                    console.print(f"      Files: {org_result.get('files_uploaded', 0)}")
                    console.print(f"      Rows: {org_result.get('total_rows', 0):,}")
                    console.print(f"      Drop ID: {org_result.get('drop_id', 'N/A')}")
                else:
                    console.print(f"      Error: {org_result.get('error', 'Unknown error')}")
        
        # Exit with appropriate code
        if result['status'] == 'success':
            if dry_run:
                console.print(f"\n✅ Validation completed successfully!")
            else:
                console.print(f"\n✅ Upload completed successfully!")
            sys.exit(0)
        elif result['status'] == 'partial':
            if dry_run:
                console.print(f"\n⚠️  Validation completed with some failures!")
            else:
                console.print(f"\n⚠️  Upload completed with some failures!")
            sys.exit(1)
        else:
            if dry_run:
                console.print(f"\n❌ Validation failed!")
            else:
                console.print(f"\n❌ Upload failed!")
            sys.exit(1)
        
    except Exception as e:
        console.print(f"❌ Upload failed: {str(e)}", style="red")
        if verbose:
            import traceback
            console.print(f"Traceback: {traceback.format_exc()}", style="red")
        raise typer.Exit(1)


def upload_adhoc(
    config: str = typer.Option(..., "--config", help="Upload configuration file (YAML)"),
    dry_run: bool = typer.Option(False, "--dry-run", help="Dry run mode - validate config and show what would be uploaded"),
    verbose: bool = typer.Option(False, "--verbose", help="Verbose output with detailed progress"),
) -> None:
    """
    Upload ad-hoc CSV data to CloudZero S3 for multiple organizations.
    
    Loads a user-provided CSV file with optional column mapping and uploads it
    to CloudZero S3 buckets for multiple organizations with proper CBF formatting,
    drop ID management, and manifest handling.
    
    Example configuration file:
    
    upload_config:
      adhoc:
        csv_path: "data/my-billing-data.csv"
        mapping_path: "data/my-column-mapping.csv"  # Optional
      organizations:
        - name: "TradeShow"
          api_token_env: "CLOUDZERO_TRADESHOW_API_TOKEN"
          providers:
            AWS: {}
            GCP: {}
          connections:
            AWS: ["tradeshow-aws-connection-1"]
            GCP: ["tradeshow-gcp-connection-1"]
    """
    try:
        # FAIL FAST: Validate AWS credentials before any work
        from ...services.environment_service import EnvironmentService
        env_service = EnvironmentService()
        env_service.validate_aws_credentials_and_access()
        
    except ValueError as e:
        console.print(f"❌ {str(e)}")
        raise typer.Exit(1)
    
    try:
        # Load and validate configuration
        config_path = Path(config)
        if not config_path.exists():
            console.print(f"❌ Configuration file not found: {config}", style="red")
            raise typer.Exit(1)
        
        console.print(f"📋 Loading upload configuration: {config_path}")
        upload_config = UploadConfig.from_yaml(config_path)
        
        # Validate this is an ad-hoc upload configuration
        if not upload_config.is_adhoc_upload():
            console.print("❌ Configuration file does not contain ad-hoc upload settings", style="red")
            console.print("Expected 'adhoc' section with 'csv_path' in upload_config", style="red")
            raise typer.Exit(1)
        
        # Display configuration summary
        console.print(f"🚀 Ad-hoc Upload Configuration:")
        console.print(f"   CSV file: {upload_config.adhoc.csv_path}")
        if upload_config.adhoc.mapping_path:
            console.print(f"   Mapping file: {upload_config.adhoc.mapping_path}")
        else:
            console.print(f"   Mapping: Default CBF mapping from S3")
        console.print(f"   Organizations: {len(upload_config.organizations)}")
        
        if verbose:
            for org in upload_config.organizations:
                providers = list(org.providers.keys())
                console.print(f"     • {org.name} - Providers: {providers}")
        
        if dry_run:
            console.print("🧪 DRY RUN MODE - Configuration validated, no files will be uploaded")
        
        # Create orchestrator and execute upload
        orchestrator = S3UploadOrchestrator(upload_config)
        
        console.print(f"\\n🚀 Starting ad-hoc upload process...")
        result = orchestrator.upload_adhoc_to_orgs(dry_run=dry_run)
        
        # Display results
        console.print(f"\\n🎯 Upload Results:")
        console.print(f"   Status: {result['status']}")
        console.print(f"   CSV file: {result['csv_path']}")
        console.print(f"   Organizations: {result['organizations_successful']}/{result['organizations_processed']} successful")
        
        if verbose or result['status'] != 'success':
            console.print(f"\\n📊 Detailed Results:")
            for org_name, org_result in result["results"].items():
                status_icon = "✅" if org_result["status"] == "success" else "❌"
                console.print(f"   {status_icon} {org_name}: {org_result['status']}")
                
                if org_result["status"] == "success":
                    console.print(f"      Files: {org_result.get('files_uploaded', 0)}")
                    console.print(f"      Rows: {org_result.get('total_rows', 0):,}")
                    console.print(f"      Providers: {org_result.get('providers', [])}")
                else:
                    console.print(f"      Error: {org_result.get('error', 'Unknown error')}")
        
        # Exit with appropriate code
        if result['status'] == 'success':
            console.print(f"\\n✅ Ad-hoc upload completed successfully!")
            sys.exit(0)
        elif result['status'] == 'partial':
            console.print(f"\\n⚠️  Ad-hoc upload completed with some failures!")
            sys.exit(1)
        else:
            console.print(f"\\n❌ Ad-hoc upload failed!")
            sys.exit(1)
        
    except Exception as e:
        console.print(f"❌ Ad-hoc upload failed: {str(e)}", style="red")
        if verbose:
            import traceback
            console.print(f"Traceback: {traceback.format_exc()}", style="red")
        raise typer.Exit(1)


# Create Typer app with new commands
app = typer.Typer(help="Data upload operations")

app.command("generated")(upload_generated)
app.command("adhoc")(upload_adhoc)

# Add connections management as a sub-command group
from ...upload.cli.connections import app as connections_app
app.add_typer(connections_app, name="connections")

# Remove the old s3 command - it's now integrated into generated