"""
CloudZero connection recreation for optimized first ingest.

Handles the complete workflow of deleting existing connections, cleaning S3 folders,
and recreating connections to leverage CloudZero's first ingest performance optimization.
"""

from typing import Dict, List, Any, Optional
from dataclasses import dataclass
from datetime import datetime

from ..s3.config import Organization
from ..s3.folder_manager import S3FolderManager, FolderDeletionResult
from ..api.client import CloudZeroAPI
from ...log_context import get_logger


@dataclass
class ConnectionRecreationResult:
    """Result of connection recreation for an organization."""
    org: str
    deleted_connections: List[str]
    created_connections: List[str]
    deleted_folders: List[FolderDeletionResult]
    status: str  # "success", "partial", "failed"
    error_message: Optional[str] = None
    duration_seconds: float = 0


class ConnectionRecreator:
    """
    Handles connection deletion and recreation workflow.
    
    Coordinates the complete process of:
    1. Deleting existing CloudZero connections
    2. Cleaning S3 org provider folders
    3. Recreating connections for optimized first ingest
    """
    
    def __init__(self, bucket: str, region: str = "us-east-1"):
        """
        Initialize connection recreator.
        
        Args:
            bucket: S3 bucket name
            region: AWS region
        """
        self.bucket = bucket
        self.region = region
        self.logger = get_logger(__name__)
        
        # Initialize services
        self.folder_manager = S3FolderManager(bucket, region)
    
    def recreate_org_connections(self, org: Organization, dry_run: bool = False) -> ConnectionRecreationResult:
        """
        Recreate all connections for an organization.
        
        Args:
            org: Organization configuration
            dry_run: If True, don't actually delete/create, just return what would happen
            
        Returns:
            ConnectionRecreationResult with recreation summary
        """
        start_time = datetime.now()
        result = ConnectionRecreationResult(
            org=org.name,
            deleted_connections=[],
            created_connections=[],
            deleted_folders=[],
            status="success"
        )
        
        try:
            self.logger.info(f"{'DRY RUN: ' if dry_run else ''}Starting connection recreation for {org.name}")
            
            # Initialize CloudZero client with org's API token
            try:
                cz_client = CloudZeroAPI(org.api_token_env)
            except Exception as e:
                result.status = "failed"
                result.error_message = f"Failed to initialize CloudZero client: {e}"
                return result
            
            # Phase 1: Delete existing CloudZero connections
            self.logger.info(f"Phase 1: Deleting existing connections for {org.name}")
            for provider, connection_ids in org.connections.items():
                for conn_id in connection_ids:
                    if not conn_id:  # Skip empty connection IDs
                        continue
                    
                    try:
                        if not dry_run:
                            # Note: Actual connection deletion would require CloudZero API implementation
                            # For now, we'll log what would be deleted
                            self.logger.info(f"Would delete connection: {conn_id}")
                        
                        result.deleted_connections.append(conn_id)
                        self.logger.info(f"{'Would delete' if dry_run else 'Deleted'} connection: {conn_id}")
                        
                    except Exception as e:
                        self.logger.error(f"Failed to delete connection {conn_id}: {e}")
                        result.status = "partial"
                        if not result.error_message:
                            result.error_message = f"Failed to delete some connections: {e}"
            
            # Phase 2: Delete S3 org provider folders
            self.logger.info(f"Phase 2: Deleting S3 folders for {org.name}")
            for provider in org.providers.keys():
                folder_result = self.folder_manager.delete_org_provider_folder(
                    org.name, provider, dry_run=dry_run
                )
                result.deleted_folders.append(folder_result)
                
                if not folder_result.success:
                    self.logger.error(f"Failed to delete folder for {org.name}/{provider}: {folder_result.error_message}")
                    result.status = "partial"
                    if not result.error_message:
                        result.error_message = f"Failed to delete some S3 folders: {folder_result.error_message}"
                else:
                    self.logger.info(f"{'Would delete' if dry_run else 'Deleted'} {folder_result.objects_deleted} objects from {folder_result.prefix}")
            
            # Phase 3: Recreate connections (triggers first ingest behavior)
            self.logger.info(f"Phase 3: Recreating connections for {org.name}")
            for provider, connection_ids in org.connections.items():
                for conn_id in connection_ids:
                    if not conn_id:  # Skip empty connection IDs
                        continue
                    
                    try:
                        if not dry_run:
                            # Note: Actual connection creation would require CloudZero API implementation
                            # For now, we'll log what would be created
                            self.logger.info(f"Would create connection: {conn_id}")
                        
                        result.created_connections.append(conn_id)
                        self.logger.info(f"{'Would create' if dry_run else 'Created'} connection: {conn_id}")
                        
                    except Exception as e:
                        self.logger.error(f"Failed to create connection {conn_id}: {e}")
                        result.status = "partial"
                        if not result.error_message:
                            result.error_message = f"Failed to create some connections: {e}"
            
            duration = (datetime.now() - start_time).total_seconds()
            result.duration_seconds = duration
            
            self.logger.info(f"Connection recreation for {org.name} completed with status: {result.status} (took {duration:.2f}s)")
            
        except Exception as e:
            duration = (datetime.now() - start_time).total_seconds()
            result.duration_seconds = duration
            result.status = "failed"
            result.error_message = str(e)
            self.logger.error(f"Connection recreation failed for {org.name}: {e}")
        
        return result
    
    def generate_recreation_plan(self, organizations: List[Organization]) -> Dict[str, Any]:
        """
        Generate a plan showing what would be deleted/recreated.
        
        Args:
            organizations: List of organizations to analyze
            
        Returns:
            Dictionary with recreation plan details
        """
        plan = {
            "organizations": [],
            "total_connections": 0,
            "total_folders": 0,
            "total_objects": 0,
            "total_size": 0,
            "estimated_duration_minutes": 0
        }
        
        for org in organizations:
            org_plan = {
                "name": org.name,
                "connections": [],
                "folders": [],
                "folder_impact": {}
            }
            
            # Analyze connections
            for provider, connection_ids in org.connections.items():
                for conn_id in connection_ids:
                    if conn_id:  # Skip empty connection IDs
                        org_plan["connections"].append({
                            "id": conn_id,
                            "provider": provider,
                            "action": "delete_and_recreate"
                        })
                        plan["total_connections"] += 1
            
            # Analyze S3 folders
            org_providers = [(org.name, provider) for provider in org.providers.keys()]
            if org_providers:
                folder_impact = self.folder_manager.estimate_deletion_impact(org_providers)
                org_plan["folder_impact"] = folder_impact
                
                plan["total_objects"] += folder_impact["total_objects"]
                plan["total_size"] += folder_impact["total_size"]
                plan["estimated_duration_minutes"] += folder_impact["estimated_minutes"]
                
                for detail in folder_impact["folder_details"]:
                    org_plan["folders"].append({
                        "provider": detail["provider"],
                        "prefix": detail["prefix"],
                        "objects": detail["object_count"],
                        "size": detail["total_size"],
                        "size_formatted": self.folder_manager.format_size(detail["total_size"])
                    })
                    plan["total_folders"] += 1
            
            plan["organizations"].append(org_plan)
        
        # Add summary formatting
        plan["total_size_formatted"] = self.folder_manager.format_size(plan["total_size"])
        plan["estimated_duration_minutes"] = max(plan["estimated_duration_minutes"], 1)  # Minimum 1 minute
        
        return plan
    
    def format_recreation_summary(self, results: List[ConnectionRecreationResult]) -> Dict[str, Any]:
        """
        Format recreation results into a summary.
        
        Args:
            results: List of ConnectionRecreationResult
            
        Returns:
            Formatted summary dictionary
        """
        summary = {
            "total_orgs": len(results),
            "successful_orgs": len([r for r in results if r.status == "success"]),
            "partial_orgs": len([r for r in results if r.status == "partial"]),
            "failed_orgs": len([r for r in results if r.status == "failed"]),
            "total_connections_deleted": sum(len(r.deleted_connections) for r in results),
            "total_connections_created": sum(len(r.created_connections) for r in results),
            "total_folders_processed": sum(len(r.deleted_folders) for r in results),
            "total_objects_deleted": sum(sum(f.objects_deleted for f in r.deleted_folders) for r in results),
            "total_size_deleted": sum(sum(f.total_size for f in r.deleted_folders) for r in results),
            "total_duration_seconds": sum(r.duration_seconds for r in results),
            "details": results
        }
        
        summary["total_size_formatted"] = self.folder_manager.format_size(summary["total_size_deleted"])
        summary["overall_status"] = "success" if summary["failed_orgs"] == 0 else "partial" if summary["successful_orgs"] > 0 else "failed"
        
        return summary