#include "ctrlvolumepanel.h"
#include "globaldefine.h"
#include "base/waitingdlg.h"
#include "gutil/qnetwork.h"
#include "tools.h"
#include <QMessageBox>
#include <QJsonArray>
#include <QTimeEdit>
#include <QSettings>
#include "devicepanel.h"

CtrlVolumePanel::CtrlVolumePanel() {
    auto vBox = new VBox(this);

    lbVolumeControl = new QLabel;
    lbVolumeControl->setAlignment(Qt::AlignCenter);
    vBox->addWidget(lbVolumeControl);

    auto hBox = new HBox(vBox);
    hBox->addStretch();

    fdManual = new QRadioButton;
    hBox->addWidget(fdManual);
    hBox->addSpacing(40);

    fdSchedule = new QRadioButton;
    hBox->addWidget(fdSchedule);
    hBox->addStretch();

    auto stack = new QStackedLayout(vBox);
    {
        auto vBox = new VBox(stack);
        vBox->addSpacing(20);

        auto hBox = new HBox(vBox);
        hBox->addStretch();

        lbVolume = new QLabel;
        hBox->addWidget(lbVolume);

        fdVolume = new QSlider(Qt::Horizontal);
        fdVolume->setTickPosition(QSlider::TicksAbove);
        fdVolume->setRange(0, 15);
        connect(fdVolume, &QSlider::sliderReleased, this, [=] {
            if(gSelCards.isEmpty()) {
                QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
                return;
            }
            QJsonObject json;
            json.insert("_id", "SetVolume");
            json.insert("_type", "SetVolume");
            json.insert("volume", fdVolume->value());
            if(gSelCards.count() == 1) {
                auto waitingDlg = new WaitingDlg(this, tr("SetVolume")+" ...");
                Def_CtrlReqPre
                connect(reply, &QNetworkReply::finished, this, [=] {
                    Def_CtrlSetReqAfter
                });
            } else {
                foreach(auto card, gSelCards) {
                    Def_CtrlSetMulti(tr("SetVolume"))
                }
            }
        });
        hBox->addWidget(fdVolume);

        auto lbCurVol = new QLabel;
        lbCurVol->setMinimumWidth(30);
        connect(fdVolume, &QSlider::valueChanged, lbCurVol, (void(QLabel::*)(int))&QLabel::setNum);
        hBox->addWidget(lbCurVol);
        hBox->addStretch();

        fdVolumeGet = new QPushButton;
        fdVolumeGet->setMinimumSize(QSize(60, 30));
        fdVolumeGet->setProperty("ssType", "progManageTool");
        connect(fdVolumeGet, &QPushButton::clicked, this, [=] {
            if(gSelCards.isEmpty()) {
                QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
                return;
            }
            QJsonObject json;
            json.insert("_id", "GetVolume");
            json.insert("_type", "GetVolume");
            if(gSelCards.count() == 1) {
                auto waitingDlg = new WaitingDlg(this, tr("GetVolume")+" ...");
                Def_CtrlReqPre
                connect(reply, &QNetworkReply::finished, this, [this, reply, waitingDlg] {
                    Def_CtrlSingleGetReply
                    waitingDlg->success();
                    fdVolume->setValue(json["volume"].toInt());
                });
            } else {
                foreach(auto card, gSelCards) {
                    auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json);
                    auto cardId = card.id;
                    connect(reply, &QNetworkReply::finished, this, [reply, cardId] {
                        QJsonDocument json;
                        QString err = checkReplyForJson(reply, &json);
                        if(err.isEmpty()) err = QString::number(json["volume"].toInt());
                        gFdResInfo->append(cardId+" "+tr("GetVolume")+" "+err);
                    });
                }
            }
        });
        vBox->addWidget(fdVolumeGet, 0, Qt::AlignCenter);
        vBox->addStretch();
    }
    {
        auto vBox = new VBox(stack);
        hBox = new HBox(vBox);

        fdScheTip = new QLabel;
        fdScheTip->setWordWrap(true);
        hBox->addWidget(fdScheTip);


        hBox = new HBox(vBox);

        btnScheAdd = new QPushButton;
        btnScheAdd->setMinimumSize(60, 30);
        btnScheAdd->setProperty("ssType", "progManageTool");
        connect(btnScheAdd, &QPushButton::clicked, this, [this] {
            int row = tableSche->appendRow();

            auto cellWgt = new QWidget;
            auto hBox = new QHBoxLayout(cellWgt);

            auto slider = new QSlider(Qt::Horizontal);
            slider->setRange(0, 15);
            slider->setValue(10);
            hBox->addWidget(slider);

            auto lb = new QLabel(QString::number(slider->value()));
            connect(slider, &QSlider::valueChanged, lb, (void(QLabel::*)(int))&QLabel::setNum);
            hBox->addWidget(lb);

            tableSche->setCellWidget(row, "vol", cellWgt);

            auto timeEdit = new QTimeEdit(QTime(0, 0));
            timeEdit->setDisplayFormat("HH:mm");
            timeEdit->setAlignment(Qt::AlignCenter);
            tableSche->setCellWidget(row, "start", timeEdit);

            timeEdit = new QTimeEdit(QTime(1, 0));
            timeEdit->setDisplayFormat("HH:mm");
            timeEdit->setAlignment(Qt::AlignCenter);
            tableSche->setCellWidget(row, "end", timeEdit);

            for(int i=0; i<7; i++) {
                auto fd = new QCheckBox;
                fd->setChecked(true);
                tableSche->setCellWidget(row, QString::number(i), fd);
            }
        });
        hBox->addWidget(btnScheAdd);

        btnScheDel = new QPushButton;
        btnScheDel->setMinimumSize(60, 30);
        btnScheDel->setProperty("ssType", "progManageTool");
        connect(btnScheDel, &QPushButton::clicked, this, [this] {
            auto selected = tableSche->selectedRanges();
            if(! selected.isEmpty()) tableSche->model()->removeRows(selected[0].topRow(), selected[0].rowCount());
        });
        hBox->addWidget(btnScheDel);

        btnScheClear = new QPushButton;
        btnScheClear->setMinimumSize(60, 30);
        btnScheClear->setProperty("ssType", "progManageTool");
        connect(btnScheClear, &QPushButton::clicked, this, [this] {tableSche->setRowCount(0);});
        hBox->addWidget(btnScheClear);

        lbDefBright = new QLabel;
        hBox->addWidget(lbDefBright);

        fdDefBright = new QSlider(Qt::Horizontal);
        fdDefBright->setFixedWidth(120);
        fdDefBright->setRange(0, 15);
        fdDefBright->setValue(10);
        hBox->addWidget(fdDefBright);

        auto lbDefBrightValue = new QLabel;
        lbDefBrightValue->setNum(fdDefBright->value());
        lbDefBrightValue->setMinimumWidth(30);
        lbDefBrightValue->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
        connect(fdDefBright, &QSlider::valueChanged, lbDefBrightValue, (void(QLabel::*)(int))&QLabel::setNum);
        hBox->addWidget(lbDefBrightValue);

        hBox->addStretch();

        btnScheImport = new QPushButton;
        btnScheImport->setMinimumSize(QSize(60, 30));
        btnScheImport->setProperty("ssType", "progManageTool");
        connect(btnScheImport, &QPushButton::clicked, this, [this] {
            auto dir = QSettings().value("CtrlScheduleDir").toString();
            if(dir.isEmpty()) dir = "/";
            QString scheFile = QFileDialog::getOpenFileName(this, tr("Import File"), dir, tr("Volume Schedule (*.vols)"));
            if(scheFile.isEmpty()) return;
            QFile scheQFile(scheFile);
            if(! scheQFile.open(QIODevice::ReadOnly)) return;
            auto data = scheQFile.readAll();
            scheQFile.close();
            restoreScheduleJson(QJsonDocument::fromJson(data).object());
        });
        hBox->addWidget(btnScheImport);

        btnScheExport = new QPushButton;
        btnScheExport->setMinimumSize(QSize(60, 30));
        btnScheExport->setProperty("ssType", "progManageTool");
        connect(btnScheExport, &QPushButton::clicked, this, [this] {
            QSettings settings;
            auto dir = settings.value("CtrlScheduleDir").toString();
            if(dir.isEmpty()) dir = "/";
            QString scheFile = QFileDialog::getSaveFileName(this, tr("Save File"), dir, tr("Volume Schedule (*.vols)"));
            if(scheFile.isEmpty()) return;
            settings.setValue("CtrlScheduleDir", QFileInfo(scheFile).absolutePath());
            QFile scheQFile(scheFile);
            if(! scheQFile.open(QIODevice::WriteOnly)) return;
            scheQFile.write(QJsonDocument(getScheduleJson()).toJson());
            scheQFile.close();
        });
        hBox->addWidget(btnScheExport);

        tableSche = new Table({
            {"vol", "", 300},
            {"start", "", 100},
            {"end", "", 100},
            {"0", "", 60},
            {"1", "", 60},
            {"2", "", 60},
            {"3", "", 60},
            {"4", "", 60},
            {"5", "", 60},
            {"6", "", 60}
        });
        tableSche->setDefs();
        vBox->addWidget(tableSche);

        hBox = new HBox(vBox);
        hBox->addStretch();

        btnScheSet = new QPushButton;
        btnScheSet->setMinimumSize(QSize(60, 30));
        btnScheSet->setProperty("ssType", "progManageTool");
        connect(btnScheSet, &QPushButton::clicked, this, [this] {
            if(gSelCards.isEmpty()) {
                QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
                return;
            }
            QJsonObject json;
            json.insert("_id", "SetAutoVolumeTask");
            json.insert("_type", "SetAutoVolumeTask");
            json.insert("taskVolume", getScheduleJson());
            if(gSelCards.count() == 1) {
                auto waitingDlg = new WaitingDlg(this, tr("SetAutoVolumeTask"));
                Def_CtrlReqPre;
                connect(reply, &QNetworkReply::finished, this, [=] {
                    Def_CtrlSetReqAfter
                });
            } else {
                foreach(auto card, gSelCards) {
                    Def_CtrlSetMulti(tr("SetAutoVolumeTask"))
                }
            }
        });
        hBox->addWidget(btnScheSet);

        hBox->addStretch();

        btnScheGet = new QPushButton;
        btnScheGet->setMinimumSize(QSize(60, 30));
        btnScheGet->setProperty("ssType", "progManageTool");
        connect(btnScheGet, &QPushButton::clicked, this, [this] {
            if(gSelCards.isEmpty()) {
                QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
                return;
            }
            QJsonObject json;
            json.insert("_id", "GetAutoVolumeTask");
            json.insert("_type", "GetAutoVolumeTask");
            if(gSelCards.count() == 1) {
                auto waitingDlg = new WaitingDlg(this, tr("GetAutoVolumeTask"));
                Def_CtrlReqPre
                connect(reply, &QNetworkReply::finished, this, [this, reply, waitingDlg, card] {
                    Def_CtrlSingleGetReply
                    waitingDlg->success();
                    restoreScheduleJson(json["taskVolume"].toObject());
                });
            }
        });
        hBox->addWidget(btnScheGet);

        hBox->addStretch();
    }

    connect(fdSchedule, &QRadioButton::toggled, stack, &QStackedLayout::setCurrentIndex);
    fdManual->setChecked(true);

    connect(gDevicePanel, &DevicePanel::sigSelectedDeviceList, this, [this] {
        if(isVisible()) init();
    });
    transUi();
}

