//
// Created by uos on 2022/3/16.
//

#include "BackupWidget.h"
#include "common/ItemFrame.h"
#include "utils/Utils.h"
#include <QVBoxLayout>
#include <DListView>
#include <QScrollBar>
#include <QDebug>

enum OptType {
    SystemBackup = 0, //系统备份
    UserDataBackup    //数据备份
};

const int ITEM_FRAME_HEIGHT = 180;
const int ITEM_FRAME_WIDTH = 180;
const int ITEM_FRAME_HEIGHT_VERTICAL_LAYOUT = 85;
const int ITEM_FRAME_WIDTH_VERTICAL_LAYOUT = 600;

BackupWidget::BackupWidget(DWidget *parent) : DWidget(parent)
{
    this->setAccessibleName("backupWidget");
    m_bDirectionRTL = Utils::isDirectionRTL();

    // 主题变换
    m_guiHelper = Dtk::Gui::DGuiApplicationHelper::instance();
    connect(m_guiHelper, &Dtk::Gui::DGuiApplicationHelper::themeTypeChanged, this, &BackupWidget::onThemeChange);
    // 初始化UI
    initUI();
}

void BackupWidget::initUI()
{
    int uiLayout = this->getBackupUiLayoutType();
    QVBoxLayout *verticalLayout = new QVBoxLayout(this);
    if (UI::UI_LAYOUT_BACKUP_HORIZONTAL == uiLayout) {
        verticalLayout->setContentsMargins(0, 20, 0, 10);
    } else if (UI::UI_LAYOUT_BACKUP_VERTICAL == uiLayout) {
        verticalLayout->setContentsMargins(0, 50, 0, 5);
    }

    m_title = new DLabel(this);
    m_title->setText(tr("Choose a backup way"));
    m_title->setAccessibleName("uosBackup_ChooseBackupWay");
    m_title->setAlignment(Qt::AlignCenter);
    m_title->setFixedHeight(35);
    DFontSizeManager::instance()->bind(m_title, DFontSizeManager::T6);
    QFont font = m_title->font();
    font.setWeight(QFont::Medium);
    m_title->setFont(font);
    QPalette titlePalette;
    titlePalette.setColor(QPalette::BrightText, QColor(qRgba(0,0,0,0.7)));
    m_title->setPalette(titlePalette);
    verticalLayout->addWidget(m_title, 0, Qt::AlignHCenter);

    m_backupView = new DListView(this);
    m_model = new QStandardItemModel(m_backupView);
    m_backupView->setModel(m_model);
    m_backupView->setAccessibleName("uosBackup_BackupListView");

    if (UI::UI_LAYOUT_BACKUP_HORIZONTAL == uiLayout) {
        verticalLayout->addSpacing(50);
        if (m_bDirectionRTL) {
            m_backupView->setFixedSize(500, 500);
            verticalLayout->addWidget(m_backupView, 0, Qt::AlignHCenter);
        } else {
            verticalLayout->addWidget(m_backupView);
        }
    } else if (UI::UI_LAYOUT_BACKUP_VERTICAL == uiLayout) {
        verticalLayout->addSpacing(8);
        if (m_bDirectionRTL) {
            m_backupView->setFixedSize(600, 500);
            verticalLayout->addWidget(m_backupView, 0, Qt::AlignHCenter);
        } else {
            verticalLayout->addWidget(m_backupView, Qt::AlignHCenter);
        }
    }

    m_backupView->setFrameShape(QFrame::Shape::NoFrame);
    // 不能编辑触发
    m_backupView->setEditTriggers(QListView::NoEditTriggers);
    // 不可以拖拽
    m_backupView->setDragEnabled(false);
    m_backupView->clearSelection();
    m_backupView->clearFocus();
    m_backupView->clearMask();
    m_backupView->setSelectionMode(QAbstractItemView::NoSelection);

    verticalLayout->addStretch();
    m_nextBtn = new DPushButton;
    m_nextBtn->setText(tr("Next"));
    m_nextBtn->setAccessibleName("uosBackup_Next");
    m_nextBtn->setFixedSize(200, 36);
    m_nextBtn->setEnabled(false);

    QHBoxLayout *hBoxLayout = new QHBoxLayout;
    if (UI::UI_LAYOUT_BACKUP_HORIZONTAL == uiLayout) {
        this->uiHorizontalLayout();
        this->initHelpLayout();

        QLabel *leftLabel = new QLabel;
        leftLabel->setFixedSize(20, 20);
        leftLabel->setAccessibleName("uosBackup_LeftLabel");

        hBoxLayout->setContentsMargins(13, 0, 13, 0);
        hBoxLayout->addWidget(leftLabel, 0, Qt::AlignLeft);
        hBoxLayout->addWidget(m_nextBtn, Qt::AlignHCenter);
        hBoxLayout->addWidget(m_helpLabel, 0, Qt::AlignRight);

        connect(this, &BackupWidget::enter, this, [=] {
            QPoint point = m_helpLabel->mapToGlobal(QPoint());
            QPoint nextBtnPoint = m_nextBtn->mapToGlobal(QPoint());
            int x = point.x();
            int w = m_helpDialog->width();
            if (x > nextBtnPoint.x()) {
                x -= w;
            }
            m_helpDialog->move(x, point.y() - m_helpDialog->height() -10);
            m_helpDialog->raise();
            m_helpDialog->activateWindow();
            m_helpDialog->show();
        });

        connect(this, &BackupWidget::leave, this, [=] {
            m_helpDialog->hide();
            if (!this->isActiveWindow()) {
                this->raise();
                this->activateWindow();
            }
        });
    } else if (UI::UI_LAYOUT_BACKUP_VERTICAL == uiLayout) {
        this->uiVerticalLayout();
        hBoxLayout->addWidget(m_nextBtn, Qt::AlignHCenter);
    }

    verticalLayout->addLayout(hBoxLayout);

    // 按钮  中间标题
    QStringList titles = {
            tr("System Backup"),
            tr("Data Backup")
    };
    m_iconList << ":/resources/icons/system_backup.svg" << ":/resources/icons/data_backup.svg";
    Q_ASSERT(titles.size() == m_iconList.size());

    QStringList description = {
            tr("Back up the partitions and directories that store system files, to resist system breakdown."),
            tr("Specify files and directories to back up, so as to avoid data loss or damage.")
    };

    for (int i = 0; i < titles.size(); i++) {
        auto *item = new QStandardItem;
        if (titles.at(i) == tr("System Backup")) {
            item->setAccessibleText("uos_SystemBackup");
        } else if (titles.at(i) == tr("Data Backup")) {
            item->setAccessibleText("uos_DataBackup");
        }
        m_model->appendRow(item);
        ItemFrame *itemFrame = new ItemFrame(titles.at(i), description.at(i), m_iconList.at(i), m_backupView);
        itemFrame->setLayoutStype(uiLayout);
        if (UI::UI_LAYOUT_BACKUP_HORIZONTAL == uiLayout) {
            itemFrame->setFixedSize(ITEM_FRAME_WIDTH, ITEM_FRAME_HEIGHT);
            itemFrame->setIconPixmap(m_iconList.at(i), QSize(96, 96));
        } else if (UI::UI_LAYOUT_BACKUP_VERTICAL == uiLayout) {
            itemFrame->setFixedSize(ITEM_FRAME_WIDTH_VERTICAL_LAYOUT, ITEM_FRAME_HEIGHT_VERTICAL_LAYOUT);
            itemFrame->setIconPixmap(m_iconList.at(i), QSize(56, 56));
        }
        itemFrame->initLayout();
        m_backupView->setIndexWidget(m_model->index(i, 0), itemFrame);
        connect(itemFrame, &ItemFrame::clicked, this, &BackupWidget::onItemChanged);
    }

    connect(m_nextBtn, &QPushButton::clicked, [=] {
        auto index = m_backupView->currentIndex();
        if (!index.isValid()) {
            return;
        }
        switch (static_cast<OptType>(index.row())) {
            case SystemBackup:
                Q_EMIT notifySystemBackup();
                break;
            case UserDataBackup:
                Q_EMIT notifyDataBackup();
                break;
            default:
                break;
        }
    });
}

