#include "../player/player_core_v2.h"
#include "../base/logger.h"
#include <iostream>
#include <thread>
#include <chrono>
#include <string>

using namespace av::player;
using namespace av::utils;

// 示例事件回调类
class ExamplePlayerCallback : public PlayerEventCallback {
public:
    void onStateChanged(PlayerState newState) override {
        std::string stateStr;
        switch (newState) {
            case PlayerState::Idle: stateStr = "Idle"; break;
            case PlayerState::Opening: stateStr = "Opening"; break;
            case PlayerState::Stopped: stateStr = "Stopped"; break;
            case PlayerState::Playing: stateStr = "Playing"; break;
            case PlayerState::Paused: stateStr = "Paused"; break;
            case PlayerState::Seeking: stateStr = "Seeking"; break;
            case PlayerState::Error: stateStr = "Error"; break;
        }
        std::cout << "[EVENT] State changed to: " << stateStr << std::endl;
    }
    
    void onPositionChanged(int64_t position) override {
        // 每秒更新一次位置信息
        static auto lastUpdate = std::chrono::steady_clock::now();
        auto now = std::chrono::steady_clock::now();
        if (std::chrono::duration_cast<std::chrono::seconds>(now - lastUpdate).count() >= 1) {
            double seconds = position / 1000000.0;
            std::cout << "[EVENT] Position: " << std::fixed << std::setprecision(2) << seconds << "s" << std::endl;
            lastUpdate = now;
        }
    }
    
    void onMediaInfoChanged(const MediaInfo& info) override {
        std::cout << "[EVENT] Media info changed:" << std::endl;
        std::cout << "  File: " << info.filename << std::endl;
        std::cout << "  Duration: " << (info.duration / 1000000.0) << "s" << std::endl;
        std::cout << "  Has Video: " << (info.hasVideo ? "Yes" : "No") << std::endl;
        std::cout << "  Has Audio: " << (info.hasAudio ? "Yes" : "No") << std::endl;
        
        if (info.hasVideo) {
            std::cout << "  Video: " << info.width << "x" << info.height << " @ " << info.fps << " fps" << std::endl;
        }
        
        if (info.hasAudio) {
            std::cout << "  Audio: " << info.sampleRate << " Hz, " << info.channels << " channels" << std::endl;
        }
    }
    
    void onErrorOccurred(const std::string& error) override {
        std::cout << "[ERROR] " << error << std::endl;
    }
    
    void onFrameDropped(int64_t totalDropped) override {
        std::cout << "[WARNING] Frame dropped, total: " << totalDropped << std::endl;
    }
    
    void onSyncError(double error, const std::string& reason) override {
        std::cout << "[WARNING] Sync error: " << (error * 1000) << "ms, reason: " << reason << std::endl;
    }
};

// 简单的命令行界面
class SimplePlayerUI {
public:
    SimplePlayerUI(PlayerCoreV2* player) : m_player(player), m_running(true) {}
    
