#include "mainwindow.h"

#include <QSplitter>
#include <QStackedWidget>
#include <QTextBrowser>
#include <QThread>

#include <util/asynchelper.h>
#include <util/jsonmapper.h>
#include <util/layoutbuilder.h>

#include "api/roomapi.h"
#include "api/userapi.h"
#include "appevent.h"
#include "capturer/video/wgc/App.h"
#include "network/websocketclient.h"
#include "qboxlayout.h"
#include "qlistwidget.h"
#include "qobject.h"
#include "ui/av_recorder.h"
#include "views/loginwindow.h"

#include "widgets/bubbletip.h"
#include "widgets/chatView/chat1/chatview.h"
#include "widgets/chatView/chatwindow.h"
#include "widgets/framelessbase.h"
#include "widgets/maskoverlay.h"
// #include "widgets/userprofilewidget.h" // 未使用，移除
#include "widgets/meetingselectionwidget.h"
#include "widgets/joinmeetingdialog.h"
#include "widgets/createmeetingdialog.h"

#include <QDebug>
#include <QFutureWatcher>
#include <QJsonObject>

#include <api/loginapi.h>

#include "util/qformatter.h"

#include <qtpromise/qpromise.h>
#include <qtpromise/qpromisefuture.h>
#include <qtpromise/qpromisehelpers.h>

#include "MainPanel.h"

#include <QListWidget>

// MainWidget 类已移除，相关实现迁移到 MainPanel.cpp/h

MainWindow::MainWindow(QWidget *parent)
    : TMainWindow(parent)
{
    setWindowTitle("test");
    setCentralWidget(new QWidget(this));
    // 创建主布局
    layout = new QVBoxLayout(centralWidget());
    layout->setContentsMargins(0, 0, 0, 0);

    // 创建堆叠部件
    stackedWidget = new QStackedWidget(this);
    layout->addWidget(stackedWidget);

    // 创建登录页面
    loginWidget = new LoginWidget(this);
    stackedWidget->addWidget(loginWidget);

    // 创建会议选择页面
    meetingSelectionWidget = new MeetingSelectionWidget(this);
    stackedWidget->addWidget(meetingSelectionWidget);

    mainWidget = nullptr;

    connect(loginWidget, &LoginWidget::loginRequested, this, &MainWindow::onLoginSuccess);
    connect(meetingSelectionWidget, &MeetingSelectionWidget::joinMeetingRequested, this, &MainWindow::onJoinMeetingRequested);
    connect(meetingSelectionWidget, &MeetingSelectionWidget::createMeetingRequested, this, &MainWindow::onCreateMeetingRequested);
    connect(meetingSelectionWidget, &MeetingSelectionWidget::logoutRequested, this, &MainWindow::onMeetingSelectionLogout);
    
    resize(1024, 576);

    // 显示登录页面
    stackedWidget->setCurrentWidget(loginWidget);
}

MainWindow::~MainWindow() {}

void MainWindow::createMainWindow()
{
    if (mainWidget) {
        delete mainWidget;
        mainWidget = nullptr;
    }
    // 主窗口
    mainWidget = new MainPanel(this);
    stackedWidget->addWidget(mainWidget);

    // 退出处理
    connect(mainWidget, &MainPanel::logoutClicked, this, [this]() {
        AppEvent *appEvent = AppEvent::instance();
        appEvent->setJwtToken(QString()); // 清理token
        appEvent->setRefreshTime(0);      // 清理token刷新时间
        appEvent->setRoles({});           // 清理角色
        appEvent->setUserId({});          // 清理用户id

        stackedWidget->setCurrentWidget(loginWidget);
    });
}

