"""
Repeat step executor for executing nested steps multiple times.
"""

from typing import Dict, Any
from ...utils import console
from .base import BaseStep
from .install import InstallApplicationStep
from .context import CreateContextStep
from .identity import CreateIdentityStep, InviteIdentityStep
from .join import JoinContextStep
from .execute import ExecuteStep
from .wait import WaitStep


class RepeatStep(BaseStep):
    """Execute nested steps multiple times."""
    
    def _get_exportable_variables(self):
        """
        Define which variables this step can export.
        
        Available variables from repeat execution:
        - iteration: Current iteration number (1-based)
        - iteration_index: Current iteration index (0-based)
        - iteration_zero_based: Current iteration index (0-based, alias)
        - iteration_one_based: Current iteration number (1-based, alias)
        - total_iterations: Total number of iterations
        - current_step: Current step being executed
        - step_count: Total number of nested steps
        """
        return [
            ('iteration', 'iteration', 'Current iteration number (1-based)'),
            ('iteration_index', 'iteration_index', 'Current iteration index (0-based)'),
            ('iteration_zero_based', 'iteration_zero_based', 'Current iteration index (0-based, alias)'),
            ('iteration_one_based', 'iteration_one_based', 'Current iteration number (1-based, alias)'),
            ('total_iterations', 'total_iterations', 'Total number of iterations'),
            ('current_step', 'current_step', 'Current step being executed'),
            ('step_count', 'step_count', 'Total number of nested steps'),
        ]
    
    async def execute(self, workflow_results: Dict[str, Any], dynamic_values: Dict[str, Any]) -> bool:
        repeat_count = self.config.get('count', 1)
        nested_steps = self.config.get('steps', [])
        step_name = self.config.get('name', 'Repeat Step')
        
        # Validate export configuration
        if not self._validate_export_config():
            console.print(f"[yellow]⚠️  Repeat step export configuration validation failed[/yellow]")
        
        if not nested_steps:
            console.print("[yellow]No nested steps specified for repeat[/yellow]")
            return True
        
        console.print(f"[cyan]🔄 Executing {len(nested_steps)} nested steps {repeat_count} times...[/cyan]")
        
        # Export repeat configuration variables
        dynamic_values['total_iterations'] = repeat_count
        dynamic_values['step_count'] = len(nested_steps)
        console.print(f"[blue]📝 Exported repeat configuration: total_iterations={repeat_count}, step_count={len(nested_steps)}[/blue]")
        
        for iteration in range(repeat_count):
            console.print(f"\n[bold blue]📋 Iteration {iteration + 1}/{repeat_count}[/bold blue]")
            
            # Create iteration-specific dynamic values
            iteration_dynamic_values = dynamic_values.copy()
            iteration_dynamic_values.update({
                'iteration': iteration + 1,
                'iteration_index': iteration,
                'iteration_zero_based': iteration,
                'iteration_one_based': iteration + 1
            })
            
            # Process custom outputs configuration for this iteration
            self._export_iteration_variables(iteration + 1, iteration_dynamic_values)
            
            # Execute each nested step in sequence
            for step_idx, step in enumerate(nested_steps):
                step_type = step.get('type')
                nested_step_name = step.get('name', f"Nested Step {step_idx + 1}")
                
                # Update current step information
                iteration_dynamic_values['current_step'] = nested_step_name
                iteration_dynamic_values['current_step_index'] = step_idx + 1
                
                console.print(f"  [cyan]Executing {nested_step_name} ({step_type})...[/cyan]")
                
                try:
                    # Create appropriate step executor for the nested step
                    step_executor = self._create_nested_step_executor(step_type, step)
                    if not step_executor:
                        console.print(f"[red]Unknown nested step type: {step_type}[/red]")
                        return False
                    
                    # Execute the nested step with iteration-specific dynamic values
                    success = await step_executor.execute(workflow_results, iteration_dynamic_values)
                    
                    if not success:
                        console.print(f"[red]❌ Nested step '{nested_step_name}' failed in iteration {iteration + 1}[/red]")
                        return False
                    
                    console.print(f"  [green]✓ Nested step '{nested_step_name}' completed in iteration {iteration + 1}[/green]")
                    
                except Exception as e:
                    console.print(f"[red]❌ Nested step '{nested_step_name}' failed with error in iteration {iteration + 1}: {str(e)}[/red]")
                    return False
        
        console.print(f"[green]✓ All {repeat_count} iterations completed successfully[/green]")
        return True
    
    def _export_iteration_variables(self, iteration: int, dynamic_values: Dict[str, Any]) -> None:
        """Export iteration variables based on custom outputs configuration."""
        outputs_config = self.config.get('outputs', {})
        if not outputs_config:
            return
        
        console.print(f"[blue]📝 Processing custom outputs for iteration {iteration}...[/blue]")
        
        for export_name, export_config in outputs_config.items():
            if isinstance(export_config, str):
                # Simple field assignment (e.g., current_iteration: iteration)
                source_field = export_config
                if source_field in dynamic_values:
                    source_value = dynamic_values[source_field]
                    dynamic_values[export_name] = source_value
                    console.print(f"  📝 Custom export: {source_field} → {export_name}: {source_value}")
                else:
                    console.print(f"[yellow]Warning: Source field {source_field} not found in dynamic values[/yellow]")
            elif isinstance(export_config, dict):
                # Complex field assignment with node name replacement
                source_field = export_config.get('field')
                target_template = export_config.get('target')
                if source_field and target_template and 'node_name' in target_template:
                    if source_field in dynamic_values:
                        source_value = dynamic_values[source_field]
                        # For repeat steps, we don't have node names, so just use the source value
                        dynamic_values[export_name] = source_value
                        console.print(f"  📝 Custom export: {source_field} → {export_name}: {source_value}")
                    else:
                        console.print(f"[yellow]Warning: Source field {source_field} not found in dynamic values[/yellow]")
    
    def _create_nested_step_executor(self, step_type: str, step_config: Dict[str, Any]):
        """Create a nested step executor based on the step type."""
        if step_type == 'install_application':
            from . import InstallApplicationStep
            return InstallApplicationStep(step_config)
        elif step_type == 'create_context':
            from . import CreateContextStep
            return CreateContextStep(step_config)
        elif step_type == 'create_identity':
            from . import CreateIdentityStep
            return CreateIdentityStep(step_config)
        elif step_type == 'invite_identity':
            from . import InviteIdentityStep
            return InviteIdentityStep(step_config)
        elif step_type == 'join_context':
            from . import JoinContextStep
            return JoinContextStep(step_config)
        elif step_type == 'call':
            from . import ExecuteStep
            return ExecuteStep(step_config)
        elif step_type == 'wait':
            from . import WaitStep
            return WaitStep(step_config)
        elif step_type == 'script':
            from . import ScriptStep
            return ScriptStep(step_config)
        else:
            console.print(f"[red]Unknown nested step type: {step_type}[/red]")
            return None
