use anyhow::Result;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, VecDeque};
use std::sync::{Arc, Mutex};
use tokio::time::{interval, Duration as TokioDuration};
use tracing::{debug, info, warn};

use crate::data::models::workflow_execution_record::ExecutionStatus;
use crate::data::repositories::workflow_execution_record_repository::WorkflowExecutionRecordRepository;
use crate::data::repositories::workflow_execution_environment_repository::WorkflowExecutionEnvironmentRepository;

/// 工作流执行队列管理服务
/// 负责管理执行队列、任务调度和负载均衡
#[derive(Clone)]
pub struct WorkflowQueueService {
    execution_record_repository: WorkflowExecutionRecordRepository,
    execution_environment_repository: WorkflowExecutionEnvironmentRepository,
    queue_state: Arc<Mutex<QueueState>>,
    config: QueueConfig,
}

/// 队列配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct QueueConfig {
    /// 最大队列长度
    pub max_queue_length: u32,
    /// 队列检查间隔（秒）
    pub queue_check_interval_seconds: u64,
    /// 任务超时时间（秒）
    pub task_timeout_seconds: u64,
    /// 最大重试次数
    pub max_retry_attempts: u32,
    /// 负载均衡策略
    pub load_balancing_strategy: LoadBalancingStrategy,
}

/// 负载均衡策略
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum LoadBalancingStrategy {
    RoundRobin,
    LeastLoaded,
    HighestPriority,
    WeightedRandom,
}

/// 队列状态
#[derive(Debug)]
struct QueueState {
    /// 待执行队列
    pending_queue: VecDeque<QueuedExecution>,
    /// 正在执行的任务
    running_executions: HashMap<i64, RunningExecution>,
    /// 环境轮询索引（用于轮询策略）
    round_robin_index: usize,
}

/// 队列中的执行任务
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct QueuedExecution {
    pub execution_id: i64,
    pub workflow_template_id: i64,
    pub priority: i32,
    pub queued_at: DateTime<Utc>,
    pub retry_count: u32,
    pub preferred_environment_id: Option<i64>,
    pub estimated_duration_seconds: Option<u32>,
}

/// 正在执行的任务
#[derive(Debug, Clone)]
struct RunningExecution {
    pub execution_id: i64,
    pub environment_id: i64,
    pub started_at: DateTime<Utc>,
    pub estimated_completion: Option<DateTime<Utc>>,
}

/// 队列统计信息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct QueueStatistics {
    pub total_pending: u32,
    pub total_running: u32,
    pub average_wait_time_seconds: Option<f64>,
    pub average_execution_time_seconds: Option<f64>,
    pub queue_throughput_per_hour: f64,
    pub environment_utilization: HashMap<i64, f64>,
    pub priority_distribution: HashMap<i32, u32>,
}

/// 队列操作结果
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct QueueOperationResult {
    pub success: bool,
    pub message: String,
    pub execution_id: Option<i64>,
    pub queue_position: Option<u32>,
}

impl Default for QueueConfig {
    fn default() -> Self {
        Self {
            max_queue_length: 1000,
            queue_check_interval_seconds: 5,
            task_timeout_seconds: 3600, // 1小时
            max_retry_attempts: 3,
            load_balancing_strategy: LoadBalancingStrategy::LeastLoaded,
        }
    }
}

impl WorkflowQueueService {
    /// 创建新的队列服务
    pub fn new(
        execution_record_repository: WorkflowExecutionRecordRepository,
        execution_environment_repository: WorkflowExecutionEnvironmentRepository,
        config: Option<QueueConfig>,
    ) -> Self {
        let queue_state = Arc::new(Mutex::new(QueueState {
            pending_queue: VecDeque::new(),
            running_executions: HashMap::new(),
            round_robin_index: 0,
        }));

        Self {
            execution_record_repository,
            execution_environment_repository,
            queue_state,
            config: config.unwrap_or_default(),
        }
    }