void CtrlVolumePanel::showEvent(QShowEvent *event) {
    QWidget::showEvent(event);
    init();
}
void CtrlVolumePanel::init() {
    bool isSingle = gSelCards.count()==1;
    btnScheGet->setEnabled(isSingle);
    if(! isSingle) return;
    auto card = gSelCards[0];

    QJsonObject json;
    json.insert("_id", "GetVolume");
    json.insert("_type", "GetVolume");
    auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json);
    connect(reply, &QNetworkReply::finished, this, [this, reply] {
        QJsonDocument json;
        QString err = checkReplyForJson(reply, &json);
        if(! err.isEmpty()) return;
        fdVolume->setValue(json["volume"].toInt());
    });

    json = QJsonObject();
    json.insert("_id", "GetAutoVolumeTask");
    json.insert("_type", "GetAutoVolumeTask");
    reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json);
    connect(reply, &QNetworkReply::finished, this, [this, reply, card] {
        QJsonDocument json;
        QString err = checkReplyForJson(reply, &json);
        if(! err.isEmpty()) return;
        if(restoreScheduleJson(json["taskVolume"].toObject())) fdSchedule->setChecked(true);
        else fdManual->setChecked(true);
    });
}

void CtrlVolumePanel::changeEvent(QEvent *event) {
    QWidget::changeEvent(event);
    if(event->type() == QEvent::LanguageChange) transUi();
}
void CtrlVolumePanel::transUi() {
    lbVolumeControl->setText(tr("Volume Control"));
    fdManual->setText(tr("Manual"));
    fdSchedule->setText(tr("Schedule"));

    lbVolume->setText(tr("Volume"));
    fdVolumeGet->setText(tr("Readback"));

    lbDefBright->setText(tr("Default volume"));
    btnScheAdd->setText(tr("Add"));
    btnScheClear->setText(tr("Clear"));
    btnScheDel->setText(tr("Delete"));
    btnScheImport->setText(tr("Import"));
    btnScheExport->setText(tr("Export"));

    tableSche->setHeaderText("vol", tr("Volume value"));
    tableSche->setHeaderText("start", tr("Start Time"));
    tableSche->setHeaderText("end", tr("End Time"));
    tableSche->setHeaderText("0", tr("SUN"));
    tableSche->setHeaderText("1", tr("MON"));
    tableSche->setHeaderText("2", tr("TUE"));
    tableSche->setHeaderText("3", tr("WED"));
    tableSche->setHeaderText("4", tr("THU"));
    tableSche->setHeaderText("5", tr("FRI"));
    tableSche->setHeaderText("6", tr("SAT"));

    btnScheSet->setText(tr("Apply"));
    btnScheGet->setText(tr("Readback"));
    fdScheTip->setText(tr("Default volume tip"));
}