void MainWindow::onLoginSuccess(const QString &username, const QString &password)
{
    // 准备登录参数
    AuthApi::LoginParams loginParams;
    loginParams.username = username;
    loginParams.password = password;

    QFuture<HttpResponse> loginApiFuture = AuthApi::loginApi(loginParams);

    // 使用fromQFuture将QFuture转换为QPromise
    QtPromise::QPromise<HttpResponse> loginApiPromise = QtPromise::resolve(loginApiFuture);

    MaskOverlay::instance()->show(stackedWidget, 0, MaskOverlay::ActiveWindow);

    loginApiPromise
        .then([this](const HttpResponse &response) {
            MaskOverlay::instance()->hide();
            if (response.code == 0) {
                // 登录成功后解析并保存JWT，确保后续请求携带Authorization
                QString token;
                if (response.data.isString()) {
                    token = response.data.toString();
                } else if (response.data.isObject()) {
                    const QJsonObject obj = response.data.toObject();
                    token = obj.value("accessToken").toString();
                    if (token.isEmpty()) token = obj.value("token").toString();
                    if (token.isEmpty()) token = obj.value("jwt").toString();
                }
                if (!token.isEmpty()) {
                    AppEvent::instance()->setJwtToken(token);
                }
                // 显示会议选择页面（内部会调用获取用户信息）
                authLogin();
            } else {
                BubbleTip::showTip(this,
                                   QString("登录失败: %1").arg(response.message),
                                   BubbleTip::Top,
                                   3000,
                                   BubbleTip::Type::Error);
            }
        })
        .fail([this](const std::exception &e) {
            MaskOverlay::instance()->hide();
            BubbleTip::showTip(this,
                               QString("登录失败: %1").arg(e.what()),
                               BubbleTip::Top,
                               3000,
                               BubbleTip::Type::Error);
        });
}

void MainWindow::authLogin()
{
    QFuture<HttpResponse> getUserInfoFuture = getUserInfoApi();

    // 使用fromQFuture将QFuture转换为QPromise
    QtPromise::QPromise<HttpResponse> userInfoPromise = QtPromise::resolve(getUserInfoFuture);

    MaskOverlay::instance()->show(stackedWidget, 0, MaskOverlay::ActiveWindow);

    userInfoPromise
        .then([this](const HttpResponse &response) {
            MaskOverlay::instance()->hide();
            if (response.code == 0) {
                UserInfo userInfo = JsonMapper::fromJson<UserInfo>(response.data);
                AppEvent *appEvent = AppEvent::instance();
                appEvent->setUserId(userInfo.id);
                appEvent->setUserName(userInfo.username);
                appEvent->setRoles(userInfo.roleName);
                showMeetingSelection();
            } else {
                qDebug() << QString("获取用户信息失败: %1").arg(response.message);
                BubbleTip::showTip(this,
                                   QString("获取用户信息失败: %1").arg(response.message),
                                   BubbleTip::Top,
                                   3000,
                                   BubbleTip::Type::Error);
            }
        })
        .fail([this](const std::exception &e) {
            MaskOverlay::instance()->hide();
            BubbleTip::showTip(this,
                               QString("获取用户信息失败: %1").arg(e.what()),
                               BubbleTip::Top,
                               3000,
                               BubbleTip::Type::Error);
        });
}

void MainWindow::showMeetingSelection()
{
    AppEvent *appEvent = AppEvent::instance();
    meetingSelectionWidget->setUserRoles(appEvent->roles());
    meetingSelectionWidget->setUserInfo(appEvent->userName(), appEvent->userId());
    
    // 显示会议选择页面
    stackedWidget->setCurrentWidget(meetingSelectionWidget);
}