int BackupWidget::getBackupUiLayoutType()
{
    int defaultLayout = Utils::getUILayoutType(UI::UI_BACKUP_MODULE);
    if (-1 == defaultLayout) {
        qCritical()<<"getBackupUiLayoutType failed";
    }
    return defaultLayout;
}

void BackupWidget::initHelpLayout()
{
    m_helpLabel = new QLabel;
    m_helpLabel->installEventFilter(this);
    Dtk::Gui::DGuiApplicationHelper::ColorType themeType =  Dtk::Gui::DGuiApplicationHelper::instance()->themeType();
    m_helpLabel->setPixmap(HelpDialog::getPixMapByThemeType(themeType));
    m_helpLabel->setFixedSize(20, 20);
    m_helpLabel->setAccessibleName("uosBackup_HelpTips");

    m_helpDialog = new HelpDialog();
    m_helpDialog->setFixedSize(QSize(320,200));
    QList<QPair<QString, QString>> tipsList = {
            {tr("System Backup"),
                    tr("Back up the partitions and directories that store system files, to resist system breakdown.")
            },

            {tr("Data Backup"),
                    tr("Specify files and directories to back up, so as to avoid data loss or damage.")
            }
    };

    QList<HelpInfoItem> helpInfos;
    m_helpDialog->tipsPairList2HelpInfoItemList(tipsList, helpInfos);
    m_helpDialog->setContentText(helpInfos);
}

