"""
Bridge service for integrating append operations with existing upload workflow.

Coordinates between append copy operations and the existing upload services
to ensure both phases use the same drop IDs and work together seamlessly.
"""

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

from .append_orchestrator import AppendUploadOrchestrator, AppendPlan
from ..models import UploadConfig, OrganizationResult, WorkflowResult
from src.services.upload_workflow_methods import UploadWorkflowMethods


@dataclass
class AppendWorkflowResult:
    """Combined result from append copy + upload operations."""
    copy_phase_result: Dict[str, Any]
    upload_phase_result: Dict[str, OrganizationResult]
    overall_status: str
    total_files_copied: int
    total_files_uploaded: int


class AppendWorkflowBridge:
    """
    Bridge service for coordinating append operations with existing workflow.
    
    Single responsibility: Coordinate copy and upload phases while maintaining
    compatibility with existing upload infrastructure.
    """
    
    def __init__(
        self,
        append_orchestrator: AppendUploadOrchestrator,
        upload_workflow: UploadWorkflowMethods
    ):
        """
        Initialize with dependencies.
        
        Args:
            append_orchestrator: Orchestrator for append copy operations
            upload_workflow: Existing upload workflow methods
        """
        self.append_orchestrator = append_orchestrator
        self.upload_workflow = upload_workflow
    
    def execute_integrated_append_workflow(
        self, 
        config: UploadConfig, 
        dry_run: bool = False
    ) -> WorkflowResult:
        """
        Execute integrated append workflow with both copy and upload phases.
        
        For now, this runs the copy phase followed by a separate upload phase.
        In a future iteration, these could be better coordinated to use the same drop IDs.
        
        Args:
            config: Upload configuration with append_mode=True
            dry_run: Whether to perform dry run validation only
            
        Returns:
            WorkflowResult compatible with existing workflow interface
        """
        if not config.is_append_mode():
            raise ValueError("Integrated append workflow requires append_mode=True")
        
        print(f"🔄 Starting integrated append workflow ({'dry-run' if dry_run else 'live mode'})")
        
        if dry_run:
            return self._execute_dry_run_workflow(config)
        else:
            return self._execute_live_workflow(config)
    
    def _execute_dry_run_workflow(self, config: UploadConfig) -> WorkflowResult:
        """Execute dry-run validation for integrated append workflow."""
        print("🧪 Dry-run mode: Validating append workflow")
        
        # Run append orchestrator in dry-run mode
        append_results = self.append_orchestrator.execute_append_workflow(config, dry_run=True)
        
        # Run existing workflow validation
        upload_results = self.upload_workflow.execute_upload_workflow(config, dry_run=True)
        
        # Combine results
        successful_orgs = len([r for r in append_results.values() if r.is_successful()])
        total_orgs = len(append_results)
        
        if successful_orgs == total_orgs:
            status = "success"
        elif successful_orgs > 0:
            status = "partial"
        else:
            status = "failed"
        
        return WorkflowResult(
            status=status,
            dataset=config.dataset_name or "append-operation",
            organizations_processed=total_orgs,
            organizations_successful=successful_orgs,
            results=append_results,
            mode="dry_run_append"
        )
    
    def _execute_live_workflow(self, config: UploadConfig) -> WorkflowResult:
        """Execute live append workflow with copy + upload phases."""
        print("🚀 Live mode: Executing append workflow")
        
        results = {}
        total_copied = 0
        total_uploaded = 0
        
        for org in config.organizations:
            print(f"\n🏢 Processing organization: {org.name}")
            
            try:
                # Phase 1: Execute copy phase
                copy_result = self.append_orchestrator.execute_pre_upload_copy_phase(config, org)
                
                if copy_result['status'] == 'no_plans':
                    print(f"   ℹ️  No append operations needed for {org.name}")
                    results[org.name] = OrganizationResult(
                        organization=org.name,
                        status="success",
                        files_uploaded=0,
                        providers=org.providers
                    )
                    continue
                
                copied_files = copy_result.get('copied_files', 0)
                copy_errors = copy_result.get('copy_errors', [])
                total_copied += copied_files
                
                if copy_errors:
                    print(f"   ⚠️  {len(copy_errors)} copy errors for {org.name}")
                
                # Phase 2: Execute upload phase for new data
                # Note: This will create separate drops from the copy phase
                # In a future iteration, we'd coordinate drop IDs between phases
                print(f"   📤 Uploading new data for {org.name}")
                
                # Create single-org config for upload workflow
                org_config = self._create_single_org_config(config, org)
                
                upload_result = self.upload_workflow.execute_upload_workflow(org_config, dry_run=False)
                
                # Extract organization result
                org_upload_result = upload_result.results.get(org.name)
                if org_upload_result:
                    uploaded_files = org_upload_result.files_uploaded
                    total_uploaded += uploaded_files
                    
                    # Combine copy and upload results
                    combined_result = OrganizationResult(
                        organization=org.name,
                        status="success" if not copy_errors and org_upload_result.is_successful() else "partial",
                        files_uploaded=copied_files + uploaded_files,
                        files_failed=len(copy_errors) + org_upload_result.files_failed,
                        providers=org.providers,
                        uploaded_files=org_upload_result.uploaded_files,
                        failed_files=copy_errors + (org_upload_result.failed_files or [])
                    )
                else:
                    # Upload failed
                    combined_result = OrganizationResult(
                        organization=org.name,
                        status="partial" if copied_files > 0 else "failed",
                        files_uploaded=copied_files,
                        files_failed=len(copy_errors),
                        providers=org.providers,
                        failed_files=copy_errors
                    )
                
                results[org.name] = combined_result
                
                # Status reporting
                if combined_result.is_successful():
                    print(f"   ✅ {org.name}: {copied_files} copied + {uploaded_files} uploaded")
                elif combined_result.is_partial():
                    total_ops = copied_files + uploaded_files
                    failed_ops = combined_result.files_failed
                    print(f"   ⚠️  {org.name}: {total_ops} completed, {failed_ops} failed")
                else:
                    print(f"   ❌ {org.name}: All operations failed")
                    
            except Exception as e:
                print(f"   ❌ Workflow failed for {org.name}: {str(e)}")
                results[org.name] = OrganizationResult(
                    organization=org.name,
                    status="failed",
                    error_message=f"Append workflow failed: {str(e)}",
                    providers=org.providers
                )
        
        # Calculate overall status
        successful_orgs = len([r for r in results.values() if r.is_successful()])
        total_orgs = len(results)
        
        if successful_orgs == total_orgs:
            status = "success"
        elif successful_orgs > 0:
            status = "partial"  
        else:
            status = "failed"
        
        return WorkflowResult(
            status=status,
            dataset=config.dataset_name or "append-operation",
            organizations_processed=total_orgs,
            organizations_successful=successful_orgs,
            results=results,
            total_files=total_copied + total_uploaded,
            mode="append"
        )
    
    def _create_single_org_config(self, config: UploadConfig, org) -> UploadConfig:
        """
        Create a config with just one organization for the upload phase.
        
        This allows us to process one organization at a time through the
        existing upload workflow.
        """
        from dataclasses import replace
        
        return replace(
            config,
            organizations=[org],
            append_mode=False  # Don't trigger append mode in the upload phase
        )