    /// 启动队列管理服务
    pub async fn start_queue_management(&self) -> Result<()> {
        info!("启动工作流队列管理服务");

        // 恢复队列状态
        self.restore_queue_state().await?;

        // 启动队列处理循环
        let queue_service = self.clone();
        tokio::spawn(async move {
            queue_service.run_queue_processing_loop().await;
        });

        // 启动超时检查循环
        let timeout_service = self.clone();
        tokio::spawn(async move {
            timeout_service.run_timeout_check_loop().await;
        });

        Ok(())
    }

    /// 将执行任务加入队列
    pub async fn enqueue_execution(&self, queued_execution: QueuedExecution) -> Result<QueueOperationResult> {
        let mut state = self.queue_state.lock().unwrap();
        
        // 检查队列长度限制
        if state.pending_queue.len() >= self.config.max_queue_length as usize {
            return Ok(QueueOperationResult {
                success: false,
                message: "队列已满，无法添加新任务".to_string(),
                execution_id: Some(queued_execution.execution_id),
                queue_position: None,
            });
        }

        // 按优先级插入队列
        let insert_position = state.pending_queue
            .iter()
            .position(|item| item.priority < queued_execution.priority)
            .unwrap_or(state.pending_queue.len());

        state.pending_queue.insert(insert_position, queued_execution.clone());

        info!("任务加入队列: 执行ID {}, 队列位置 {}", 
              queued_execution.execution_id, insert_position + 1);

        Ok(QueueOperationResult {
            success: true,
            message: "任务已加入队列".to_string(),
            execution_id: Some(queued_execution.execution_id),
            queue_position: Some(insert_position as u32 + 1),
        })
    }

    /// 从队列中移除执行任务
    pub async fn dequeue_execution(&self, execution_id: i64) -> Result<QueueOperationResult> {
        let mut state = self.queue_state.lock().unwrap();
        
        // 从待执行队列中移除
        if let Some(position) = state.pending_queue.iter().position(|item| item.execution_id == execution_id) {
            state.pending_queue.remove(position);
            
            info!("从队列中移除任务: 执行ID {}", execution_id);
            
            return Ok(QueueOperationResult {
                success: true,
                message: "任务已从队列中移除".to_string(),
                execution_id: Some(execution_id),
                queue_position: None,
            });
        }

        // 从正在执行的任务中移除
        if state.running_executions.remove(&execution_id).is_some() {
            info!("停止正在执行的任务: 执行ID {}", execution_id);
            
            return Ok(QueueOperationResult {
                success: true,
                message: "正在执行的任务已停止".to_string(),
                execution_id: Some(execution_id),
                queue_position: None,
            });
        }

        Ok(QueueOperationResult {
            success: false,
            message: "未找到指定的执行任务".to_string(),
            execution_id: Some(execution_id),
            queue_position: None,
        })
    }

    /// 获取队列统计信息
    pub async fn get_queue_statistics(&self) -> Result<QueueStatistics> {
        let state = self.queue_state.lock().unwrap();
        
        let total_pending = state.pending_queue.len() as u32;
        let total_running = state.running_executions.len() as u32;

        // 计算平均等待时间
        let now = Utc::now();
        let average_wait_time = if !state.pending_queue.is_empty() {
            let total_wait_time: i64 = state.pending_queue.iter()
                .map(|item| (now - item.queued_at).num_seconds())
                .sum();
            Some(total_wait_time as f64 / state.pending_queue.len() as f64)
        } else {
            None
        };

        // 计算优先级分布
        let mut priority_distribution = HashMap::new();
        for item in &state.pending_queue {
            *priority_distribution.entry(item.priority).or_insert(0) += 1;
        }

        // 计算环境利用率
        let environment_utilization = self.calculate_environment_utilization().await?;

        // 简化的吞吐量计算（实际应该基于历史数据）
        let queue_throughput_per_hour = 10.0; // 占位值

        Ok(QueueStatistics {
            total_pending,
            total_running,
            average_wait_time_seconds: average_wait_time,
            average_execution_time_seconds: None, // 需要从历史数据计算
            queue_throughput_per_hour,
            environment_utilization,
            priority_distribution,
        })
    }

