#include "scheduler.h"
#include <iostream>
#include <algorithm>
#include <sstream>
#include <iomanip>

namespace jtjai_media {

StreamScheduler::StreamScheduler(const ConfigManager& config_mgr)
    : config_mgr_(config_mgr)
    , is_running_(false)
    , should_stop_(false)
{
    scheduler_stats_.total_tasks = 0;
    scheduler_stats_.completed_tasks = 0;
    scheduler_stats_.failed_tasks = 0;
    scheduler_stats_.cancelled_tasks = 0;
    scheduler_stats_.max_concurrent_used = 0;
    scheduler_stats_.completion_rate = 0.0;
}

StreamScheduler::~StreamScheduler() {
    stop_execution();
    wait_for_completion();
}

bool StreamScheduler::start_execution() {
    if (is_running_.load()) {
        std::cerr << "调度器已经在运行中" << std::endl;
        return false;
    }
    
    std::cout << "开始创建调度方案..." << std::endl;
    
    // 创建调度方案
    if (!create_schedule()) {
        std::cerr << "创建调度方案失败" << std::endl;
        return false;
    }
    
    std::cout << "调度方案创建成功，共 " << tasks_.size() << " 个任务" << std::endl;
    std::cout << get_schedule_info() << std::endl;
    
    // 初始化统计信息
    {
        std::lock_guard<std::mutex> lock(stats_mutex_);
        scheduler_stats_.total_tasks = tasks_.size();
        scheduler_stats_.completed_tasks = 0;
        scheduler_stats_.failed_tasks = 0;
        scheduler_stats_.cancelled_tasks = 0;
        scheduler_stats_.start_time = std::chrono::system_clock::now();
        schedule_start_time_ = scheduler_stats_.start_time;
    }
    
    // 启动调度线程
    is_running_.store(true);
    should_stop_.store(false);
    scheduler_thread_ = std::make_unique<std::thread>(&StreamScheduler::scheduler_main_loop, this);
    
    std::cout << "调度器启动成功" << std::endl;
    return true;
}

void StreamScheduler::stop_execution() {
    if (!is_running_.load()) {
        return;
    }
    
    std::cout << "正在停止调度器..." << std::endl;
    
    should_stop_.store(true);
    task_cv_.notify_all();
    
    // 停止所有客户端
    {
        std::lock_guard<std::mutex> lock(tasks_mutex_);
        for (auto& task : tasks_) {
            if (task.client) {
                task.client->stop_recording();
            }
        }
    }
}

void StreamScheduler::wait_for_completion() {
    if (scheduler_thread_ && scheduler_thread_->joinable()) {
        scheduler_thread_->join();
    }
    is_running_.store(false);
    
    {
        std::lock_guard<std::mutex> lock(stats_mutex_);
        scheduler_stats_.end_time = std::chrono::system_clock::now();
    }
    
    std::cout << "调度器已停止" << std::endl;
}

bool StreamScheduler::reset_for_next_cycle() {
    // 等待当前执行完成
    if (is_running_.load()) {
        wait_for_completion();
    }
    
    // 重置所有任务状态
    {
        std::lock_guard<std::mutex> lock(tasks_mutex_);
        for (auto& task : tasks_) {
            task.started.store(false);
            task.completed.store(false);
        }
    }
    
    // 重置调度器状态
    should_stop_.store(false);
    is_running_.store(false);
    
    // 重置统计信息
    {
        std::lock_guard<std::mutex> lock(stats_mutex_);
        scheduler_stats_.completed_tasks = 0;
        scheduler_stats_.failed_tasks = 0;
        scheduler_stats_.cancelled_tasks = 0;
        scheduler_stats_.max_concurrent_used = 0;
        scheduler_stats_.completion_rate = 0.0;
    }
    
    std::cout << "调度器状态已重置，准备下一轮执行" << std::endl;
    return true;
}

std::vector<RTSPClientStats> StreamScheduler::get_all_stats() const {
    std::vector<RTSPClientStats> all_stats;
    
    std::lock_guard<std::mutex> lock(tasks_mutex_);
    for (const auto& task : tasks_) {
        if (task.client) {
            all_stats.push_back(task.client->get_stats());
        }
    }
    
    return all_stats;
}

StreamScheduler::SchedulerStats StreamScheduler::get_scheduler_stats() const {
    std::lock_guard<std::mutex> lock(stats_mutex_);
    return scheduler_stats_;
}

std::string StreamScheduler::get_schedule_info() const {
    const auto& streams = config_mgr_.get_stream_configs();
    const auto& global_config = config_mgr_.get_global_config();
    
    std::vector<StreamScheduleInfo> schedule_info;
    {
        std::lock_guard<std::mutex> lock(tasks_mutex_);
        for (const auto& task : tasks_) {
            schedule_info.emplace_back(
                task.stream_index,
                task.start_time,
                task.duration,
                streams[task.stream_index].weight
            );
        }
    }
    
    return calculator_.format_schedule(schedule_info, streams, global_config.total_poll_duration_seconds);
}

bool StreamScheduler::create_schedule() {
    const auto& streams = config_mgr_.get_stream_configs();
    const auto& global_config = config_mgr_.get_global_config();
    
    if (streams.empty()) {
        std::cerr << "没有配置的流" << std::endl;
        return false;
    }
    
    // 计算调度方案
    auto schedule = calculator_.calculate_schedule(
        streams,
        global_config.total_poll_duration_seconds,
        global_config.max_concurrent_streams
    );
    
    if (schedule.empty()) {
        std::cerr << "无法创建有效的调度方案" << std::endl;
        return false;
    }
    
    // 验证调度方案
    if (!calculator_.validate_schedule(schedule, global_config.total_poll_duration_seconds, global_config.max_concurrent_streams)) {
        std::cerr << "调度方案验证失败" << std::endl;
        return false;
    }
    
    // 创建任务和客户端
    tasks_.clear();
    clients_.clear();
    
    for (const auto& info : schedule) {
        if (info.stream_index >= 0 && info.stream_index < static_cast<int>(streams.size())) {
            const auto& stream_config = streams[info.stream_index];
            
            // 创建RTSP客户端
            auto client = std::make_shared<RTSPClient>(
                info.stream_index,
                stream_config,
                global_config.output_directory
            );
            
            client->set_connection_timeout(global_config.connection_timeout_seconds);
            client->set_read_timeout(global_config.read_timeout_seconds);
            
            // 创建任务
            tasks_.emplace_back(info.stream_index, info.start_time, info.duration, client);
            clients_.push_back(client);
        }
    }
    
    std::cout << "创建了 " << tasks_.size() << " 个任务" << std::endl;
    return !tasks_.empty();
}

void StreamScheduler::scheduler_main_loop() {
    std::vector<std::thread> task_threads;
    
    try {
        while (!should_stop_.load()) {
            // 检查是否有任务需要启动
            std::vector<std::shared_ptr<TaskInfo>> tasks_to_start;
            
            {
                std::lock_guard<std::mutex> lock(tasks_mutex_);
                for (auto& task : tasks_) {
                    if (!task.started.load() && should_start_task(task)) {
                        task.started.store(true);
                        tasks_to_start.push_back(std::make_shared<TaskInfo>(task));
                    }
                }
            }
            
            // 启动准备好的任务
            for (auto task : tasks_to_start) {
                task_threads.emplace_back(&StreamScheduler::execute_task, this, task);
            }
            
            // 清理已完成的线程
            task_threads.erase(
                std::remove_if(task_threads.begin(), task_threads.end(),
                    [](std::thread& t) {
                        if (t.joinable()) {
                            // 这里应该使用非阻塞的方式检查线程是否完成
                            // 为简化起见，我们暂时保留所有线程
                            return false;
                        }
                        return true;
                    }),
                task_threads.end()
            );
            
            // 更新统计信息
            update_stats();
            
            // 检查是否所有任务都已完成
            bool all_done = true;
            {
                std::lock_guard<std::mutex> lock(tasks_mutex_);
                for (auto& task : tasks_) {
                    if (!task.completed.load()) {
                        // 检查是否已经启动但还在运行
                        if (task.started.load() && task.client && task.client->is_running()) {
                            all_done = false;
                            break;
                        }
                        // 检查是否还没有启动但应该启动
                        else if (!task.started.load() && should_start_task(task)) {
                            all_done = false;
                            break;
                        }
                        // 如果任务已经启动但不再运行，标记为完成
                        else if (task.started.load() && task.client && !task.client->is_running()) {
                            task.completed.store(true);
                        }
                    }
                }
            }
            
            auto current_time = std::chrono::system_clock::now();
            auto elapsed = std::chrono::duration_cast<std::chrono::seconds>(
                current_time - schedule_start_time_).count();
            
            if (all_done || elapsed >= config_mgr_.get_global_config().total_poll_duration_seconds) {
                std::cout << "所有任务已完成或达到总轮询时长" << std::endl;
                break;
            }
            
            // 短暂休眠
            std::this_thread::sleep_for(std::chrono::milliseconds(100));
        }
        
        // 等待所有任务线程完成
        for (auto& thread : task_threads) {
            if (thread.joinable()) {
                thread.join();
            }
        }
        
    } catch (const std::exception& e) {
        std::cerr << "调度器主循环异常: " << e.what() << std::endl;
    }
    
    std::cout << "调度器主循环结束" << std::endl;
    
    // 主循环结束后立即生成报告
    if (report_callback_) {
        std::cout << "主循环结束，自动生成报告..." << std::endl;
        auto client_stats = get_all_stats();
        auto scheduler_stats = get_scheduler_stats();
        report_callback_(client_stats, scheduler_stats);
        std::cout << "报告生成完成" << std::endl;
    } else {
        std::cout << "警告: 未设置报告回调，跳过报告生成" << std::endl;
    }
}

void StreamScheduler::execute_task(std::shared_ptr<TaskInfo> task) {
    try {
        std::cout << "任务 " << task->stream_index << " 开始执行" << std::endl;
        
        // 等待到任务开始时间
        wait_until_task_start_time(*task);
        
        if (should_stop_.load()) {
            std::cout << "任务 " << task->stream_index << " 被取消" << std::endl;
            task->completed.store(true);
            return;
        }
        
        // 执行录制
        bool success = task->client->start_recording(task->duration);
        
        // 获取结果并更新统计
        auto stats = task->client->get_stats();
        task_completion_callback(task->stream_index, stats);
        
        std::cout << "任务 " << task->stream_index << " 完成，状态: " 
                  << (success ? "成功" : "失败") << std::endl;
        
        // 标记任务完成
        task->completed.store(true);
                  
    } catch (const std::exception& e) {
        std::cerr << "执行任务 " << task->stream_index << " 时发生异常: " << e.what() << std::endl;
        
        // 更新失败统计
        RTSPClientStats error_stats;
        error_stats.stream_index = task->stream_index;
        error_stats.status = RTSPClientStatus::ERROR_RECORD;
        error_stats.error_message = e.what();
        task_completion_callback(task->stream_index, error_stats);
        
        // 标记任务完成
        task->completed.store(true);
    }
}

bool StreamScheduler::should_start_task(const TaskInfo& task) const {
    if (!task.client) {
        return false;
    }
    
    // 检查是否到了开始时间
    auto current_time = std::chrono::system_clock::now();
    auto elapsed_seconds = std::chrono::duration_cast<std::chrono::seconds>(
        current_time - schedule_start_time_).count();
    
    return elapsed_seconds >= task.start_time;
}

void StreamScheduler::wait_until_task_start_time(const TaskInfo& task) {
    auto target_time = calculate_absolute_start_time(task.start_time);
    auto current_time = std::chrono::system_clock::now();
    
    if (target_time > current_time) {
        auto wait_duration = target_time - current_time;
        std::this_thread::sleep_for(wait_duration);
    }
}

std::chrono::system_clock::time_point StreamScheduler::calculate_absolute_start_time(int relative_start_time) const {
    return schedule_start_time_ + std::chrono::seconds(relative_start_time);
}

void StreamScheduler::update_stats() {
    std::lock_guard<std::mutex> lock(stats_mutex_);
    
    // 统计各种状态的任务数量
    int completed = 0, failed = 0, cancelled = 0;
    int max_concurrent = 0;
    
    {
        std::lock_guard<std::mutex> task_lock(tasks_mutex_);
        
        // 计算当前并发数
        int current_concurrent = 0;
        for (const auto& task : tasks_) {
            if (task.client && task.client->is_running()) {
                current_concurrent++;
            }
            
            if (task.completed.load()) {
                auto status = task.client ? task.client->get_status() : RTSPClientStatus::IDLE;
                switch (status) {
                    case RTSPClientStatus::FINISHED:
                        completed++;
                        break;
                    case RTSPClientStatus::ERROR_CONNECT:
                    case RTSPClientStatus::ERROR_RECORD:
                    case RTSPClientStatus::TIMEOUT:
                    case RTSPClientStatus::STREAM_UNAVAILABLE:
                        failed++;
                        break;
                    case RTSPClientStatus::CANCELLED:
                        cancelled++;
                        break;
                    default:
                        // 如果状态不明确但已经完成，认为成功
                        completed++;
                        break;
                }
            }
        }
        
        max_concurrent = std::max(scheduler_stats_.max_concurrent_used, current_concurrent);
    }
    
    scheduler_stats_.completed_tasks = completed;
    scheduler_stats_.failed_tasks = failed;
    scheduler_stats_.cancelled_tasks = cancelled;
    scheduler_stats_.max_concurrent_used = max_concurrent;
    
    if (scheduler_stats_.total_tasks > 0) {
        scheduler_stats_.completion_rate = 
            static_cast<double>(completed) / scheduler_stats_.total_tasks;
    }
    
    // 调用进度回调
    if (progress_callback_) {
        progress_callback_(scheduler_stats_);
    }
}

void StreamScheduler::task_completion_callback(int stream_index, const RTSPClientStats& stats) {
    std::cout << "流 " << stream_index << " 录制完成: ";
    
    switch (stats.status) {
        case RTSPClientStatus::FINISHED:
            std::cout << "成功 (接收 " << stats.frames_received << " 帧, " 
                      << stats.bytes_received << " 字节)";
            break;
        case RTSPClientStatus::STREAM_UNAVAILABLE:
            std::cout << "流不可用（快速棄用）: " << stats.error_message;
            break;
        case RTSPClientStatus::ERROR_CONNECT:
            std::cout << "连接错误: " << stats.error_message;
            break;
        case RTSPClientStatus::ERROR_RECORD:
            std::cout << "录制错误: " << stats.error_message;
            break;
        case RTSPClientStatus::TIMEOUT:
            std::cout << "超时";
            break;
        case RTSPClientStatus::CANCELLED:
            std::cout << "已取消";
            break;
        default:
            std::cout << "未知状态";
            break;
    }
    
    std::cout << std::endl;
}

} // namespace jtjai_media