    void run() {
        std::cout << "\n=== PlayerCoreV2 Example ===" << std::endl;
        std::cout << "Commands:" << std::endl;
        std::cout << "  open <filename>  - Open media file" << std::endl;
        std::cout << "  play             - Start playback" << std::endl;
        std::cout << "  pause            - Pause playback" << std::endl;
        std::cout << "  stop             - Stop playback" << std::endl;
        std::cout << "  seek <seconds>   - Seek to position" << std::endl;
        std::cout << "  speed <rate>     - Set playback speed (0.5-4.0)" << std::endl;
        std::cout << "  volume <level>   - Set volume (0.0-1.0)" << std::endl;
        std::cout << "  stats            - Show playback statistics" << std::endl;
        std::cout << "  debug            - Show debug information" << std::endl;
        std::cout << "  config           - Show sync configuration" << std::endl;
        std::cout << "  quit             - Exit program" << std::endl;
        std::cout << "============================\n" << std::endl;
        
        std::string line;
        while (m_running && std::getline(std::cin, line)) {
            processCommand(line);
        }
    }
    
private:
    void processCommand(const std::string& line) {
        std::istringstream iss(line);
        std::string command;
        iss >> command;
        
        if (command == "open") {
            std::string filename;
            iss >> filename;
            if (!filename.empty()) {
                auto result = m_player->openFile(filename);
                if (result == ErrorCode::SUCCESS) {
                    std::cout << "File opened successfully" << std::endl;
                } else {
                    std::cout << "Failed to open file: " << static_cast<int>(result) << std::endl;
                }
            } else {
                std::cout << "Usage: open <filename>" << std::endl;
            }
        }
        else if (command == "play") {
            auto result = m_player->play();
            if (result == ErrorCode::SUCCESS) {
                std::cout << "Playback started" << std::endl;
            } else {
                std::cout << "Failed to start playback: " << static_cast<int>(result) << std::endl;
            }
        }
        else if (command == "pause") {
            auto result = m_player->pause();
            if (result == ErrorCode::SUCCESS) {
                std::cout << "Playback paused" << std::endl;
            } else {
                std::cout << "Failed to pause playback: " << static_cast<int>(result) << std::endl;
            }
        }
        else if (command == "stop") {
            auto result = m_player->stop();
            if (result == ErrorCode::SUCCESS) {
                std::cout << "Playback stopped" << std::endl;
            } else {
                std::cout << "Failed to stop playback: " << static_cast<int>(result) << std::endl;
            }
        }
        else if (command == "seek") {
            double seconds;
            iss >> seconds;
            if (iss) {
                int64_t timestamp = static_cast<int64_t>(seconds * 1000000); // 转换为微秒
                auto result = m_player->seek(timestamp);
                if (result == ErrorCode::SUCCESS) {
                    std::cout << "Seeking to " << seconds << "s" << std::endl;
                } else {
                    std::cout << "Failed to seek: " << static_cast<int>(result) << std::endl;
                }
            } else {
                std::cout << "Usage: seek <seconds>" << std::endl;
            }
        }
        else if (command == "speed") {
            double speed;
            iss >> speed;
            if (iss) {
                auto result = m_player->setPlaybackSpeed(speed);
                if (result == ErrorCode::SUCCESS) {
                    std::cout << "Playback speed set to " << speed << "x" << std::endl;
                } else {
                    std::cout << "Failed to set playback speed: " << static_cast<int>(result) << std::endl;
                }
            } else {
                std::cout << "Usage: speed <rate>" << std::endl;
            }
        }
        else if (command == "volume") {
            double volume;
            iss >> volume;
            if (iss) {
                m_player->setVolume(volume);
                std::cout << "Volume set to " << volume << std::endl;
            } else {
                std::cout << "Usage: volume <level>" << std::endl;
            }
        }
        else if (command == "stats") {
            showStats();
        }
        else if (command == "debug") {
            std::cout << m_player->getDebugInfo() << std::endl;
        }
        else if (command == "config") {
            showSyncConfig();
        }
        else if (command == "quit" || command == "exit") {
            m_running = false;
            std::cout << "Exiting..." << std::endl;
        }
        else if (!command.empty()) {
            std::cout << "Unknown command: " << command << std::endl;
        }
    }
    
    void showStats() {
        auto stats = m_player->getStats();
        
        std::cout << "\n=== Playback Statistics ===" << std::endl;
        std::cout << "Current Time: " << std::fixed << std::setprecision(2) << (stats.currentTime / 1000000.0) << "s" << std::endl;
        std::cout << "Playback Speed: " << stats.playbackSpeed << "x" << std::endl;
        std::cout << "Total Frames: " << stats.totalFrames << std::endl;
        std::cout << "Dropped Frames: " << stats.droppedFrames << std::endl;
        std::cout << "Duplicated Frames: " << stats.duplicatedFrames << std::endl;
        std::cout << "Sync Error: " << std::fixed << std::setprecision(1) << (stats.syncError * 1000) << "ms" << std::endl;
        std::cout << "Avg Sync Error: " << std::fixed << std::setprecision(1) << (stats.avgSyncError * 1000) << "ms" << std::endl;
        std::cout << "Max Sync Error: " << std::fixed << std::setprecision(1) << (stats.maxSyncError * 1000) << "ms" << std::endl;
        std::cout << "CPU Usage: " << std::fixed << std::setprecision(1) << stats.cpuUsage << "%" << std::endl;
        std::cout << "Memory Usage: " << std::fixed << std::setprecision(1) << stats.memoryUsage << "MB" << std::endl;
        std::cout << "Queued Packets: " << stats.queuedPackets << std::endl;
        std::cout << "Queued Video Frames: " << stats.queuedVideoFrames << std::endl;
        std::cout << "Queued Audio Frames: " << stats.queuedAudioFrames << std::endl;
        std::cout << "Bitrate: " << std::fixed << std::setprecision(1) << stats.bitrate << " kbps" << std::endl;
        std::cout << "===========================\n" << std::endl;
    }
    
