#include "avplayerwidget.h"

#include "avopenglwidget.h"

#include "av_player.h"
#include "vframe.h"
#include <QtConcurrent>
#include <QApplication>
#include <QDebug>
#include <QElapsedTimer>

AVPlayerWidget::AVPlayerWidget(QWidget *parent)
    : QWidget{parent}
    , m_player(new AVPlayer)
    , m_openglWidget(new AVOpenGLWidget(this))
    , m_isPlaying(false)
    , m_isPaused(false)
    , m_isLoading(false)
    , m_playWatcher(new QFutureWatcher<bool>(this))
    , m_loadingLabel(nullptr)
    , m_loadingProgress(nullptr)
    , m_loadingMovie(nullptr)
{
    // 设置尺寸策略，确保能够正确填充空间
    setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    
    setupUI();
    connectSignals();
    
    // 设置默认音量
    m_player->setVolume(50);
    m_volumeSlider->setValue(50);
    
    // 设置默认测试URL
    m_urlEdit->setText("rtmp://106.55.186.74:1935/stream/V1/");
}

AVPlayerWidget::~AVPlayerWidget()
{
    if (m_player) {
        m_player->clearPlayer();
    }
}

void AVPlayerWidget::setupUI()
{
    m_mainLayout = new QVBoxLayout(this);
    m_mainLayout->setContentsMargins(5, 5, 5, 5);  // 减少主布局边距
    m_mainLayout->setSpacing(5);  // 减少组件间距
    
    // 添加OpenGL视频渲染组件
    m_mainLayout->addWidget(m_openglWidget, 1);
    
    // 创建加载状态UI组件（初始隐藏）
    m_loadingLabel = new QLabel("正在连接...", this);
    m_loadingLabel->setAlignment(Qt::AlignCenter);
    m_loadingLabel->setStyleSheet("QLabel { background-color: rgba(0, 0, 0, 180); color: white; font-size: 16px; padding: 10px; border-radius: 5px; }");
    m_loadingLabel->hide();
    
    m_loadingProgress = new QProgressBar(this);
    m_loadingProgress->setRange(0, 0);  // 无限进度条
    m_loadingProgress->setStyleSheet("QProgressBar { border: 2px solid grey; border-radius: 5px; text-align: center; } QProgressBar::chunk { background-color: #05B8CC; width: 20px; }");
    m_loadingProgress->hide();
    
    // 创建控制面板容器
    QWidget *controlWidget = new QWidget(this);
    controlWidget->setFixedHeight(60);  // 设置控制面板固定高度
    controlWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    
    m_controlLayout = new QHBoxLayout(controlWidget);
    m_controlLayout->setContentsMargins(5, 5, 5, 5);  // 减少控制面板内边距
    m_controlLayout->setSpacing(5);  // 减少控件间距
    
    // URL输入框
    m_urlEdit = new QLineEdit(this);
    m_urlEdit->setPlaceholderText("输入视频文件路径或URL");
    m_urlEdit->setFixedHeight(30);  // 固定高度适应控制面板
    m_urlEdit->setFont(QFont("Arial", 9));
    m_controlLayout->addWidget(m_urlEdit, 2);
    
    // 测试播放按钮
    m_testPlayButton = new QPushButton("测试播放", this);
    m_testPlayButton->setFixedSize(70, 30);  // 固定尺寸
    m_testPlayButton->setFont(QFont("Arial", 9, QFont::Bold));
    m_controlLayout->addWidget(m_testPlayButton);
    
    // 播放控制按钮
    m_playButton = new QPushButton("播放", this);
    m_playButton->setFixedSize(50, 30);  // 固定尺寸
    m_playButton->setFont(QFont("Arial", 9, QFont::Bold));
    
    m_pauseButton = new QPushButton("暂停", this);
    m_pauseButton->setFixedSize(50, 30);  // 固定尺寸
    m_pauseButton->setFont(QFont("Arial", 9, QFont::Bold));
    
    m_stopButton = new QPushButton("停止", this);
    m_stopButton->setFixedSize(50, 30);  // 固定尺寸
    m_stopButton->setFont(QFont("Arial", 9, QFont::Bold));
    
    m_controlLayout->addWidget(m_playButton);
    m_controlLayout->addWidget(m_pauseButton);
    m_controlLayout->addWidget(m_stopButton);
    
    // 音量控制
    QLabel *volumeLabel = new QLabel("音量:", this);
    volumeLabel->setFont(QFont("Arial", 9));
    m_volumeSlider = new QSlider(Qt::Horizontal, this);
    m_volumeSlider->setRange(0, 100);
    m_volumeSlider->setValue(50);
    m_volumeSlider->setFixedSize(100, 20);  // 固定尺寸
    
    m_controlLayout->addWidget(volumeLabel);
    m_controlLayout->addWidget(m_volumeSlider);
    
    // 时间显示
    m_timeLabel = new QLabel("00:00 / 00:00", this);
    m_timeLabel->setFont(QFont("Arial", 9));
    m_timeLabel->setFixedWidth(80);
    m_controlLayout->addWidget(m_timeLabel);
    
    m_mainLayout->addWidget(controlWidget, 0);  // 拉伸因子为0，不占用额外空间
    
    // 设置初始状态
    m_pauseButton->setEnabled(false);
    m_stopButton->setEnabled(false);

    controlWidget->hide();
}

