#include "reporter.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <ctime>
#include <algorithm>
#include <filesystem>

namespace jtjai_media {

ResultReporter::ResultReporter(const ConfigManager& config_mgr)
    : config_mgr_(config_mgr) {
}

bool ResultReporter::generate_report(
    const std::vector<RTSPClientStats>& client_stats,
    const StreamScheduler::SchedulerStats& scheduler_stats
) {
    const auto& global_config = config_mgr_.get_global_config();
    
    // 确保输出目录存在
    std::filesystem::create_directories(global_config.output_directory);
    
    bool success = true;
    
    // 生成JSON报告
    std::string json_report = generate_json_report(client_stats, scheduler_stats);
    std::string json_path = global_config.output_directory + "/" + global_config.report_filename;
    if (!save_to_file(json_report, json_path)) {
        std::cerr << "保存JSON报告失败: " << json_path << std::endl;
        success = false;
    } else {
        std::cout << "JSON报告已保存: " << json_path << std::endl;
    }
    
    // 生成文本报告
    std::string text_report = generate_text_report(client_stats, scheduler_stats);
    std::string text_path = global_config.output_directory + "/report.txt";
    if (!save_to_file(text_report, text_path)) {
        std::cerr << "保存文本报告失败: " << text_path << std::endl;
        success = false;
    } else {
        std::cout << "文本报告已保存: " << text_path << std::endl;
    }
    
    // 生成CSV报告
    std::string csv_report = generate_csv_report(client_stats);
    std::string csv_path = global_config.output_directory + "/streams.csv";
    if (!save_to_file(csv_report, csv_path)) {
        std::cerr << "保存CSV报告失败: " << csv_path << std::endl;
        success = false;
    } else {
        std::cout << "CSV报告已保存: " << csv_path << std::endl;
    }
    
    // 打印控制台报告
    print_console_report(client_stats, scheduler_stats);
    
    return success;
}

std::string ResultReporter::generate_json_report(
    const std::vector<RTSPClientStats>& client_stats,
    const StreamScheduler::SchedulerStats& scheduler_stats
) const {
    boost::json::object root;
    
    // 基本信息
    root["report_generated_at"] = format_timestamp(std::chrono::system_clock::now());
    root["config"] = config_to_json();
    
    // 调度器统计
    root["scheduler_stats"] = scheduler_stats_to_json(scheduler_stats);
    
    // 客户端统计
    boost::json::array streams_array;
    for (const auto& stats : client_stats) {
        streams_array.push_back(client_stats_to_json(stats));
    }
    root["streams"] = streams_array;
    
    // 汇总统计
    auto summary = calculate_summary_stats(client_stats);
    boost::json::object summary_obj;
    summary_obj["total_streams"] = summary.total_streams;
    summary_obj["successful_streams"] = summary.successful_streams;
    summary_obj["failed_streams"] = summary.failed_streams;
    summary_obj["cancelled_streams"] = summary.cancelled_streams;
    summary_obj["total_bytes"] = summary.total_bytes;
    summary_obj["total_frames"] = summary.total_frames;
    summary_obj["success_rate"] = summary.success_rate;
    summary_obj["average_duration"] = summary.average_duration;
    summary_obj["earliest_start"] = format_timestamp(summary.earliest_start);
    summary_obj["latest_end"] = format_timestamp(summary.latest_end);
    
    root["summary"] = summary_obj;
    
    return boost::json::serialize(root);
}

std::string ResultReporter::generate_text_report(
    const std::vector<RTSPClientStats>& client_stats,
    const StreamScheduler::SchedulerStats& scheduler_stats
) const {
    std::stringstream ss;
    
    ss << "========================================\\n";
    ss << "RTSP视频流拉取报告\\n";
    ss << "========================================\\n";
    ss << "生成时间: " << format_timestamp(std::chrono::system_clock::now()) << "\\n\\n";
    
    // 配置信息
    const auto& global_config = config_mgr_.get_global_config();
    const auto& streams = config_mgr_.get_stream_configs();
    
    ss << "配置信息:\\n";
    ss << "--------\\n";
    ss << "总轮询时长: " << global_config.total_poll_duration_seconds << " 秒\\n";
    ss << "最大并发流数: " << global_config.max_concurrent_streams << "\\n";
    ss << "输出目录: " << global_config.output_directory << "\\n";
    ss << "配置的流数量: " << streams.size() << "\\n\\n";
    
    // 调度器统计
    ss << "调度器统计:\\n";
    ss << "----------\\n";
    ss << "总任务数: " << scheduler_stats.total_tasks << "\\n";
    ss << "已完成: " << scheduler_stats.completed_tasks << "\\n";
    ss << "失败: " << scheduler_stats.failed_tasks << "\\n";
    ss << "取消: " << scheduler_stats.cancelled_tasks << "\\n";
    ss << "最大并发数: " << scheduler_stats.max_concurrent_used << "\\n";
    ss << "完成率: " << std::fixed << std::setprecision(2) << (scheduler_stats.completion_rate * 100) << "%\\n";
    ss << "调度开始时间: " << format_timestamp(scheduler_stats.start_time) << "\\n";
    ss << "调度结束时间: " << format_timestamp(scheduler_stats.end_time) << "\\n";
    ss << "总调度时长: " << format_duration(scheduler_stats.start_time, scheduler_stats.end_time) << "\\n\\n";
    
    // 汇总统计
    auto summary = calculate_summary_stats(client_stats);
    ss << "汇总统计:\\n";
    ss << "--------\\n";
    ss << "成功流数: " << summary.successful_streams << " / " << summary.total_streams << "\\n";
    ss << "成功率: " << std::fixed << std::setprecision(2) << (summary.success_rate * 100) << "%\\n";
    ss << "总接收字节: " << format_bytes(summary.total_bytes) << "\\n";
    ss << "总接收帧数: " << summary.total_frames << "\\n";
    ss << "平均持续时间: " << std::fixed << std::setprecision(1) << summary.average_duration << " 秒\\n\\n";
    
    // 详细流信息
    ss << "详细流信息:\\n";
    ss << "==========\\n";
    
    for (const auto& stats : client_stats) {
        ss << "流 " << stats.stream_index << ":\\n";
        ss << "  RTSP地址: " << stats.rtsp_url << "\\n";
        ss << "  输出文件: " << stats.output_file << "\\n";
        ss << "  状态: " << status_to_string(stats.status) << "\\n";
        
        if (stats.start_time != std::chrono::system_clock::time_point{}) {
            ss << "  开始时间: " << format_timestamp(stats.start_time) << "\\n";
        }
        
        if (stats.end_time != std::chrono::system_clock::time_point{}) {
            ss << "  结束时间: " << format_timestamp(stats.end_time) << "\\n";
            ss << "  持续时间: " << format_duration(stats.start_time, stats.end_time) << "\\n";
        }
        
        ss << "  计划持续时间: " << stats.duration_seconds << " 秒\\n";
        ss << "  接收字节: " << format_bytes(stats.bytes_received) << "\\n";
        ss << "  接收帧数: " << stats.frames_received << "\\n";
        
        if (!stats.error_message.empty()) {
            ss << "  错误信息: " << stats.error_message << "\\n";
        }
        
        ss << "\\n";
    }
    
    return ss.str();
}

std::string ResultReporter::generate_csv_report(
    const std::vector<RTSPClientStats>& client_stats
) const {
    std::stringstream ss;
    
    // CSV头部
    ss << "Stream Index,RTSP URL,Output File,Status,Start Time,End Time,Duration (s),";
    ss << "Planned Duration (s),Bytes Received,Frames Received,Error Message\\n";
    
    // 数据行
    for (const auto& stats : client_stats) {
        ss << stats.stream_index << ",";
        ss << "\\"" << stats.rtsp_url << "",";
        ss << "\\"" << stats.output_file << "",";
        ss << "\\"" << status_to_string(stats.status) << "",";
        
        if (stats.start_time != std::chrono::system_clock::time_point{}) {
            ss << "\\"" << format_timestamp(stats.start_time) << "",";
        } else {
            ss << ",";
        }
        
        if (stats.end_time != std::chrono::system_clock::time_point{}) {
            ss << "\\"" << format_timestamp(stats.end_time) << "",";
            
            auto duration = std::chrono::duration_cast<std::chrono::seconds>(
                stats.end_time - stats.start_time).count();
            ss << duration << ",";
        } else {
            ss << ",,";
        }
        
        ss << stats.duration_seconds << ",";
        ss << stats.bytes_received << ",";
        ss << stats.frames_received << ",";
        ss << "\\"" << stats.error_message << ""\\n";
    }
    
    return ss.str();
}

bool ResultReporter::save_to_file(const std::string& content, const std::string& filename) const {
    try {
        std::ofstream file(filename);
        if (!file.is_open()) {
            return false;
        }
        
        file << content;
        file.close();
        return true;
    } catch (const std::exception& e) {
        std::cerr << "保存文件异常: " << e.what() << std::endl;
        return false;
    }
}

void ResultReporter::print_console_report(
    const std::vector<RTSPClientStats>& client_stats,
    const StreamScheduler::SchedulerStats& scheduler_stats
) const {
    std::cout << "\\n========================================" << std::endl;
    std::cout << "RTSP视频流拉取结果汇总" << std::endl;
    std::cout << "========================================" << std::endl;
    
    auto summary = calculate_summary_stats(client_stats);
    
    std::cout << "总流数: " << summary.total_streams << std::endl;
    std::cout << "成功: " << summary.successful_streams << " (" 
              << std::fixed << std::setprecision(1) << (summary.success_rate * 100) << "%)" << std::endl;
    std::cout << "失败: " << summary.failed_streams << std::endl;
    std::cout << "取消: " << summary.cancelled_streams << std::endl;
    std::cout << "最大并发: " << scheduler_stats.max_concurrent_used << std::endl;
    std::cout << "总接收数据: " << format_bytes(summary.total_bytes) << std::endl;
    std::cout << "总接收帧数: " << summary.total_frames << std::endl;
    
    std::cout << "\\n各流状态:" << std::endl;
    std::cout << "----------" << std::endl;
    
    for (const auto& stats : client_stats) {
        std::cout << "流 " << std::setw(2) << stats.stream_index << ": " 
                  << std::setw(12) << status_to_string(stats.status)
                  << " | " << format_bytes(stats.bytes_received) 
                  << " | " << stats.frames_received << " 帧";
        
        if (!stats.error_message.empty()) {
            std::cout << " | " << stats.error_message;
        }
        
        std::cout << std::endl;
    }
    
    std::cout << "========================================\\n" << std::endl;
}

std::string ResultReporter::format_duration(
    const std::chrono::system_clock::time_point& start,
    const std::chrono::system_clock::time_point& end
) const {
    if (start == std::chrono::system_clock::time_point{} || 
        end == std::chrono::system_clock::time_point{}) {
        return "N/A";
    }
    
    auto duration = std::chrono::duration_cast<std::chrono::seconds>(end - start);
    return std::to_string(duration.count()) + " 秒";
}

std::string ResultReporter::format_bytes(int64_t bytes) const {
    const char* units[] = {"B", "KB", "MB", "GB", "TB"};
    int unit_index = 0;
    double size = static_cast<double>(bytes);
    
    while (size >= 1024.0 && unit_index < 4) {
        size /= 1024.0;
        unit_index++;
    }
    
    std::stringstream ss;
    ss << std::fixed << std::setprecision(2) << size << " " << units[unit_index];
    return ss.str();
}

std::string ResultReporter::format_timestamp(
    const std::chrono::system_clock::time_point& time
) const {
    if (time == std::chrono::system_clock::time_point{}) {
        return "N/A";
    }
    
    auto time_t = std::chrono::system_clock::to_time_t(time);
    auto tm = *std::localtime(&time_t);
    
    std::stringstream ss;
    ss << std::put_time(&tm, "%Y-%m-%d %H:%M:%S");
    return ss.str();
}

std::string ResultReporter::status_to_string(RTSPClientStatus status) const {
    switch (status) {
        case RTSPClientStatus::IDLE: return "空闲";
        case RTSPClientStatus::CONNECTING: return "连接中";
        case RTSPClientStatus::CONNECTED: return "已连接";
        case RTSPClientStatus::RECORDING: return "录制中";
        case RTSPClientStatus::FINISHED: return "完成";
        case RTSPClientStatus::ERROR_CONNECT: return "连接错误";
        case RTSPClientStatus::ERROR_RECORD: return "录制错误";
        case RTSPClientStatus::TIMEOUT: return "超时";
        case RTSPClientStatus::CANCELLED: return "已取消";
        case RTSPClientStatus::STREAM_UNAVAILABLE: return "流不可用";
        default: return "未知";
    }
}

boost::json::object ResultReporter::client_stats_to_json(const RTSPClientStats& stats) const {
    boost::json::object obj;
    
    obj["stream_index"] = stats.stream_index;
    obj["rtsp_url"] = stats.rtsp_url;
    obj["output_file"] = stats.output_file;
    obj["status"] = status_to_string(stats.status);
    obj["start_time"] = format_timestamp(stats.start_time);
    obj["end_time"] = format_timestamp(stats.end_time);
    obj["bytes_received"] = stats.bytes_received;
    obj["frames_received"] = stats.frames_received;
    obj["duration_seconds"] = stats.duration_seconds;
    obj["error_message"] = stats.error_message;
    
    if (stats.start_time != std::chrono::system_clock::time_point{} &&
        stats.end_time != std::chrono::system_clock::time_point{}) {
        auto actual_duration = std::chrono::duration_cast<std::chrono::seconds>(
            stats.end_time - stats.start_time).count();
        obj["actual_duration_seconds"] = actual_duration;
    }
    
    return obj;
}

boost::json::object ResultReporter::scheduler_stats_to_json(
    const StreamScheduler::SchedulerStats& stats
) const {
    boost::json::object obj;
    
    obj["total_tasks"] = stats.total_tasks;
    obj["completed_tasks"] = stats.completed_tasks;
    obj["failed_tasks"] = stats.failed_tasks;
    obj["cancelled_tasks"] = stats.cancelled_tasks;
    obj["start_time"] = format_timestamp(stats.start_time);
    obj["end_time"] = format_timestamp(stats.end_time);
    obj["max_concurrent_used"] = stats.max_concurrent_used;
    obj["completion_rate"] = stats.completion_rate;
    
    if (stats.start_time != std::chrono::system_clock::time_point{} &&
        stats.end_time != std::chrono::system_clock::time_point{}) {
        auto total_duration = std::chrono::duration_cast<std::chrono::seconds>(
            stats.end_time - stats.start_time).count();
        obj["total_duration_seconds"] = total_duration;
    }
    
    return obj;
}

boost::json::object ResultReporter::config_to_json() const {
    boost::json::object config_obj;
    
    const auto& global_config = config_mgr_.get_global_config();
    const auto& streams = config_mgr_.get_stream_configs();
    
    // 全局配置
    boost::json::object global_obj;
    global_obj["total_poll_duration_seconds"] = global_config.total_poll_duration_seconds;
    global_obj["max_concurrent_streams"] = global_config.max_concurrent_streams;
    global_obj["output_directory"] = global_config.output_directory;
    global_obj["report_filename"] = global_config.report_filename;
    global_obj["connection_timeout_seconds"] = global_config.connection_timeout_seconds;
    global_obj["read_timeout_seconds"] = global_config.read_timeout_seconds;
    
    config_obj["global_config"] = global_obj;
    
    // 流配置
    boost::json::array streams_array;
    for (const auto& stream : streams) {
        boost::json::object stream_obj;
        stream_obj["rtsp_url"] = stream.rtsp_url;
        stream_obj["duration_seconds"] = stream.duration_seconds;
        stream_obj["weight"] = stream.weight;
        stream_obj["output_filename"] = stream.output_filename;
        streams_array.push_back(stream_obj);
    }
    
    config_obj["streams"] = streams_array;
    
    return config_obj;
}

ResultReporter::SummaryStats ResultReporter::calculate_summary_stats(
    const std::vector<RTSPClientStats>& client_stats
) const {
    SummaryStats summary;
    summary.total_streams = client_stats.size();
    summary.successful_streams = 0;
    summary.failed_streams = 0;
    summary.cancelled_streams = 0;
    summary.total_bytes = 0;
    summary.total_frames = 0;
    summary.success_rate = 0.0;
    summary.average_duration = 0.0;
    summary.earliest_start = std::chrono::system_clock::time_point::max();
    summary.latest_end = std::chrono::system_clock::time_point::min();
    
    if (client_stats.empty()) {
        return summary;
    }
    
    double total_duration = 0.0;
    int duration_count = 0;
    
    for (const auto& stats : client_stats) {
        // 统计状态
        switch (stats.status) {
            case RTSPClientStatus::FINISHED:
                summary.successful_streams++;
                break;
            case RTSPClientStatus::ERROR_CONNECT:
            case RTSPClientStatus::ERROR_RECORD:
            case RTSPClientStatus::TIMEOUT:
                summary.failed_streams++;
                break;
            case RTSPClientStatus::CANCELLED:
                summary.cancelled_streams++;
                break;
            default:
                break;
        }
        
        // 累计数据
        summary.total_bytes += stats.bytes_received;
        summary.total_frames += stats.frames_received;
        
        // 计算时间统计
        if (stats.start_time != std::chrono::system_clock::time_point{}) {
            summary.earliest_start = std::min(summary.earliest_start, stats.start_time);
            
            if (stats.end_time != std::chrono::system_clock::time_point{}) {
                summary.latest_end = std::max(summary.latest_end, stats.end_time);
                
                auto duration = std::chrono::duration_cast<std::chrono::seconds>(
                    stats.end_time - stats.start_time).count();
                total_duration += duration;
                duration_count++;
            }
        }
    }
    
    // 计算比率
    if (summary.total_streams > 0) {
        summary.success_rate = static_cast<double>(summary.successful_streams) / summary.total_streams;
    }
    
    if (duration_count > 0) {
        summary.average_duration = total_duration / duration_count;
    }
    
    // 处理时间边界情况
    if (summary.earliest_start == std::chrono::system_clock::time_point::max()) {
        summary.earliest_start = std::chrono::system_clock::time_point{};
    }
    
    if (summary.latest_end == std::chrono::system_clock::time_point::min()) {
        summary.latest_end = std::chrono::system_clock::time_point{};
    }
    
    return summary;
}

} // namespace jtjai_media