#include <QDebug>
#include <QFont>
#include <QVBoxLayout>
#include <QPushButton>
#include "custom_message_box.h"
#include <QByteArray>
#include "mainwindow.h"
#include "find_and_match_ppds.h"
#include "base_notify_dialog.h"
#include "self_destroy_message_box.h"
#include "daemonipcdbus.h"
#include "size_para.h"
#include "global_variable.h"
#include "windowmanage.hpp"

#define g_popWindow PopWindowManager::getInstance()

MainWindow::MainWindow(QWidget *parent) :
            QMainWindow(parent),
            m_dbus(nullptr),
            m_AddWindow(nullptr),
            m_propertyDialog(nullptr),
            m_jobListDialog(nullptr),
            m_allPrintersVector()
{
    qDebug() << "主窗口初始化";
    g_printerManger.enumPrinters(m_allPrintersVector);

    kabase::WindowManage::getWindowId(&m_windowId);
    kabase::WindowManage::removeHeader(this);
    initModule();
    initQSS();
    initConnect();

    m_centerWidget->setLayout(m_HLayoutWholeWin);

    setCentralWidget(m_centerWidget);

    QRect availableGeometry = qApp->primaryScreen()->availableGeometry();
    this->move((availableGeometry.width()-this->width())/2, (availableGeometry.height()-this->height())/2);
    this->installEventFilter(this);
    if(m_allPrintersVector.size())
    {
        qDebug() << "打印机数量";
        m_currentSelectedPrinter = m_allPrintersVector.at(m_allPrintersVector.size() - 1);
        emit updateListSector(m_allPrintersVector, m_currentSelectedPrinter);
    }
    emit getCurFontSize();
    m_timer = new QTimer(this);
    m_timer->setInterval(5000);
    connect(m_timer,SIGNAL(timeout()),this,SLOT(updateImmediately()));
    m_timer->start();
}

MainWindow::~MainWindow()
{
    // qDebug() << "主窗口析构";
    // if(m_dbus != nullptr)
    //     m_dbus->deleteLater();
}

void MainWindow::topWindow()
{
    qDebug()<<"Set mainwindow to toplevel.";
    if(!this->isActiveWindow())
    {
        this->hide();
        this->show();
    }
    this->show();
    this->raise();
    this->activateWindow();
}
void MainWindow::onBtnClicked()
{
    qDebug() << "add Device!";
    QPoint temp = QPoint(this->mapToGlobal(QPoint(0,0)).x() + this->width()/2,this->mapToGlobal(QPoint(0,0)).y() + this->height()/2);
    if(m_AddWindow == nullptr)
    {
        qDebug() << "New Add Window";
        m_AddWindow = new AddPrinterWindow(temp,this);
        connect(m_AddWindow,SIGNAL(needUpdateDests(QString)),this,SLOT(updateMainWindowByAdd(QString)));
    }
    emit m_AddWindow->showThis(temp);
}

void MainWindow::initModule()
{
    //UI
    m_centerWidget = new QWidget(this);
    setWindowTitle(tr("Printer"));
//    setWindowIcon(QIcon::fromTheme("kylin-printer"));
    setFixedSize(MAIN_WIN_WIDTH,MAIN_WIN_HEIGHT);
    setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed);

    //Dbus
    m_dbus = DaemonIpcDbus::getInstance();

    m_leftWidget = new LeftWidget(this);
    m_leftWidget->setObjectName("leftWidget");
    m_leftWidget->setFixedSize(QSize(NAVIGATION_SECTOR_WIDTH,MAIN_WIN_HEIGHT));
    m_leftWidget->setAutoFillBackground(true);
    m_leftWidget->setBackgroundRole(QPalette::Window);

    m_rightWidget= new RightWidget(this);
    m_rightWidget->setObjectName("rightWidget");
    m_rightWidget->setFixedSize(QSize(EXHBITION_SECTOR_WIDTH,MAIN_WIN_HEIGHT));
    m_rightWidget->setAutoFillBackground(true);
    m_rightWidget->setBackgroundRole(QPalette::Base);
    m_rightWidget->hideExhbitionSector();
}