bool CtrlVolumePanel::restoreScheduleJson(QJsonObject json) {
    tableSche->setRowCount(0);
    fdDefBright->setValue(json["defaultVolume"].toInt());
    auto items = json["items"].toArray();
    for(int i=0; i<items.size(); i++) {
        auto schedule = items.at(i)["schedules"][0];
        int row = tableSche->rowCount();
        tableSche->insertRow(row);

        auto cellWgt = new QWidget;
        auto hBox = new QHBoxLayout(cellWgt);

        auto slider = new QSlider(Qt::Horizontal);
        slider->setRange(0, 15);
        slider->setValue(items.at(i)["volume"].toInt());
        hBox->addWidget(slider);

        auto lb = new QLabel;
        lb->setNum(slider->value());
        connect(slider, &QSlider::valueChanged, lb, (void(QLabel::*)(int))&QLabel::setNum);
        hBox->addWidget(lb);
        tableSche->setCellWidget(row, "vol", cellWgt);

        auto timeEdit = new QTimeEdit(QTime::fromString(schedule["startTime"].toString(), "HH:mm"));
        timeEdit->setDisplayFormat("HH:mm");
        timeEdit->setAlignment(Qt::AlignCenter);
        tableSche->setCellWidget(row, "start", timeEdit);

        timeEdit = new QTimeEdit(QTime::fromString(schedule["endTime"].toString(), "HH:mm"));
        timeEdit->setDisplayFormat("HH:mm");
        timeEdit->setAlignment(Qt::AlignCenter);
        tableSche->setCellWidget(row, "end", timeEdit);

        if(schedule["filterType"].toString()=="None") for(int i=0; i<7; i++) {
            auto fd = new QCheckBox;
            fd->setChecked(true);
            tableSche->setCellWidget(row, QString::number(i), fd);
        } else if(schedule["filterType"].toString()=="Week") {
            auto weekFilter = schedule["weekFilter"].toArray();
            for(int i=0; i<7; i++) {
                auto fd = new QCheckBox;
                if(weekFilter.contains(i)) fd->setChecked(true);
                tableSche->setCellWidget(row, QString::number(i), fd);
            }
        }
    }
    return items.count() > 0;
}
QJsonObject CtrlVolumePanel::getScheduleJson() {
    QJsonArray items;
    for(int i=0; i<tableSche->rowCount(); i++) {
        QJsonObject item;
        item.insert("volume", static_cast<QSlider*>(tableSche->cellWidget(i, "vol")->layout()->itemAt(0)->widget())->value());
        QJsonObject schedule;
        schedule["timeType"] = "Range";
        schedule["startTime"] = static_cast<QTimeEdit*>(tableSche->cellWidget(i, "start"))->text();
        schedule["endTime"] = static_cast<QTimeEdit*>(tableSche->cellWidget(i, "end"))->text();
        schedule["dateType"] = "All";
        schedule["monthFilter"] = QJsonArray();
        QJsonArray weekFilter;
        for(int d=0; d<7; d++) if(static_cast<QCheckBox*>(tableSche->cellWidget(i, QString::number(d)))->isChecked()) weekFilter.append(d);
        if(weekFilter.size()>=7) {
            schedule["filterType"] = "None";
            weekFilter = QJsonArray();
        } else schedule["filterType"] = "Week";
        schedule["weekFilter"] = weekFilter;
        item.insert("schedules", QJsonArray{schedule});
        items.append(item);
    }
    auto def = fdDefBright->value();
    return QJsonObject{
        {"createBy", "alahover"},
        {"name", "TimingVolume"},
        {"defaultVolume", def},
        {"volume", def},
        {"items", items}
    };
}
