use super::error_types::{WorkflowError, ErrorSeverity};
use anyhow::{Result, anyhow};
use std::time::Duration;
use tokio::time::sleep;
use tracing::{debug, info, warn, error};

/// 错误恢复策略
#[derive(Debug, Clone)]
pub enum RecoveryStrategy {
    /// 立即重试
    ImmediateRetry,
    /// 延迟重试
    DelayedRetry { delay_seconds: u64 },
    /// 指数退避重试
    ExponentialBackoff { base_delay_seconds: u64, max_delay_seconds: u64 },
    /// 降级服务
    Fallback,
    /// 失败快速返回
    FailFast,
    /// 断路器模式
    CircuitBreaker,
}

/// 重试配置
#[derive(Debug, Clone)]
pub struct RetryConfig {
    pub max_attempts: u32,
    pub strategy: RecoveryStrategy,
    pub timeout_seconds: Option<u64>,
}

impl Default for RetryConfig {
    fn default() -> Self {
        Self {
            max_attempts: 3,
            strategy: RecoveryStrategy::ExponentialBackoff {
                base_delay_seconds: 1,
                max_delay_seconds: 60,
            },
            timeout_seconds: Some(300), // 5分钟
        }
    }
}

/// 错误恢复管理器
pub struct ErrorRecoveryManager {
    retry_configs: std::collections::HashMap<String, RetryConfig>,
}

impl ErrorRecoveryManager {
    /// 创建新的错误恢复管理器
    pub fn new() -> Self {
        let mut manager = Self {
            retry_configs: std::collections::HashMap::new(),
        };

        // 设置默认重试配置
        manager.setup_default_configs();
        manager
    }

    /// 设置默认重试配置
    fn setup_default_configs(&mut self) {
        // 数据库操作重试配置
        self.retry_configs.insert("database".to_string(), RetryConfig {
            max_attempts: 5,
            strategy: RecoveryStrategy::ExponentialBackoff {
                base_delay_seconds: 1,
                max_delay_seconds: 30,
            },
            timeout_seconds: Some(60),
        });

        // 网络请求重试配置
        self.retry_configs.insert("network".to_string(), RetryConfig {
            max_attempts: 3,
            strategy: RecoveryStrategy::ExponentialBackoff {
                base_delay_seconds: 2,
                max_delay_seconds: 60,
            },
            timeout_seconds: Some(120),
        });

        // 工作流执行重试配置
        self.retry_configs.insert("execution".to_string(), RetryConfig {
            max_attempts: 2,
            strategy: RecoveryStrategy::DelayedRetry { delay_seconds: 30 },
            timeout_seconds: Some(3600), // 1小时
        });

        // 文件操作重试配置
        self.retry_configs.insert("filesystem".to_string(), RetryConfig {
            max_attempts: 3,
            strategy: RecoveryStrategy::DelayedRetry { delay_seconds: 5 },
            timeout_seconds: Some(60),
        });
    }

    /// 执行带重试的操作
    pub async fn execute_with_retry<F, T, E>(
        &self,
        operation_type: &str,
        operation: F,
    ) -> Result<T>
    where
        F: Fn() -> Result<T, E> + Send + Sync,
        E: Into<WorkflowError> + std::fmt::Debug,
        T: Send,
    {
        let default_config = RetryConfig::default();
        let config = self.retry_configs.get(operation_type)
            .unwrap_or(&default_config);

        let mut last_error: Option<WorkflowError> = None;
        let mut attempt = 0;

        while attempt < config.max_attempts {
            attempt += 1;

            match operation() {
                Ok(result) => {
                    if attempt > 1 {
                        info!("操作在第{}次尝试后成功: {}", attempt, operation_type);
                    }
                    return Ok(result);
                }
                Err(error) => {
                    let workflow_error = error.into();
                    last_error = Some(workflow_error.clone());

                    warn!("操作失败 (尝试 {}/{}): {} - {}", 
                          attempt, config.max_attempts, operation_type, workflow_error);

                    // 检查是否可重试
                    if !workflow_error.is_retryable() {
                        error!("错误不可重试，停止尝试: {}", workflow_error);
                        break;
                    }

                    // 如果还有重试机会，计算延迟
                    if attempt < config.max_attempts {
                        let delay = self.calculate_delay(&config.strategy, attempt);
                        debug!("等待 {} 秒后重试", delay);
                        sleep(Duration::from_secs(delay)).await;
                    }
                }
            }
        }

        // 所有重试都失败了
        if let Some(error) = last_error {
            error!("操作最终失败，已用尽所有重试机会: {} - {}", operation_type, error);
            Err(anyhow::anyhow!("操作失败: {}", error))
        } else {
            Err(anyhow::anyhow!("操作失败，原因未知"))
        }
    }

    /// 计算重试延迟
    fn calculate_delay(&self, strategy: &RecoveryStrategy, attempt: u32) -> u64 {
        match strategy {
            RecoveryStrategy::ImmediateRetry => 0,
            RecoveryStrategy::DelayedRetry { delay_seconds } => *delay_seconds,
            RecoveryStrategy::ExponentialBackoff { base_delay_seconds, max_delay_seconds } => {
                let delay = base_delay_seconds * 2_u64.pow(attempt.saturating_sub(1));
                delay.min(*max_delay_seconds)
            }
            RecoveryStrategy::Fallback => 0,
            RecoveryStrategy::FailFast => 0,
            RecoveryStrategy::CircuitBreaker => 5, // 简化实现
        }
    }