void AVPlayerWidget::connectSignals()
{
    // 连接AVPlayer信号
    connect(m_player, &AVPlayer::frameChanged, this, &AVPlayerWidget::onFrameChanged, Qt::QueuedConnection);
    connect(m_player, &AVPlayer::AVDurationChanged, this, &AVPlayerWidget::durationChangedSlot);
    connect(m_player, &AVPlayer::AVPtsChanged, this, &AVPlayerWidget::ptsChangedSlot);
    connect(m_player, &AVPlayer::AVTerminate, this, &AVPlayerWidget::terminateSlot, Qt::QueuedConnection);
    
    // 连接UI控件信号
    connect(m_playButton, &QPushButton::clicked, this, &AVPlayerWidget::onPlayButtonClicked);
    connect(m_pauseButton, &QPushButton::clicked, this, &AVPlayerWidget::onPauseButtonClicked);
    connect(m_stopButton, &QPushButton::clicked, this, &AVPlayerWidget::onStopButtonClicked);
    connect(m_testPlayButton, &QPushButton::clicked, this, &AVPlayerWidget::onTestPlayButtonClicked);
    connect(m_volumeSlider, &QSlider::valueChanged, this, &AVPlayerWidget::onVolumeChanged);
    
    // 连接异步播放信号
    connect(m_playWatcher, &QFutureWatcher<bool>::finished, this, &AVPlayerWidget::onAsyncPlayFinished);
}

void AVPlayerWidget::play(const QString &url)
{
    if (!m_player->play(url)) {
        // 提示反馈?
        return;
    }
    m_isPlaying = true;
    m_isPaused = false;
    m_playButton->setEnabled(false);
    m_pauseButton->setEnabled(true);
    m_stopButton->setEnabled(true);
    emit playStateChanged(true);
}

void AVPlayerWidget::stop()
{
    m_player->clearPlayer();
    m_isPlaying = false;
    m_isPaused = false;
    m_playButton->setEnabled(true);
    m_pauseButton->setEnabled(false);
    m_stopButton->setEnabled(false);
    m_openglWidget->clearFrame();
    emit playStateChanged(false);
}

void AVPlayerWidget::pause()
{
    if (m_isPlaying && !m_isPaused) {
        m_player->pause(true);
        m_isPaused = true;
        m_playButton->setText("继续");
        m_playButton->setEnabled(true);
        m_pauseButton->setEnabled(false);
    }
}

void AVPlayerWidget::resume()
{
    if (m_isPlaying && m_isPaused) {
        m_player->pause(false);
        m_isPaused = false;
        m_playButton->setText("播放");
        m_playButton->setEnabled(false);
        m_pauseButton->setEnabled(true);
    }
}

void AVPlayerWidget::onPlayButtonClicked()
{
    if (m_isPaused) {
        resume();
    } else {
        QString url = m_urlEdit->text().trimmed();
        if (!url.isEmpty()) {
            play(url);
        }
    }
}

void AVPlayerWidget::onPauseButtonClicked()
{
    pause();
}

void AVPlayerWidget::onStopButtonClicked()
{
    stop();
}

void AVPlayerWidget::onTestPlayButtonClicked()
{
    // 使用默认测试视频
    QString testUrl = "C:/Users/zhuizhu/Videos/2.mp4";
    m_urlEdit->setText(testUrl);
    play(testUrl);
}

void AVPlayerWidget::onVolumeChanged(int volume)
{
    m_player->setVolume(volume);
}

void AVPlayerWidget::onFrameChanged(QSharedPointer<VideoFrame> frame)
{
    m_openglWidget->onShowYUV(frame);

    // 注意：这里不要释放avFrame，因为Render方法会处理
}

void AVPlayerWidget::ptsChangedSlot(unsigned int pts)
{
    // 更新时间显示
    int seconds = pts / 1000;
    int minutes = seconds / 60;
    seconds = seconds % 60;
    
    QString timeStr = QString("%1:%2").arg(minutes, 2, 10, QChar('0')).arg(seconds, 2, 10, QChar('0'));
    // 这里可以更新时间标签的当前时间部分
}

void AVPlayerWidget::durationChangedSlot(unsigned int duration)
{
    // 更新总时长显示
    int seconds = duration / 1000;
    int minutes = seconds / 60;
    seconds = seconds % 60;
    
    QString durationStr = QString("%1:%2").arg(minutes, 2, 10, QChar('0')).arg(seconds, 2, 10, QChar('0'));
    m_timeLabel->setText(QString("00:00 / %1").arg(durationStr));
}

void AVPlayerWidget::terminateSlot()
{
    stop();
}

// 兼容旧接口实现
void AVPlayerWidget::stopPlay()
{
    stop();
}