    void showSyncConfig() {
        auto config = m_player->getSyncConfig();
        
        std::cout << "\n=== Sync Configuration ===" << std::endl;
        std::cout << "Sync Strategy: " << static_cast<int>(config.syncStrategy) << std::endl;
        std::cout << "Audio Sync Threshold: " << (config.audioSyncThreshold * 1000) << "ms" << std::endl;
        std::cout << "Video Sync Threshold: " << (config.videoSyncThreshold * 1000) << "ms" << std::endl;
        std::cout << "Max Sync Error: " << (config.maxSyncError * 1000) << "ms" << std::endl;
        std::cout << "Clock Update Interval: " << config.clockUpdateInterval << "ms" << std::endl;
        std::cout << "Smoothing Window: " << config.smoothingWindow << std::endl;
        std::cout << "Adaptive Sync: " << (config.enableAdaptiveSync ? "Enabled" : "Disabled") << std::endl;
        std::cout << "Frame Drop: " << (config.enableFrameDrop ? "Enabled" : "Disabled") << std::endl;
        std::cout << "Frame Duplicate: " << (config.enableFrameDuplicate ? "Enabled" : "Disabled") << std::endl;
        std::cout << "Prediction: " << (config.enablePrediction ? "Enabled" : "Disabled") << std::endl;
        std::cout << "==========================\n" << std::endl;
    }
    
    PlayerCoreV2* m_player;
    bool m_running;
};

int main(int argc, char* argv[]) {
    // 初始化日志系统
    Logger::instance().setLevel(LogLevel::INFO);
    Logger::instance().info("PlayerCoreV2 Example Started");
    
    try {
        // 创建同步配置
        SyncConfigV2 syncConfig;
        syncConfig.syncStrategy = SyncStrategy::ADAPTIVE;  // 使用自适应同步策略
        syncConfig.audioSyncThreshold = 0.040;  // 40ms
        syncConfig.videoSyncThreshold = 0.020;  // 20ms
        syncConfig.maxSyncError = 0.200;        // 200ms
        syncConfig.clockUpdateInterval = 10;     // 10ms
        syncConfig.smoothingWindow = 10;         // 10个样本
        syncConfig.enableAdaptiveSync = true;
        syncConfig.enableFrameDrop = true;
        syncConfig.enableFrameDuplicate = true;
        syncConfig.enablePrediction = true;
        syncConfig.enableErrorRecovery = true;
        
        // 创建播放器实例
        auto player = std::make_unique<PlayerCoreV2>(syncConfig);
        
        // 创建事件回调
        auto callback = std::make_unique<ExamplePlayerCallback>();
        player->setEventCallback(callback.get());
        
        // 如果命令行提供了文件名，自动打开
        if (argc > 1) {
            std::string filename = argv[1];
            std::cout << "Opening file: " << filename << std::endl;
            
            auto result = player->openFile(filename);
            if (result == ErrorCode::SUCCESS) {
                std::cout << "File opened successfully" << std::endl;
                
                // 自动开始播放
                result = player->play();
                if (result == ErrorCode::SUCCESS) {
                    std::cout << "Playback started" << std::endl;
                } else {
                    std::cout << "Failed to start playback: " << static_cast<int>(result) << std::endl;
                }
            } else {
                std::cout << "Failed to open file: " << static_cast<int>(result) << std::endl;
            }
        }
        
        // 启动用户界面
        SimplePlayerUI ui(player.get());
        
        // 启动更新线程
        std::atomic<bool> shouldStop(false);
        std::thread updateThread([&player, &shouldStop]() {
            while (!shouldStop) {
                player->update();
                std::this_thread::sleep_for(std::chrono::milliseconds(16)); // ~60 FPS
            }
        });
        
        // 运行用户界面
        ui.run();
        
        // 停止更新线程
        shouldStop = true;
        if (updateThread.joinable()) {
            updateThread.join();
        }
        
        // 停止播放器
        player->stop();
        
        std::cout << "PlayerCoreV2 Example finished" << std::endl;
        
    } catch (const std::exception& e) {
        std::cerr << "Exception: " << e.what() << std::endl;
        return 1;
    } catch (...) {
        std::cerr << "Unknown exception occurred" << std::endl;
        return 1;
    }
    
    return 0;
}