#include "progitem.h"
#include "QtWidgets/qdialogbuttonbox.h"
#include "QtWidgets/qlineedit.h"
#include "gutil/qcore.h"
#include "gutil/qgui.h"
#include "base/waitingdlg.h"
#include "progeditorwin.h"
#include "base/waitingdlg.h"
#include "gentmpthread.h"
#include <globaldefine.h>
#include "sendprogramdialog.h"
#include <QJsonArray>
#include <QMessageBox>
#include <QStorageInfo>

ProgItem::ProgItem(const QString &progsDir, const QString &name, int w, int h, const QString &remarks, QList<int> &splitWidths, int maxWidth, LoQTreeWidget *tree) : QTreeWidgetItem(UserType),
    mName(name), mWidth(w), mHeight(h), mRemark(remarks), mSplitWidths(splitWidths), mMaxWidth(maxWidth), mProgsDir(progsDir), mTree(tree) {
    m_last = QDateTime::currentDateTime();
    mProgDir = progsDir + "/" + mName;
    m_orgName = mName;
    init();
}

ProgItem::ProgItem(const QString &progsDir, const QJsonObject &json, LoQTreeWidget *tree) : QTreeWidgetItem(UserType), mProgsDir(progsDir), mTree(tree) {
    mName = json["name"].toString();
    mWidth = json["resolution"]["w"].toInt();
    mHeight = json["resolution"]["h"].toInt();
    mRemark = json["remarks"].toString();
    auto splitWidths = json["splitWidths"].toArray();
    foreach(auto splitWidth, splitWidths) {
        int width = splitWidth.toInt();
        if(mMaxWidth < width) mMaxWidth = width;
        mSplitWidths.append(width);
    }
    m_fsize = json["file_size"].toDouble();
    m_last = QDateTime::fromString(json["last_edit"].toString(), "yyyy-MM-dd hh:mm:ss");
    mProgDir = progsDir + "/" + mName;
    m_orgName = mName;
    init();
}