void MainWindow::onJoinMeetingRequested()
{
    // 创建加入会议对话框
    JoinMeetingDialog *joinDialog = new JoinMeetingDialog(this);
    
    // 获取会议列表并设置到对话框
    RoomInfo roomInfo;
    QFuture<HttpResponse> getRoomListFuture = getRoomListApi(roomInfo);
    
    // 使用QtPromise处理异步获取会议列表
    QtPromise::QPromise<HttpResponse> roomListPromise = QtPromise::resolve(getRoomListFuture);
    
    roomListPromise
        .then([this, joinDialog](const HttpResponse &response) {
            qDebug() << "获取会议列表:" << response.data << response.rawData << response.message;
            
            if (response.code == 0) {
                RoomListData roomListData(response.data.toObject());
                QList<RoomInfo> roomInfos = roomListData.getRooms();
                
                QStringList meetingIds;
                QStringList meetingNames;
                
                // 提取会议ID和名称
                for (const RoomInfo &room : roomInfos) {
                    if (room.id.has_value() && room.name.has_value()) {
                        meetingIds.append(room.id.value());
                        meetingNames.append(room.name.value());
                    }
                }

                // 设置可用的会议列表
                joinDialog->setAvailableMeetings(meetingIds, meetingNames);
            } else {
                qWarning() << "获取会议列表失败:" << response.message;
                BubbleTip::showTip(this,
                                   QString("获取会议列表失败: %1").arg(response.message),
                                   BubbleTip::Top,
                                   3000,
                                   BubbleTip::Type::Error);
            }
            
            // 显示对话框
            if (joinDialog->exec() == JoinMeetingDialog::Accepted) {
                QString meetingId = joinDialog->getSelectedMeetingId();
                
                // 独立窗口加入会议（观看者模式）
                MainPanel *panel = new MainPanel(nullptr);
                panel->setAttribute(Qt::WA_DeleteOnClose);
                panel->setRole({"role.viewer"});
                connect(panel, &MainPanel::logoutClicked, panel, &QWidget::close);
                panel->show();
                
                // 检查房间状态并验证会议ID是否存在
                checkRoom(panel, meetingId);
            }
            
            joinDialog->deleteLater();
        })
        .fail([this, joinDialog](const std::exception &e) {
            qWarning() << "获取会议列表异常:" << e.what();
            BubbleTip::showTip(this,
                               QString("获取会议列表失败: %1").arg(e.what()),
                               BubbleTip::Top,
                               3000,
                               BubbleTip::Type::Error);
            
            // 即使获取失败也显示对话框，允许手动输入
            if (joinDialog->exec() == JoinMeetingDialog::Accepted) {
                QString meetingId = joinDialog->getSelectedMeetingId();
                
                // 独立窗口加入会议（观看者模式）
                MainPanel *panel = new MainPanel(nullptr);
                panel->setAttribute(Qt::WA_DeleteOnClose);
                panel->setRole({"role.viewer"});
                connect(panel, &MainPanel::logoutClicked, panel, &QWidget::close);
                panel->show();
                
                // 检查房间状态并验证会议ID是否存在
                checkRoom(panel, meetingId);
            }
            
            joinDialog->deleteLater();
        });
}

void MainWindow::onCreateMeetingRequested()
{
    // 获取会议列表并设置到对话框
    RoomInfo roomInfo;
    roomInfo.ownerId = AppEvent::instance()->userId();

    QFuture<HttpResponse> getRoomListFuture = getRoomListApi(roomInfo);

    // 使用QtPromise处理异步获取会议列表
    QtPromise::QPromise<HttpResponse> roomListPromise = QtPromise::resolve(getRoomListFuture);

    roomListPromise
        .then([this](const HttpResponse &response) {
            qDebug() << "获取会议列表:" << response.data << response.rawData << response.message;

            QStringList meetingIds;
            if (response.code == 0) {
                RoomListData roomListData(response.data.toObject());
                QList<RoomInfo> roomInfos = roomListData.getRooms();

                QStringList meetingNames;

                // 提取会议ID和名称
                for (const RoomInfo &room : std::as_const(roomInfos)) {
                    if (room.id.has_value() && room.name.has_value()) {
                        meetingIds.append(room.id.value());
                        meetingNames.append(room.name.value());
                    }
                }
            } else {
                qWarning() << "获取会议列表失败:" << response.message;
                BubbleTip::showTip(this,
                                   QString("获取会议列表失败: %1").arg(response.message),
                                   BubbleTip::Top,
                                   3000,
                                   BubbleTip::Type::Error);
            }

            // 独立窗口创建/开启会议（管理员模式）
            MainPanel *panel = new MainPanel(nullptr);
            panel->setAttribute(Qt::WA_DeleteOnClose);
            panel->setRole({"role.admin"});
            connect(panel, &MainPanel::logoutClicked, panel, &QWidget::close);
            panel->show();

            if (meetingIds.size() > 0) {
                checkRoom(panel, meetingIds[0]);
            }
        })
        .fail([this](const std::exception &e) {
            qWarning() << "获取会议列表异常:" << e.what();
            BubbleTip::showTip(this,
                               QString("获取会议列表失败: %1").arg(e.what()),
                               BubbleTip::Top,
                               3000,
                               BubbleTip::Type::Error);
        });
}