    /// 获取队列中的任务列表
    pub async fn get_queued_executions(&self) -> Result<Vec<QueuedExecution>> {
        let state = self.queue_state.lock().unwrap();
        Ok(state.pending_queue.iter().cloned().collect())
    }

    /// 获取正在执行的任务列表
    pub async fn get_running_executions(&self) -> Result<Vec<RunningExecution>> {
        let state = self.queue_state.lock().unwrap();
        Ok(state.running_executions.values().cloned().collect())
    }

    /// 队列处理循环
    async fn run_queue_processing_loop(&self) {
        let mut interval = interval(TokioDuration::from_secs(self.config.queue_check_interval_seconds));

        loop {
            interval.tick().await;
            
            if let Err(e) = self.process_queue().await {
                warn!("队列处理失败: {}", e);
            }
        }
    }

    /// 超时检查循环
    async fn run_timeout_check_loop(&self) {
        let mut interval = interval(TokioDuration::from_secs(60)); // 每分钟检查一次

        loop {
            interval.tick().await;
            
            if let Err(e) = self.check_timeouts().await {
                warn!("超时检查失败: {}", e);
            }
        }
    }

    /// 处理队列
    async fn process_queue(&self) -> Result<()> {
        // 获取可用环境
        let available_environments = self.get_available_environments().await?;
        
        if available_environments.is_empty() {
            debug!("没有可用的执行环境");
            return Ok(());
        }

        let mut state = self.queue_state.lock().unwrap();
        
        // 处理待执行队列
        while let Some(queued_execution) = state.pending_queue.front() {
            // 选择执行环境
            let selected_env = self.select_environment(&available_environments, queued_execution)?;
            
            if let Some(env_id) = selected_env {
                // 从队列中移除任务
                let execution = state.pending_queue.pop_front().unwrap();
                
                // 添加到正在执行的任务
                let running_execution = RunningExecution {
                    execution_id: execution.execution_id,
                    environment_id: env_id,
                    started_at: Utc::now(),
                    estimated_completion: execution.estimated_duration_seconds
                        .map(|duration| Utc::now() + chrono::Duration::seconds(duration as i64)),
                };
                
                state.running_executions.insert(execution.execution_id, running_execution);
                
                info!("开始执行任务: 执行ID {}, 环境ID {}", execution.execution_id, env_id);
                
                // 更新数据库中的执行状态
                if let Ok(Some(mut record)) = self.execution_record_repository.find_by_id(execution.execution_id) {
                    record.status = ExecutionStatus::Running;
                    record.started_at = Some(Utc::now());
                    let _ = self.execution_record_repository.update(&record);
                }
            } else {
                // 没有可用环境，停止处理
                break;
            }
        }

        Ok(())
    }

    /// 检查超时任务
    async fn check_timeouts(&self) -> Result<()> {
        let now = Utc::now();
        let timeout_threshold = now - chrono::Duration::seconds(self.config.task_timeout_seconds as i64);

        let mut state = self.queue_state.lock().unwrap();
        let mut timed_out_executions = Vec::new();

        // 检查正在执行的任务是否超时
        for (execution_id, running_execution) in &state.running_executions {
            if running_execution.started_at < timeout_threshold {
                timed_out_executions.push(*execution_id);
            }
        }

        // 处理超时任务
        for execution_id in timed_out_executions {
            state.running_executions.remove(&execution_id);

            warn!("任务执行超时: 执行ID {}", execution_id);

            // 更新数据库状态
            if let Ok(Some(mut record)) = self.execution_record_repository.find_by_id(execution_id) {
                record.status = ExecutionStatus::Failed;
                record.completed_at = Some(now);
                record.error_message = Some("执行超时".to_string());
                let _ = self.execution_record_repository.update(&record);
            }
        }

        Ok(())
    }