void AVPlayerWidget::setPlayRoomId(const QString &id)
{
    // 以当前URL为基准，去掉最后一节后拼接房间ID，避免硬编码服务器地址
    QString base = m_urlEdit->text().trimmed();
    if (base.isEmpty()) {
        base = "rtmp://106.55.186.74:1935/stream/V1/";
    }
    // rtmp://106.55.186.74:1935/stream/V1/0198da41-cdb6-78e3-879d-2ea32d58f73f
    int lastSlash = base.lastIndexOf('/');
    QString streamBase = lastSlash > 0 ? base.left(lastSlash) : base;
    QString url = streamBase + "/" + id;

    qDebug() << "setPlayRoomId" << url;
    m_urlEdit->setText(url);
}

void AVPlayerWidget::startPlay()
{
    const QString url = m_urlEdit->text().trimmed();
    if (!url.isEmpty()) {
        qDebug() << "startPlay" << url;
        playAsync(url);  // 使用异步播放
    }
}

void AVPlayerWidget::playAsync(const QString &url)
{
    if (m_isLoading) {
        qDebug() << "Already loading, ignoring new play request";
        return;
    }
    
    m_pendingUrl = url;
    m_isLoading = true;
    
    // 显示加载状态
    showLoadingUI();
    emit playLoadingStarted();
    
    // 在后台线程执行播放逻辑
    QFuture<bool> future = QtConcurrent::run([this, url]() -> bool {
        try {
            // 创建临时播放器用于测试连接
            AVPlayer testPlayer;
            
            // 设置超时时间（10秒）
            QElapsedTimer timer;
            timer.start();
            const int timeoutMs = 10000;
            
            bool success = testPlayer.play(url);
            
            // 检查是否超时
            if (timer.elapsed() > timeoutMs) {
                qDebug() << "Connection timeout after" << timeoutMs << "ms";
                testPlayer.clearPlayer();
                return false;
            }
            
            if (!success) {
                qDebug() << "Failed to connect to stream:" << url;
                return false;
            }
            
            // 连接成功，清理测试播放器
            testPlayer.clearPlayer();
            return true;
            
        } catch (const std::exception &e) {
            qDebug() << "Exception during async play:" << e.what();
            return false;
        } catch (...) {
            qDebug() << "Unknown exception during async play";
            return false;
        }
    });
    
    m_playWatcher->setFuture(future);
}

void AVPlayerWidget::startPlayAsync()
{
    const QString url = m_urlEdit->text().trimmed();
    if (!url.isEmpty()) {
        playAsync(url);
    }
}

void AVPlayerWidget::onAsyncPlayFinished()
{
    m_isLoading = false;
    hideLoadingUI();
    
    bool success = m_playWatcher->result();
    if (success) {
        // 连接成功，使用主线程播放器开始播放
        if (!m_player->play(m_pendingUrl)) {
            QString errorMsg = "播放失败：无法初始化播放器";
            qDebug() << errorMsg;
            emit playError(errorMsg);
            return;
        }
        m_isPlaying = true;
        m_isPaused = false;
        m_playButton->setEnabled(false);
        m_pauseButton->setEnabled(true);
        m_stopButton->setEnabled(true);
        emit playStateChanged(true);
        emit playLoadingFinished();
        qDebug() << "Successfully started playing:" << m_pendingUrl;
    } else {
        QString errorMsg;
        if (m_pendingUrl.startsWith("rtmp://")) {
            errorMsg = "RTMP连接失败：请检查流地址是否正确，网络是否畅通";
        } else if (m_pendingUrl.startsWith("http://") || m_pendingUrl.startsWith("https://")) {
            errorMsg = "HTTP流连接失败：请检查网络连接和流地址";
        } else {
            errorMsg = "连接失败：不支持的协议或无效的流地址";
        }
        qDebug() << "Play failed for URL:" << m_pendingUrl;
        emit playError(errorMsg);
    }
}

void AVPlayerWidget::onAsyncPlayError(const QString &error)
{
    m_isLoading = false;
    hideLoadingUI();
    emit playError(error);
}

void AVPlayerWidget::showLoadingUI()
{
    if (m_loadingLabel && m_loadingProgress) {
        // 计算居中位置
        QRect rect = m_openglWidget->geometry();
        int labelWidth = 200;
        int labelHeight = 50;
        int progressWidth = 300;
        int progressHeight = 20;
        
        m_loadingLabel->setGeometry(
            rect.x() + (rect.width() - labelWidth) / 2,
            rect.y() + (rect.height() - labelHeight) / 2 - 30,
            labelWidth, labelHeight
        );
        
        m_loadingProgress->setGeometry(
            rect.x() + (rect.width() - progressWidth) / 2,
            rect.y() + (rect.height() - progressHeight) / 2 + 30,
            progressWidth, progressHeight
        );
        
        m_loadingLabel->show();
        m_loadingProgress->show();
        m_loadingLabel->raise();
        m_loadingProgress->raise();
    }
}

void AVPlayerWidget::hideLoadingUI()
{
    if (m_loadingLabel && m_loadingProgress) {
        m_loadingLabel->hide();
        m_loadingProgress->hide();
    }
}