void ProgItem::init() {
    setForeground(ENUM_PROGRAMLISTHEADERITEM_NAME, Qt::transparent);
    setText(ENUM_PROGRAMLISTHEADERITEM_NAME, mName);
    setData(ENUM_PROGRAMLISTHEADERITEM_RESOLUTION, 0, QString("%1 x %2").arg(mWidth).arg(mHeight));
    if(m_fsize<=0) setData(ENUM_PROGRAMLISTHEADERITEM_SIZE, 0, byteSizeStr((qint64)100));
    else setData(ENUM_PROGRAMLISTHEADERITEM_SIZE, 0, byteSizeStr(m_fsize));
    setData(ENUM_PROGRAMLISTHEADERITEM_LASTTIME, 0, m_last.toString("yyyy-MM-dd hh:mm:ss"));
    setTextAlignment(ENUM_PROGRAMLISTHEADERITEM_NAME, Qt::AlignLeft | Qt::AlignVCenter);
    for(int i=1; i<ENUM_PROGRAMLISTHEADERITEM_END; i++) setTextAlignment(i, Qt::AlignCenter);
    setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
    setCheckState(0, Qt::Unchecked);
    mTree->insertTopLevelItem(0,this);

    m_bnName = new QPushButton(mName);
    m_bnName->setStyleSheet(R"delimiter(
QPushButton{border-radius: 4px;}
QPushButton:hover {
    background-color: #cccccc;
    text-decoration: underline;
}
)delimiter");

    m_bnName->setCursor(QCursor(Qt::PointingHandCursor));
    mTree->setItemWidget(this, ENUM_PROGRAMLISTHEADERITEM_NAME, m_bnName);
    QObject::connect(m_bnName, &QPushButton::clicked, mTree, [this] {
        auto editor = new ProgEditorWin(this, mTree->parentWidget());
        editor->show();
    });
    m_bnExport = new QPushButton();
    m_bnExport->setCursor(QCursor(Qt::PointingHandCursor));
    m_bnExport->setToolTip(QObject::tr("ExportButtonTip"));
    m_bnExport->setStyleSheet(R"rrr(
QPushButton {
    border-radius: 4px;
    image: url(:/res/program/bnExport_u.png);
}
QPushButton:pressed{image: url(:/res/program/bnExport_s.png);}
QPushButton:hover{background-color: #cccccc;}
)rrr");

    mTree->setItemWidget(this, ENUM_PROGRAMLISTHEADERITEM_USB_EXPORT, m_bnExport);
    QObject::connect(m_bnExport, &QPushButton::clicked, mTree, [this] {
        QDialog dlg(mTree);
        dlg.setWindowTitle(QObject::tr("Usb upgrade program"));
#ifdef Q_OS_WIN
        dlg.setWindowFlag(Qt::WindowContextHelpButtonHint, 0);
#endif
        dlg.resize(300, 260);

        auto vBox = new VBox(&dlg);
        auto hBox = new HBox(vBox);

        hBox->addWidget(new QLabel(QObject::tr("Password")));

        auto fdPassword = new QLineEdit;
        fdPassword->setEchoMode(QLineEdit::Password);
        fdPassword->setPlaceholderText(QObject::tr("Input password"));
        hBox->addWidget(fdPassword);

        auto fdDrives = new ListWgt;
        fdDrives->setSelectionRectVisible(true);
        vBox->addWidget(fdDrives);

        auto btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
        QObject::connect(btnBox, &QDialogButtonBox::rejected, &dlg, &QDialog::reject);
        QObject::connect(btnBox, &QDialogButtonBox::accepted, &dlg, [=, &dlg] {
            auto selects = fdDrives->selectedItems();
            if(selects.count() > 0) {
                foreach(auto select, selects) {
                    auto strPath = select->data(Qt::UserRole).toString();
                    auto waitingDlg = new WaitingDlg(&dlg, QObject::tr("Convertering")+" ...");
                    auto gen = new GenTmpThread(this, mName, strPath + (strPath.endsWith('/') ? "program.zip" : "/program.zip"), fdPassword->text());
                    QObject::connect(gen, &GenTmpThread::onErr, &dlg, [=, &dlg](QString err) {
                        QMessageBox::warning(&dlg, "GenTmpThread Error", err);
                    });
                    QObject::connect(gen, &QThread::finished, waitingDlg, &WaitingDlg::success);
                    QObject::connect(gen, &GenTmpThread::sProgress, waitingDlg->mIndicator, &CustomProgressIndicator::onProgress);
                    gen->start();
                    waitingDlg->exec();
                }
                dlg.accept();
                return;
            }
            if(fdDrives->count() <= 0) QMessageBox::warning(&dlg, QObject::tr("Tip"), QObject::tr("No checked USB device"));
            else QMessageBox::warning(&dlg, QObject::tr("Tip"), QObject::tr("please select usb device in list"));
        });
        vBox->addWidget(btnBox);

        fdDrives->clear();
        auto volumes = QStorageInfo::mountedVolumes();
        foreach(auto volume, volumes) fdDrives->addItem(volume.displayName(), volume.rootPath());

        dlg.exec();
    });

    m_bnSend = new QPushButton();
    m_bnSend->setCursor(QCursor(Qt::PointingHandCursor));
    m_bnSend->setToolTip(QObject::tr("SendButtonTip"));
    m_bnSend->setStyleSheet(R"rrr(
QPushButton{
    border-radius: 4px;
    image: url(:/res/program/bnSend_u.png);
}
QPushButton:pressed{image: url(:/res/program/bnSend_s.png);}
QPushButton:hover{background-color: #cccccc;}
)rrr");

    mTree->setItemWidget(this, ENUM_PROGRAMLISTHEADERITEM_SEND, m_bnSend);
    QObject::connect(m_bnSend, &QPushButton::clicked, mTree, [this] {
        auto waitingDlg = new WaitingDlg(mTree, QObject::tr("Convertering")+" ...");
        auto gen = new GenTmpThread(this, mName, "", "");
        QObject::connect(gen, &GenTmpThread::onErr, mTree, [=](QString err) {
            QMessageBox::warning(mTree, "GenTmpThread Error", err);
        });
        QObject::connect(gen, &QThread::finished, waitingDlg, &WaitingDlg::close);
        QObject::connect(gen, &GenTmpThread::sProgress, waitingDlg->mIndicator, &CustomProgressIndicator::onProgress);
        gen->start();
        waitingDlg->exec();
        SendProgramDialog dlg(mName, mTree);
        dlg.exec();
    });
}
void ProgItem::refreshLable() {
    m_bnExport->setToolTip(QObject::tr("ExportButtonTip"));
    m_bnSend->setToolTip(QObject::tr("SendButtonTip"));
}

void ProgItem::save() {
    QDir dRoot(mProgDir);
    QDir dParent(mProgsDir);
    if(!dRoot.exists()) {
        dParent.mkdir(mName);
    } else if(mName != m_orgName) {
        dParent.rename(m_orgName, mName);
        m_orgName = mName;
        mProgDir = mProgsDir + "/" + mName;
    }

    dRoot = QDir(mProgDir);
    if(dRoot.exists()) {
        QJsonObject obj;
        QJsonObject oSize;
        obj["name"]       = mName;
        obj["resolution"] = QJsonObject{{"w", mWidth}, {"h", mHeight}};
        obj["remarks"]    = mRemark;
        QJsonArray splitWidths;
        foreach(auto splitWidth, mSplitWidths) splitWidths.append(splitWidth);
        obj["splitWidths"] = splitWidths;
        obj["file_size"]  = m_fsize;
        obj["last_edit"]  = m_last.toString("yyyy-MM-dd hh:mm:ss");
        QJsonDocument json(obj);
        QFile f(mProgDir + "/pro.json");
        f.open(QIODevice::WriteOnly);
        f.write(json.toJson());
        f.close();
    }
}

void ProgItem::del() {
    QDir dRoot(mProgDir);
    if(dRoot.exists()) dRoot.removeRecursively();
}
//设置列表项的值
void ProgItem::onSetProgram() {
    m_bnName->setText(mName);
    setData(ENUM_PROGRAMLISTHEADERITEM_RESOLUTION, 0, QString("%1 x %2").arg(mWidth).arg(mHeight));
    setData(ENUM_PROGRAMLISTHEADERITEM_SIZE, 0, byteSizeStr(m_fsize<=0 ? 100 : m_fsize));
    setData(ENUM_PROGRAMLISTHEADERITEM_LASTTIME, 0, m_last.toString("yyyy-MM-dd hh:mm:ss"));
    save();
}