void BackupWidget::uiHorizontalLayout()
{
    m_backupView->setResizeMode(QListView::Adjust);
    m_backupView->setViewMode(QListView::IconMode);
    m_backupView->setViewportMargins(QMargins(0, 0, 0, 0));

    m_backupView->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
    m_backupView->setSpacing(46);

    // 每个对象大小
    m_backupView->setItemSize(QSize(ITEM_FRAME_WIDTH, ITEM_FRAME_HEIGHT));

    // 设置其他属性
    m_backupView->setTextElideMode(Qt::ElideRight);
    m_backupView->setBackgroundType(DStyledItemDelegate::RoundedBackground);
}

void BackupWidget::uiVerticalLayout()
{
    m_backupView->setResizeMode(QListView::Adjust);
    m_backupView->setViewMode(QListView::IconMode);
    m_backupView->setViewportMargins(QMargins(0, 0, 0, 0));

    m_backupView->verticalScrollBar()->setEnabled(false);
    m_backupView->horizontalScrollBar()->setEnabled(false);
    m_backupView->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
    m_backupView->setSpacing(16);

    // 每个对象大小
    m_backupView->setItemSize(QSize(ITEM_FRAME_WIDTH_VERTICAL_LAYOUT, ITEM_FRAME_HEIGHT_VERTICAL_LAYOUT));

    // 设置其他属性
    m_backupView->setTextElideMode(Qt::ElideRight);
    m_backupView->setBackgroundType(DStyledItemDelegate::RoundedBackground);
}

void BackupWidget::onThemeChange(Dtk::Gui::DGuiApplicationHelper::ColorType themeType)
{
    if (nullptr != m_helpLabel) {
        m_helpLabel->setPixmap(HelpDialog::getPixMapByThemeType(themeType));
    }
}

void BackupWidget::onItemChanged(bool checked)
{
    if (checked) {
        auto *itemFrame = dynamic_cast<ItemFrame *>(sender());
        int rowCount = m_model->rowCount();
        for (int i = 0; i < rowCount; ++i) {
            auto item = dynamic_cast<ItemFrame *>(m_backupView->indexWidget(m_model->index(i, 0)));
            item->setCheckState(itemFrame == item);
        }
        m_nextBtn->setEnabled(checked);
    }
}

bool BackupWidget::eventFilter(QObject* watched, QEvent* event)
{
    if (watched == m_helpLabel) {
        switch (event->type()) {
            case QEvent::Enter: {
                Q_EMIT enter();
                break;
            }
            case QEvent::Leave: {
                Q_EMIT leave();
                break;
            }
            default:
                break;
        }
    }

    return QWidget::eventFilter(watched, event);
}
