"""
List outputs command implementation.

Implements the 'precipgen list-outputs' command for displaying
all station directories with file counts and disk usage summary.
"""

import argparse
from typing import Optional

from precipgen.utils import get_logger
from precipgen.utils.directory_manager import DirectoryManager


def add_parser(subparsers) -> argparse.ArgumentParser:
    """
    Add list-outputs command parser to subparsers.
    
    Args:
        subparsers: ArgumentParser subparsers object
        
    Returns:
        The list-outputs command parser
    """
    parser = subparsers.add_parser(
        "list-outputs",
        help="List all station directories with file counts and disk usage",
        description="Display summary of all station outputs and directory usage",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
Examples:
  precipgen list-outputs
  precipgen list-outputs --output-dir /path/to/analysis
  precipgen list-outputs --station USC00426128
  precipgen list-outputs --format json
        """
    )
    
    # Filter options
    parser.add_argument(
        "--station", "-s",
        type=str,
        help="Show information for specific station only"
    )
    
    parser.add_argument(
        "--workflow", "-w",
        choices=["data", "analysis", "simulation", "validation"],
        help="Filter by workflow type"
    )
    
    # Output options
    parser.add_argument(
        "--output-dir", "-o",
        type=str,
        help="Custom output directory (default: ./precipgen_output)"
    )
    
    parser.add_argument(
        "--format", "-f",
        choices=["table", "json", "summary"],
        default="table",
        help="Output format (default: table)"
    )
    
    parser.add_argument(
        "--sort-by",
        choices=["station", "size", "modified", "files"],
        default="station",
        help="Sort stations by field (default: station)"
    )
    
    parser.add_argument(
        "--reverse", "-r",
        action="store_true",
        help="Reverse sort order"
    )
    
    return parser


def format_file_size(size_mb: float) -> str:
    """
    Format file size in human-readable format.
    
    Args:
        size_mb: Size in megabytes
        
    Returns:
        Formatted size string
    """
    if size_mb < 1:
        return f"{size_mb * 1024:.1f} KB"
    elif size_mb < 1024:
        return f"{size_mb:.1f} MB"
    else:
        return f"{size_mb / 1024:.1f} GB"


def display_table_format(station_dirs: list, workflow_filter: Optional[str] = None) -> None:
    """
    Display station directories in table format.
    
    Args:
        station_dirs: List of StationDirectory objects
        workflow_filter: Optional workflow filter
    """
    if not station_dirs:
        print("No station directories found.")
        return
    
    # Header
    print(f"{'Station ID':<15} {'Size':<10} {'Data':<6} {'Analysis':<9} {'Simulation':<11} {'Validation':<11} {'Modified':<12}")
    print("-" * 85)
    
    total_size = 0.0
    total_files = 0
    
    for station in station_dirs:
        # Apply workflow filter
        if workflow_filter:
            if workflow_filter == "data" and not station.data_files:
                continue
            elif workflow_filter == "analysis" and not station.analysis_files:
                continue
            elif workflow_filter == "simulation" and not station.simulation_files:
                continue
            elif workflow_filter == "validation" and not station.validation_files:
                continue
        
        size_str = format_file_size(station.total_size_mb)
        modified_str = station.last_modified.strftime('%Y-%m-%d')
        
        data_count = len(station.data_files)
        analysis_count = len(station.analysis_files)
        simulation_count = len(station.simulation_files)
        validation_count = len(station.validation_files)
        
        print(f"{station.station_id:<15} {size_str:<10} {data_count:<6} {analysis_count:<9} {simulation_count:<11} {validation_count:<11} {modified_str:<12}")
        
        total_size += station.total_size_mb
        total_files += data_count + analysis_count + simulation_count + validation_count
    
    # Summary
    print("-" * 85)
    print(f"Total: {len(station_dirs)} stations, {format_file_size(total_size)}, {total_files} files")


def display_summary_format(station_dirs: list) -> None:
    """
    Display station directories in summary format.
    
    Args:
        station_dirs: List of StationDirectory objects
    """
    if not station_dirs:
        print("No station directories found.")
        return
    
    print("PrecipGen Output Summary")
    print("=" * 40)
    print()
    
    # Overall statistics
    total_size = sum(station.total_size_mb for station in station_dirs)
    total_files = sum(
        len(station.data_files) + len(station.analysis_files) + 
        len(station.simulation_files) + len(station.validation_files)
        for station in station_dirs
    )
    
    print(f"Total Stations: {len(station_dirs)}")
    print(f"Total Size: {format_file_size(total_size)}")
    print(f"Total Files: {total_files}")
    print()
    
    # Workflow completion statistics
    data_complete = sum(1 for station in station_dirs if station.data_files)
    analysis_complete = sum(1 for station in station_dirs if station.analysis_files)
    simulation_complete = sum(1 for station in station_dirs if station.simulation_files)
    validation_complete = sum(1 for station in station_dirs if station.validation_files)
    
    print("Workflow Completion:")
    print(f"  Data Acquisition: {data_complete}/{len(station_dirs)} ({data_complete/len(station_dirs)*100:.1f}%)")
    print(f"  Data Analysis:    {analysis_complete}/{len(station_dirs)} ({analysis_complete/len(station_dirs)*100:.1f}%)")
    print(f"  Simulation:       {simulation_complete}/{len(station_dirs)} ({simulation_complete/len(station_dirs)*100:.1f}%)")
    print(f"  Validation:       {validation_complete}/{len(station_dirs)} ({validation_complete/len(station_dirs)*100:.1f}%)")
    print()
    
    # Size distribution
    if station_dirs:
        sizes = [station.total_size_mb for station in station_dirs]
        avg_size = sum(sizes) / len(sizes)
        max_size = max(sizes)
        min_size = min(sizes)
        
        print("Size Distribution:")
        print(f"  Average: {format_file_size(avg_size)}")
        print(f"  Maximum: {format_file_size(max_size)}")
        print(f"  Minimum: {format_file_size(min_size)}")
        print()
    
    # Recent activity
    if station_dirs:
        recent_stations = sorted(station_dirs, key=lambda x: x.last_modified, reverse=True)[:5]
        
        print("Recent Activity (Top 5):")
        for station in recent_stations:
            modified_str = station.last_modified.strftime('%Y-%m-%d %H:%M')
            print(f"  {station.station_id}: {modified_str}")


def display_json_format(station_dirs: list, workflow_filter: Optional[str] = None) -> None:
    """
    Display station directories in JSON format.
    
    Args:
        station_dirs: List of StationDirectory objects
        workflow_filter: Optional workflow filter
    """
    import json
    
    # Filter stations if needed
    filtered_stations = []
    for station in station_dirs:
        if workflow_filter:
            if workflow_filter == "data" and not station.data_files:
                continue
            elif workflow_filter == "analysis" and not station.analysis_files:
                continue
            elif workflow_filter == "simulation" and not station.simulation_files:
                continue
            elif workflow_filter == "validation" and not station.validation_files:
                continue
        filtered_stations.append(station)
    
    # Create JSON structure
    output_data = {
        "summary": {
            "total_stations": len(filtered_stations),
            "total_size_mb": sum(station.total_size_mb for station in filtered_stations),
            "total_files": sum(
                len(station.data_files) + len(station.analysis_files) + 
                len(station.simulation_files) + len(station.validation_files)
                for station in filtered_stations
            )
        },
        "stations": []
    }
    
    for station in filtered_stations:
        station_data = {
            "station_id": station.station_id,
            "directory_path": str(station.directory_path),
            "total_size_mb": station.total_size_mb,
            "last_modified": station.last_modified.isoformat(),
            "file_counts": {
                "data": len(station.data_files),
                "analysis": len(station.analysis_files),
                "simulation": len(station.simulation_files),
                "validation": len(station.validation_files)
            },
            "workflows_completed": {
                "data_acquisition": len(station.data_files) > 0,
                "data_analysis": len(station.analysis_files) > 0,
                "simulation": len(station.simulation_files) > 0,
                "validation": len(station.validation_files) > 0
            }
        }
        output_data["stations"].append(station_data)
    
    print(json.dumps(output_data, indent=2))


def sort_stations(station_dirs: list, sort_by: str, reverse: bool = False) -> list:
    """
    Sort station directories by specified field.
    
    Args:
        station_dirs: List of StationDirectory objects
        sort_by: Field to sort by
        reverse: Whether to reverse sort order
        
    Returns:
        Sorted list of stations
    """
    if sort_by == "station":
        return sorted(station_dirs, key=lambda x: x.station_id, reverse=reverse)
    elif sort_by == "size":
        return sorted(station_dirs, key=lambda x: x.total_size_mb, reverse=reverse)
    elif sort_by == "modified":
        return sorted(station_dirs, key=lambda x: x.last_modified, reverse=reverse)
    elif sort_by == "files":
        return sorted(station_dirs, 
                     key=lambda x: len(x.data_files) + len(x.analysis_files) + 
                                  len(x.simulation_files) + len(x.validation_files),
                     reverse=reverse)
    else:
        return station_dirs


def execute(args) -> int:
    """
    Execute the list-outputs command.
    
    Args:
        args: Parsed command line arguments
        
    Returns:
        Exit code (0 for success, non-zero for error)
    """
    logger = get_logger("precipgen.cli.list_outputs")
    
    try:
        # Initialize directory manager
        dir_manager = DirectoryManager(args.output_dir or "./precipgen_output")
        
        # Get station directories
        if args.station:
            # Show specific station
            station_info = dir_manager.get_station_info(args.station, args.output_dir)
            if not station_info:
                print(f"Error: Station directory not found for {args.station}")
                return 1
            station_dirs = [station_info]
        else:
            # Show all stations
            station_dirs = dir_manager.list_station_directories(args.output_dir)
        
        if not station_dirs:
            print("No station directories found.")
            if not args.output_dir:
                print("Try running some workflows first or specify a different --output-dir")
            return 0
        
        # Sort stations
        station_dirs = sort_stations(station_dirs, args.sort_by, args.reverse)
        
        # Display based on format
        if args.format == "table":
            display_table_format(station_dirs, args.workflow)
        elif args.format == "json":
            display_json_format(station_dirs, args.workflow)
        else:  # summary
            display_summary_format(station_dirs)
        
        return 0
        
    except Exception as e:
        logger.error(f"Unexpected error in list-outputs command: {e}")
        print(f"Error: {e}")
        return 1