void MainWindow::onMeetingSelectionLogout()
{
    // 清理用户信息
    AppEvent *appEvent = AppEvent::instance();
    appEvent->setJwtToken(QString()); // 清理token
    appEvent->setRefreshTime(0);      // 清理token刷新时间
    appEvent->setRoles({});           // 清理角色
    appEvent->setUserId({});          // 清理用户id
    appEvent->setUserName({});        // 清理用户名
    
    // 返回登录页面
    stackedWidget->setCurrentWidget(loginWidget);
}

void MainWindow::checkRoom(MainPanel *target, const QString &meetingId)
{
    // 创建两个异步操作的Promise
    RoomInfo roomInfo;
    roomInfo.id = meetingId;
    QFuture<HttpResponse> getRoomListFuture = getRoomListApi(roomInfo);

    // 使用fromQFuture将QFuture转换为QPromise
    QtPromise::QPromise<HttpResponse> userInfoPromise = QtPromise::resolve(getRoomListFuture);

    // 使用QtPromise::all等待所有Promise完成
    QtPromise::all(QVector<QtPromise::QPromise<HttpResponse>>{userInfoPromise})
        .then([this, target, meetingId](const QVector<HttpResponse> &results) {
            const HttpResponse &getRoomList = results[0];
            qDebug() << "访问房间:" << getRoomList.data << getRoomList.rawData
                     << getRoomList.message;
            // JsonObject({"data":[{"createdAt":1752512296000,"createdId":null,"description":"","id":"019809df-75db-73db-adbb-2ca949a9329a","maxUsers":100,"name":"默认房间","ownerId":"0196e8ac-c737-7f93-ba6a-6562f2c8854d","status":1,"updatedAt":1752512296000}],"total":1})

            RoomListData roomListData(getRoomList.data.toObject());
            QList<RoomInfo> RoomInfos = roomListData.getRooms();
            qDebug() << RoomInfos.size();

            // 如果有待验证的会议ID，检查是否存在
            if (!meetingId.isEmpty()) {
                bool meetingFound = false;
                int foundIndex = -1;
                
                for (int i = 0; i < RoomInfos.size(); ++i) {
                    const RoomInfo room = RoomInfos.at(i);
                    if (room.id.value_or("") == meetingId) {
                        meetingFound = true;
                        foundIndex = i;
                        break;
                    }
                }
                
                if (meetingFound) {
                    // 会议ID存在，设置为当前房间
                    if (target) target->setPushRoomId(meetingId);
                    qDebug() << "成功加入会议:" << meetingId;

                    BubbleTip::showTip(this,
                                       QString("成功加入会议: %1").arg(meetingId),
                                       BubbleTip::Top,
                                       3000,
                                       BubbleTip::Type::Success);
                } else {
                    // 会议ID不存在，显示错误提示
                    qWarning() << "会议ID不存在:" << meetingId;

                    BubbleTip::showTip(this,
                                       QString("会议ID不存在: %1").arg(meetingId),
                                       BubbleTip::Top,
                                       5000,
                                       BubbleTip::Type::Error);

                    // 回到会议选择页面
                    showMeetingSelection();
                }
            } else if (RoomInfos.size() > 0) {
                // 没有待验证的会议ID，使用默认的第一个房间
                if (target) target->setPushRoomId(RoomInfos[0].id.value_or(""));
            }
        })
        .fail([this](const std::exception &e) {
            // 处理错误
            qWarning() << "[异常]获取房间失败:" << e.what();
            BubbleTip::showTip(this,
                               QString("请求失败: %1").arg(e.what()),
                               BubbleTip::Top,
                               3000,
                               BubbleTip::Type::Error);
        });
}
