"""
S3 operations for reference data management.

Provides download and upload commands for S3-backed reference data storage
with local caching and validation.
"""

from pathlib import Path
from typing import Optional

import typer
from rich.console import Console

from ...services.s3_data_service import S3DataService
from ...services.environment_service import env_service

console = Console()
app = typer.Typer(help="S3 reference data operations")


@app.command()
def download(
    force: bool = typer.Option(
        False, "--force", "-f", help="Force re-download even if cached file exists"
    ),
):
    """Download reference data from S3 to local cache."""
    try:
        # FAIL FAST: Validate AWS credentials before any work
        env_service.validate_aws_credentials_and_access()
        
        s3_service = S3DataService()
        
        console.print("🔄 Downloading reference data from S3...")
        
        cached_path = s3_service.download_reference_data(force=force)
        
        console.print(f"✅ Reference data downloaded to: {cached_path}")
        console.print(f"📊 Cache location: {s3_service.cache_dir}")
        
        # Show basic file info
        file_size_mb = cached_path.stat().st_size / (1024 * 1024)
        console.print(f"📁 File size: {file_size_mb:.1f} MB")
        
    except FileNotFoundError as e:
        console.print(f"❌ {e}", style="red")
        console.print("💡 Make sure reference data has been uploaded to S3 first", style="yellow")
        raise typer.Exit(1)
    except ValueError as e:
        console.print(f"❌ Configuration error: {e}", style="red")
        console.print("💡 Check your ~/.czbillgen/.env file for S3 settings", style="yellow")
        raise typer.Exit(1)
    except Exception as e:
        console.print(f"❌ Download failed: {e}", style="red")
        raise typer.Exit(1)


@app.command()
def upload(
    source: Optional[Path] = typer.Option(
        None, "--source", "-s", help="Source reference data file (default: data/reference.parquet)"
    ),
    refresh_backup: bool = typer.Option(
        False, "--refresh-backup", help="Refresh S3 backup before uploading new version"
    ),
):
    """Upload reference data to S3 with validation and optional backup refresh."""
    try:
        # FAIL FAST: Validate AWS credentials before any work
        env_service.validate_aws_credentials_and_access()
        
        # Default to current project's reference data
        if source is None:
            source = Path("data/reference.parquet")
        
        # Resolve to absolute path
        source = source.resolve()
        
        if not source.exists():
            console.print(f"❌ Source file not found: {source}", style="red")
            console.print("💡 Make sure you're in the project directory or specify --source", style="yellow")
            raise typer.Exit(1)
        
        s3_service = S3DataService()
        
        console.print(f"🔄 Uploading reference data from: {source}")
        
        if refresh_backup:
            console.print("🔄 Refreshing backup before upload...")
        
        s3_service.upload_reference_data(source, refresh_backup=refresh_backup)
        
        console.print("✅ Reference data uploaded successfully!")
        console.print(f"📊 S3 location: s3://{s3_service.bucket}/{s3_service._get_s3_reference_key('reference.parquet')}")
        
        if refresh_backup:
            console.print(f"💾 Backup location: s3://{s3_service.bucket}/{s3_service._get_s3_reference_key('reference.backup.parquet')}")
        
    except ValueError as e:
        console.print(f"❌ Validation error: {e}", style="red")
        console.print("💡 Check file format, required columns, and row count", style="yellow")
        raise typer.Exit(1)
    except Exception as e:
        console.print(f"❌ Upload failed: {e}", style="red")
        raise typer.Exit(1)


@app.command()
def status():
    """Show S3 reference data cache status and configuration."""
    try:
        # FAIL FAST: Validate AWS credentials before any work
        env_service.validate_aws_credentials_and_access()
        
        s3_service = S3DataService()
        
        console.print("📊 S3 Reference Data Status", style="bold")
        console.print()
        
        # S3 Configuration
        console.print("🔧 Configuration:", style="bold")
        console.print(f"  Bucket: {s3_service.bucket}")
        console.print(f"  Reference path: {s3_service.reference_path}")
        console.print(f"  Region: {s3_service.region}")
        console.print(f"  Cache directory: {s3_service.cache_dir}")
        console.print()
        
        # Cache status
        console.print("💾 Cache Status:", style="bold")
        cached_path = s3_service.get_cached_reference_path()
        
        if cached_path:
            file_size_mb = cached_path.stat().st_size / (1024 * 1024)
            modified_time = cached_path.stat().st_mtime
            from datetime import datetime
            modified_str = datetime.fromtimestamp(modified_time).strftime("%Y-%m-%d %H:%M:%S")
            
            console.print(f"  ✅ Cached: {cached_path}")
            console.print(f"  📁 Size: {file_size_mb:.1f} MB")
            console.print(f"  🕐 Modified: {modified_str}")
        else:
            console.print("  ❌ No cached reference data found")
            console.print("  💡 Run 'czbillgen data download' to cache from S3")
        
        console.print()
        
        # Test S3 connection
        console.print("🌐 S3 Connection:", style="bold")
        try:
            # Test S3 connection by accessing the client
            _ = s3_service.s3_client
            console.print("  ✅ Connected successfully")
        except Exception as e:
            console.print(f"  ❌ Connection failed: {e}")
            console.print("  💡 Check your AWS credentials and .env configuration")
        
    except Exception as e:
        console.print(f"❌ Status check failed: {e}", style="red")
        raise typer.Exit(1)