void MainWindow::initConnect()
{
    connect(m_dbus, SIGNAL(show()), this, SLOT(topWindow()));

    connect(m_leftWidget,&LeftWidget::addDevice,this,&MainWindow::onBtnClicked);
    connect(this,SIGNAL(updateListSector(QList<UkuiUsbPrinter>,UkuiUsbPrinter)),
            m_leftWidget,SLOT(updateListSector(QList<UkuiUsbPrinter>,UkuiUsbPrinter)));
    connect(this,SIGNAL(addPrinterToListSector(UkuiUsbPrinter)),m_leftWidget,SLOT(addPrinterToListSector(UkuiUsbPrinter)));

    connect(m_leftWidget,SIGNAL(printerIsSelected(const UkuiUsbPrinter&)),
            this,SLOT(updateRightWidgetByCheckBtn(const UkuiUsbPrinter&)));
    connect(m_leftWidget,SIGNAL(printerIsSelected(const UkuiUsbPrinter&)),
            this,SLOT(updateCurrentSelectedPrinter(const UkuiUsbPrinter&)));
    connect(m_leftWidget,SIGNAL(delDevice(QString)),
            this,SLOT(updateMainWindowByDel(QString)));
    connect(m_leftWidget,&LeftWidget::noBtnIsChecked,[=](){
        m_rightWidget->hideExhbitionSector();
    });
    connect(this,SIGNAL(updateRightWidget(const UkuiUsbPrinter&)),
            m_rightWidget,SLOT(updateExhbitionSector(const UkuiUsbPrinter&)));
    connect(m_rightWidget->m_deviceExhbitionMyWidget, &MainWinPropertyWidget::ppdDialogShowRequest,
            this, &MainWindow::ppdDialogShow);
    connect(this,SIGNAL(showPPDSelectDialog()),this,SLOT(ppdDialogShow()));
    connect(m_rightWidget->m_deviceExhbitionMyWidget,SIGNAL(sendOutCurrentPinterInfo(const UkuiUsbPrinter&)),
            this,SLOT(propertyDialogShow(const UkuiUsbPrinter&)));
    connect(m_rightWidget->m_deviceExhbitionMyWidget,SIGNAL(sendOutCurrentPinterName(const QString&)),
            this,SLOT(jobListDialogShow(const QString&)));
    connect(m_rightWidget->m_deviceExhbitionMyWidget,SIGNAL(currentPinterInfoPrintTest(const UkuiUsbPrinter&)),
            this,SLOT(printTestPage(const UkuiUsbPrinter&)));
    connect(m_rightWidget->m_deviceExhbitionMyWidget,SIGNAL(updateWholeMainWin(QString)),
            this,SLOT(updateByRename(QString)));

    connect(this,SIGNAL(clearRightWidget()),m_rightWidget,SLOT(hideExhbitionSector()));

    connect(this,SIGNAL(updateMainWin()),this,SLOT(updateImmediately()));
    connect(this,SIGNAL(modifyPPD(QString)),this,SLOT(updateByChangePPD(QString)));
}
void MainWindow::initQSS()
{
    //全局布局
    m_HLayoutWholeWin  = new QHBoxLayout(m_centerWidget);

    m_HLayoutWholeWin->setSpacing(0);
    m_HLayoutWholeWin->setMargin(0);
    m_HLayoutWholeWin->addSpacing(0);
    m_HLayoutWholeWin->addWidget(m_leftWidget);
    m_HLayoutWholeWin->addWidget(m_rightWidget);
    m_HLayoutWholeWin->addStretch();
}

void MainWindow::updateRightWidgetByCheckBtn(const UkuiUsbPrinter& printer)
{
    qDebug() << "当前选中打印机名称：" << (printer.name);
    qDebug() << "当前选中打印机驱动：" << (printer.make_and_model);
    emit updateRightWidget(printer);
}

void MainWindow::updateMainWindowByAdd(QString printerName)
{
    m_allPrintersVector.clear();
    g_printerManger.enumPrinters(m_allPrintersVector);

    QList<UkuiUsbPrinter>::iterator printer;

    for(printer = m_allPrintersVector.begin();printer != m_allPrintersVector.end();printer++)
    {
        if(printer->name == printerName)
        {
            emit addPrinterToListSector(*printer);
            break;
        }
    }

    emit updateListSector(m_allPrintersVector, m_currentSelectedPrinter);
    emit getCurFontSize();
}