    /// 设置操作类型的重试配置
    pub fn set_retry_config(&mut self, operation_type: String, config: RetryConfig) {
        self.retry_configs.insert(operation_type, config);
    }

    /// 获取操作类型的重试配置
    pub fn get_retry_config(&self, operation_type: &str) -> Option<&RetryConfig> {
        self.retry_configs.get(operation_type)
    }
}

/// 断路器状态
#[derive(Debug, Clone)]
pub enum CircuitBreakerState {
    Closed,  // 正常状态
    Open,    // 断开状态
    HalfOpen, // 半开状态
}

/// 断路器配置
#[derive(Debug, Clone)]
pub struct CircuitBreakerConfig {
    pub failure_threshold: u32,
    pub success_threshold: u32,
    pub timeout_seconds: u64,
    pub reset_timeout_seconds: u64,
}

impl Default for CircuitBreakerConfig {
    fn default() -> Self {
        Self {
            failure_threshold: 5,
            success_threshold: 3,
            timeout_seconds: 60,
            reset_timeout_seconds: 300,
        }
    }
}

/// 断路器实现
pub struct CircuitBreaker {
    config: CircuitBreakerConfig,
    state: CircuitBreakerState,
    failure_count: u32,
    success_count: u32,
    last_failure_time: Option<std::time::Instant>,
}

impl CircuitBreaker {
    /// 创建新的断路器
    pub fn new(config: CircuitBreakerConfig) -> Self {
        Self {
            config,
            state: CircuitBreakerState::Closed,
            failure_count: 0,
            success_count: 0,
            last_failure_time: None,
        }
    }

    /// 执行操作
    pub async fn execute<F, T, E>(&mut self, operation: F) -> Result<T, E>
    where
        F: Fn() -> Result<T, E> + Send + Sync,
        E: std::fmt::Debug + std::convert::From<anyhow::Error>,
    {
        // 检查断路器状态
        match self.state {
            CircuitBreakerState::Open => {
                if let Some(last_failure) = self.last_failure_time {
                    if last_failure.elapsed().as_secs() > self.config.reset_timeout_seconds {
                        self.state = CircuitBreakerState::HalfOpen;
                        self.success_count = 0;
                        debug!("断路器状态变更为半开");
                    } else {
                        // 快速失败，返回一个通用错误
                        return Err(anyhow!("断路器开启，拒绝请求").into());
                    }
                }
            }
            CircuitBreakerState::HalfOpen => {
                // 在半开状态下，允许少量请求通过
            }
            CircuitBreakerState::Closed => {
                // 正常状态，允许所有请求
            }
        }

        // 执行操作
        match operation() {
            Ok(result) => {
                self.on_success();
                Ok(result)
            }
            Err(error) => {
                self.on_failure();
                Err(error)
            }
        }
    }

    /// 处理成功情况
    fn on_success(&mut self) {
        match self.state {
            CircuitBreakerState::HalfOpen => {
                self.success_count += 1;
                if self.success_count >= self.config.success_threshold {
                    self.state = CircuitBreakerState::Closed;
                    self.failure_count = 0;
                    self.success_count = 0;
                    info!("断路器状态变更为关闭（正常）");
                }
            }
            CircuitBreakerState::Closed => {
                self.failure_count = 0;
            }
            _ => {}
        }
    }

    /// 处理失败情况
    fn on_failure(&mut self) {
        self.failure_count += 1;
        self.last_failure_time = Some(std::time::Instant::now());

        match self.state {
            CircuitBreakerState::Closed => {
                if self.failure_count >= self.config.failure_threshold {
                    self.state = CircuitBreakerState::Open;
                    warn!("断路器状态变更为打开（断开）");
                }
            }
            CircuitBreakerState::HalfOpen => {
                self.state = CircuitBreakerState::Open;
                warn!("断路器状态从半开变更为打开");
            }
            _ => {}
        }
    }

    /// 获取当前状态
    pub fn get_state(&self) -> &CircuitBreakerState {
        &self.state
    }

    /// 重置断路器
    pub fn reset(&mut self) {
        self.state = CircuitBreakerState::Closed;
        self.failure_count = 0;
        self.success_count = 0;
        self.last_failure_time = None;
        info!("断路器已重置");
    }
}

/// 降级服务管理器
pub struct FallbackManager {
    fallback_handlers: std::collections::HashMap<String, Box<dyn Fn() -> Result<serde_json::Value> + Send + Sync>>,
}

impl FallbackManager {
    /// 创建新的降级服务管理器
    pub fn new() -> Self {
        Self {
            fallback_handlers: std::collections::HashMap::new(),
        }
    }

    /// 注册降级处理器
    pub fn register_fallback<F>(&mut self, service_name: String, handler: F)
    where
        F: Fn() -> Result<serde_json::Value> + Send + Sync + 'static,
    {
        self.fallback_handlers.insert(service_name, Box::new(handler));
    }

    /// 执行降级服务
    pub fn execute_fallback(&self, service_name: &str) -> Result<serde_json::Value> {
        if let Some(handler) = self.fallback_handlers.get(service_name) {
            warn!("执行降级服务: {}", service_name);
            handler()
        } else {
            Err(anyhow::anyhow!("未找到降级服务处理器: {}", service_name))
        }
    }
}

impl Default for ErrorRecoveryManager {
    fn default() -> Self {
        Self::new()
    }
}