    /// 获取可用环境
    async fn get_available_environments(&self) -> Result<Vec<i64>> {
        use crate::data::models::workflow_execution_environment::{ExecutionEnvironmentFilter, HealthStatus};

        let filter = ExecutionEnvironmentFilter {
            is_active: Some(true),
            is_available: Some(true),
            health_status: Some(HealthStatus::Healthy),
            ..Default::default()
        };

        let environments = self.execution_environment_repository.find_all(Some(&filter))?;
        let env_ids: Vec<i64> = environments.into_iter()
            .filter_map(|env| env.id)
            .collect();

        Ok(env_ids)
    }

    /// 选择执行环境
    fn select_environment(
        &self,
        available_environments: &[i64],
        queued_execution: &QueuedExecution,
    ) -> Result<Option<i64>> {
        if available_environments.is_empty() {
            return Ok(None);
        }

        // 如果指定了首选环境，优先使用
        if let Some(preferred_env) = queued_execution.preferred_environment_id {
            if available_environments.contains(&preferred_env) {
                return Ok(Some(preferred_env));
            }
        }

        // 根据负载均衡策略选择环境
        match self.config.load_balancing_strategy {
            LoadBalancingStrategy::RoundRobin => {
                let mut state = self.queue_state.lock().unwrap();
                let index = state.round_robin_index % available_environments.len();
                state.round_robin_index = (state.round_robin_index + 1) % available_environments.len();
                Ok(Some(available_environments[index]))
            }
            LoadBalancingStrategy::LeastLoaded => {
                // 选择当前负载最低的环境
                self.select_least_loaded_environment(available_environments)
            }
            LoadBalancingStrategy::HighestPriority => {
                // 简化实现：选择第一个环境（假设按优先级排序）
                Ok(Some(available_environments[0]))
            }
            LoadBalancingStrategy::WeightedRandom => {
                // 简化实现：选择第一个环境
                Ok(Some(available_environments[0]))
            }
        }
    }

    /// 选择负载最低的环境
    fn select_least_loaded_environment(&self, available_environments: &[i64]) -> Result<Option<i64>> {
        let state = self.queue_state.lock().unwrap();

        // 计算每个环境的当前负载
        let mut env_loads: HashMap<i64, u32> = HashMap::new();
        for env_id in available_environments {
            env_loads.insert(*env_id, 0);
        }

        for running_execution in state.running_executions.values() {
            if let Some(load) = env_loads.get_mut(&running_execution.environment_id) {
                *load += 1;
            }
        }

        // 找到负载最低的环境
        let least_loaded_env = env_loads.iter()
            .min_by_key(|(_, &load)| load)
            .map(|(&env_id, _)| env_id);

        Ok(least_loaded_env)
    }

    /// 清空队列
    pub async fn clear_queue(&self) -> Result<QueueOperationResult> {
        let mut state = self.queue_state.lock().unwrap();
        let cleared_count = state.pending_queue.len();
        state.pending_queue.clear();

        info!("清空队列: 移除了 {} 个待执行任务", cleared_count);

        Ok(QueueOperationResult {
            success: true,
            message: format!("已清空队列，移除了 {} 个任务", cleared_count),
            execution_id: None,
            queue_position: None,
        })
    }

    /// 计算环境利用率
    async fn calculate_environment_utilization(&self) -> Result<HashMap<i64, f64>> {
        let environments = self.execution_environment_repository.find_all(None)?;
        let state = self.queue_state.lock().unwrap();
        let mut utilization = HashMap::new();

        for env in environments {
            if let Some(env_id) = env.id {
                let running_count = state.running_executions.values()
                    .filter(|exec| exec.environment_id == env_id)
                    .count() as f64;

                let max_jobs = env.max_concurrent_jobs as f64;
                let util = if max_jobs > 0.0 { running_count / max_jobs } else { 0.0 };

                utilization.insert(env_id, util);
            }
        }

        Ok(utilization)
    }

    /// 恢复队列状态
    async fn restore_queue_state(&self) -> Result<()> {
        // 简化实现 - 在实际应用中应该从持久化存储恢复队列状态
        debug!("恢复队列状态");
        Ok(())
    }
}