void MainWindow::updateMainWindowByDel(QString printerName)
{
    m_allPrintersVector.clear();
    g_printerManger.enumPrinters(m_allPrintersVector);
    qDebug() <<"打印机" << printerName << "删除按钮被点下";
    QList<UkuiUsbPrinter>::iterator printer;
    for(printer = m_allPrintersVector.begin(); printer != m_allPrintersVector.end(); printer++)
    {
        qDebug() << "遍历打印机列表中，当前打印机名称为："
                 <<  (printer->name);
        if(printer->name == printerName)
        {
            if(g_printerManger.removePrinter(printerName))
            {
                m_allPrintersVector.erase(printer);
                break;
            }
            else
            {
                QString showMsg = printerName;
                QString warningMsg = tr("Delete Failed!");
                showMsg.append(warningMsg);
                CustomMessageBox Msg(CustomMessageBox::Warning,tr("Warning"),showMsg,CustomMessageBox::NoButton);
                Msg.setParent(this);
                Msg.addButton(tr("Close"), CustomMessageBox::NoRole);
                Msg.exec();
                break;
            }

        }
    }
    if(m_allPrintersVector.size() != 0)
    {
        m_currentSelectedPrinter = m_allPrintersVector.at(m_allPrintersVector.size() - 1);
    }
    emit updateListSector(m_allPrintersVector,m_currentSelectedPrinter);
    emit getCurFontSize();
}

void MainWindow::ppdDialogShow(const QString &str)
{
    m_pDebInstallWindow = new DebInstallWindow(this);

    connect(m_pDebInstallWindow,SIGNAL(modifyPPDName(QString)),this,SLOT(modifyPrinterPPD(QString)));
    connect(m_pDebInstallWindow,SIGNAL(getCurFontSize()),this,SIGNAL(getCurFontSize()));
    m_pDebInstallWindow->onShow(str);
    m_pDebInstallWindow->exec();
}
void MainWindow::updateByChangePPD(QString ppdName)
{
    modifyPrinterPPD(ppdName);
    emit getCurFontSize();
}
void MainWindow::modifyPrinterPPD(QString ppd)
{
    bool ret = false;
    ret = g_printerManger.addPrinter(m_currentSelectedPrinter.device_uri
                                     ,m_currentSelectedPrinter.name,ppd
                                     ,m_currentSelectedPrinter.location);
    if (ret == false) {
        //弹出一个提示窗口，然后返回(安装失败，请重试)
        CustomMessageBox Msg(CustomMessageBox::Critical,tr("Warning"),tr("Add printer failed，please retry after a while."),CustomMessageBox::NoButton);
        Msg.setParent(this);
        Msg.addButton(tr("Close"), CustomMessageBox::YesRole);
        Msg.exec();
        emit showPPDSelectDialog();
        return;
    }
    updateMainWindowByAdd(m_currentSelectedPrinter.name);
    emit getCurFontSize();
    return;
}
void MainWindow::updateCurrentSelectedPrinter(const UkuiUsbPrinter&printer)
{
    m_currentSelectedPrinter = printer;
}
void MainWindow::propertyDialogShow(const UkuiUsbPrinter& currentPrinter)
{
    m_allPrintersVector.clear();
    g_printerManger.enumPrinters(m_allPrintersVector);

    for(auto printer : m_allPrintersVector)
    {
        if(printer.name == currentPrinter.name)
        {
            m_currentSelectedPrinter = printer;
        }
    }

    m_propertyDialog = new PropertyWindow(m_currentSelectedPrinter,this);
    connect(m_propertyDialog, &PropertyWindow::destroyed, this, [=](){
        m_propertyDialog = nullptr;
    });
    m_propertyDialog->setQSSFontSize(m_curFont);
    m_propertyDialog->onShow();
}
void MainWindow::jobListDialogShow(const QString& currentPrinterName)
{
    m_allPrintersVector.clear();
    g_printerManger.enumPrinters(m_allPrintersVector);

    for(auto printer : m_allPrintersVector)
    {
        if(printer.name == currentPrinterName)
        {
            m_currentSelectedPrinter = printer;
        }
    }

    m_jobListDialog = JobManagerWindow::getInstance(m_currentSelectedPrinter.name,UkuiQueueStatus::UKUI_PRINTER_QUEUE_ALL,this);
    m_jobListDialog->showThis();
}
void MainWindow::printTestPage(const UkuiUsbPrinter& printer)
{
    //TODO:打印测试页要传出的参数，调用哪个接口
    qDebug() <<"打印机" << printer.name << "打印测试页！";

    bool res = false;
    res = g_printerManger.printTestPage(printer.name);
    if(res)
    {
        SelfDestroyMessageBox MsgBox(tr("Try to connect the Printer..."), 5000, this);
        MsgBox.onShow();
    }
    else
    {
        CustomMessageBox Msg(CustomMessageBox::Critical,tr("Error"),tr("Open Printer Failed,Please Del And Add Printer, Then Try Again!"),CustomMessageBox::NoButton);
        Msg.setParent(this);
        Msg.addButton(tr("Sure"), CustomMessageBox::YesRole);
        Msg.exec();
    }
    emit updateRightWidget(printer);
}

