#include "code/player/player_core_v2.h"
#include "code/base/logger.h"

#include <iostream>
#include <fstream>
#include <thread>
#include <chrono>

using namespace av::player;
using namespace av;
class TestCallback : public PlayerEventCallback {
public:
    TestCallback(std::ofstream& output) : outputFile(output) {}
    
    void onStateChanged(PlayerState newState) override {
        std::cout << "State changed to: " << static_cast<int>(newState) << std::endl;
        currentState = newState;
    }
    
    void onMediaInfoChanged(const MediaInfo& info) override {
        std::cout << "Media info: " << info.filename << ", duration: " << info.duration
                  << std::endl;
    }
    
    void onPositionChanged(int64_t position) override {
        std::cout << "Position: " << position / 1000000.0 << "s" << std::endl;
        currentPosition = position;
    }
    
    void onErrorOccurred(const std::string& error) override {
        std::cout << "Error: " << error << std::endl;
    }

    void onEndOfFile() override { std::cout << "End of file" << std::endl; }

    void onSyncError(double error, const std::string& reason) override
    {
        std::cout << "Sync error: " << error << ", reason: " << reason << std::endl;
    }

    void onFrameDropped(int64_t count) override
    {
        std::cout << "Frame dropped: " << count << std::endl;
    }

    void onVideoFrameReady(AVFrame* frame) override
    {
        // 简单处理视频帧
    }

    void onVideoRendererInitRequired(int width, int height) override
    {
        std::cout << "Video renderer init: " << width << "x" << height << std::endl;
    }

    void onVideoRendererCloseRequired() override
    {
        std::cout << "Video renderer close" << std::endl;
    }

    PlayerState currentState = PlayerState::Idle;
    int64_t currentPosition = 0;
    
private:
    std::ofstream& outputFile;
};

int main() {
    // 创建输出文件
    std::ofstream outputFile("test_seek_pause_output.txt");
    if (!outputFile.is_open()) {
        std::cerr << "无法创建输出文件" << std::endl;
        return 1;
    }
    
    // 初始化日志
    Logger::instance().initialize("test.log", LogLevel::ERROR, false, true);
    Logger::instance().info("PlayerCoreV2 Example Started");

    // 创建播放器
    PlayerCoreV2 player;
    TestCallback callback(outputFile);
    player.setEventCallback(&callback);

    std::cout << "=== 测试修复后的暂停后seek功能 ===" << std::endl;

    // 请用户提供测试文件路径
    std::string filename = "C:/Users/zhuizhu/Videos/2.mp4";
    // std::cout << "请输入测试视频文件路径: ";
    // std::getline(std::cin, filename);

    // if (filename.empty()) {
    //     std::cout << "未提供文件路径，退出测试" << std::endl;
    //     return 1;
    // }

    // 打开文件
    std::cout << "\n1. 打开文件: " << filename << std::endl;
    auto result = player.openFile(filename);
    if (result != ErrorCode::SUCCESS) {
        std::cout << "打开文件失败" << std::endl;
        return 1;
    }
    
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    
    // 开始播放
    std::cout << "\n2. 开始播放" << std::endl;
    player.play();
    std::this_thread::sleep_for(std::chrono::seconds(3));
    
    // 暂停
    std::cout << "\n3. 暂停播放" << std::endl;
    player.pause();
    std::this_thread::sleep_for(std::chrono::milliseconds(500));
    
    // 获取当前位置
    int64_t pausePosition = player.getCurrentTime();
    std::cout << "暂停时位置: " << pausePosition / 1000000.0 << "s" << std::endl;

    // 在暂停状态下seek
    int64_t seekTarget = pausePosition + 5000000; // 向前seek 5秒
    std::cout << "\n4. 在暂停状态下seek到: " << seekTarget / 1000000.0 << "s" << std::endl;
    player.seek(seekTarget);
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    
    // 检查seek后的位置
    int64_t afterSeekPosition = player.getCurrentTime();
    std::cout << "seek后位置: " << afterSeekPosition / 1000000.0 << "s" << std::endl;
    std::cout << "状态: " << static_cast<int>(callback.currentState) << std::endl;

    // 验证结果
    if (callback.currentState == PlayerState::Paused) {
        std::cout << "✓ 状态正确：保持暂停状态" << std::endl;
    } else {
        std::cout << "✗ 状态错误：应该保持暂停状态" << std::endl;
    }
    
    if (std::abs(afterSeekPosition - seekTarget) < 1000000) { // 允许1秒误差
        std::cout << "✓ 位置正确：seek到目标位置" << std::endl;
    } else {
        std::cout << "✗ 位置错误：seek位置不正确" << std::endl;
        std::cout << "  期望: " << seekTarget / 1000000.0 << "s" << std::endl;
        std::cout << "  实际: " << afterSeekPosition / 1000000.0 << "s" << std::endl;
    }
    
    // 恢复播放测试
    std::cout << "\n5. 恢复播放测试" << std::endl;
    player.play();
    std::this_thread::sleep_for(std::chrono::seconds(2));
    
    int64_t playPosition = player.getCurrentTime();
    std::cout << "恢复播放后位置: " << playPosition / 1000000.0 << "s" << std::endl;

    if (playPosition > afterSeekPosition) {
        std::cout << "✓ 播放正常：时间在前进" << std::endl;
    } else {
        std::cout << "✗ 播放异常：时间没有前进" << std::endl;
    }

    // 测试连续seek
    std::cout << "\n6. 测试连续seek" << std::endl;
    player.pause();
    std::this_thread::sleep_for(std::chrono::milliseconds(500));
    
    // 第一次seek
    int64_t seek1 = seekTarget + 2000000; // 再向前2秒
    std::cout << "第一次seek到: " << seek1 / 1000000.0 << "s" << std::endl;
    player.seek(seek1);
    std::this_thread::sleep_for(std::chrono::milliseconds(500));
    
    int64_t pos1 = player.getCurrentTime();
    std::cout << "第一次seek后位置: " << pos1 / 1000000.0 << "s" << std::endl;

    // 第二次seek
    int64_t seek2 = seek1 - 3000000; // 向后3秒
    std::cout << "第二次seek到: " << seek2 / 1000000.0 << "s" << std::endl;
    player.seek(seek2);
    std::this_thread::sleep_for(std::chrono::milliseconds(500));
    
    int64_t pos2 = player.getCurrentTime();
    std::cout << "第二次seek后位置: " << pos2 / 1000000.0 << "s" << std::endl;

    if (callback.currentState == PlayerState::Paused) {
        std::cout << "✓ 连续seek测试：状态保持暂停" << std::endl;
    } else {
        std::cout << "✗ 连续seek测试：状态错误" << std::endl;
    }

    // 停止播放
    std::cout << "\n7. 停止播放" << std::endl;
    player.stop();

    std::cout << "\n=== 测试完成 ===" << std::endl;

    // 关闭输出文件
    outputFile.close();
    
    std::cout << "测试完成，结果已保存到 test_seek_pause_output.txt" << std::endl;
    
    return 0;
}