void MainWindow::updateImmediately()
{
    m_allPrintersVector.clear();
    g_printerManger.enumPrinters(m_allPrintersVector);
    emit updateListSector(m_allPrintersVector,m_currentSelectedPrinter);
}

void MainWindow::updateByRename(QString printerName)
{
    m_allPrintersVector.clear();
    g_printerManger.enumPrinters(m_allPrintersVector);
    for (auto &cur : m_allPrintersVector)
    {
        if(cur.name == printerName)
        {
            m_currentSelectedPrinter = cur;
        }
    }
    emit addPrinterToListSector(m_currentSelectedPrinter);
    updateImmediately();
    emit getCurFontSize();
}

MainWindow *MainWindow::getInstance()
{
    static MainWindow *mainWinInstance = nullptr;
    if (nullptr == mainWinInstance){
        mainWinInstance = new MainWindow();
    }

    return mainWinInstance;
}

void MainWindow::setQSSFontSize(QFont currentFont)
{
    m_curFont = currentFont;
    m_curFontPointSize = currentFont.pointSizeF();
    m_leftWidget->setQSSFontSize(currentFont);
    m_rightWidget->setQSSFontSize(currentFont);
    if (m_propertyDialog != nullptr)
    {
        m_propertyDialog->setQSSFontSize(currentFont);
    }
    if (m_AddWindow != nullptr)
    {
        m_AddWindow->setQSSFontSize(currentFont);
    }
}

void MainWindow::recvDeviceIn(DeviceInformation& info)
{
    QPoint temp = QPoint(this->mapToGlobal(QPoint(0, 0)).x() + this->width() / 2, this->mapToGlobal(QPoint(0, 0)).y() + this->height() / 2);
    if(isHidden()== true){
        show();
    }
    qDebug() << "add Device!";
    if (m_AddWindow == nullptr) {
        qDebug() << "New Add Window";
        m_AddWindow = new AddPrinterWindow(temp);
        connect(m_AddWindow, SIGNAL(needUpdateDests(QString)), this, SLOT(updateMainWindowByAdd(QString)));
    }
    m_AddWindow->manualInstall(info);
    emit m_AddWindow->showThis(temp);
}
/************************************************
* 函数名称：keyPressEvent
* 功能描述：F1键打开用户手册对应页
* 输入参数：QKeyEvent *event键盘事件
* 输出参数：
* 修改日期：2021.07.03
* 修改内容：
*   创建  HZH
*
*************************************************/
void MainWindow::keyPressEvent(QKeyEvent *event)
{
    if(event->key() == Qt::Key_F1)
    {
        DaemonIpcDbus *ipcDbus = DaemonIpcDbus::getInstance();
        if(!ipcDbus->daemonIsNotRunning()){
            ipcDbus->showGuide("kylin-printer");
        }
    }
}

bool MainWindow::eventFilter(QObject* watched, QEvent* event)
{
    if (watched == this) {
        if (event->type() == QEvent::MouseButtonPress) {
            if (m_rightWidget->m_deviceExhbitionMyWidget->m_printerShowNameEdit->hasFocus())
            {
                    m_rightWidget->m_deviceExhbitionMyWidget->m_printerShowNameEdit->clearFocus();
            }
        }
    }
    return QWidget::eventFilter(watched, event);
}

quint32 MainWindow::getWindowId(void)
{
    return m_windowId;
}
