#include "foldertreedelegateeditor.h" // 包含FolderTreeDelegateEditor类的声明
#include <QHBoxLayout> // 包含水平布局管理器
#include <QLabel> // 包含标签控件
#include <QPainter> // 包含绘图器
#include <QDebug> // 包含调试输出
#include <QTreeView> // 包含树视图控件
#include <QMouseEvent> // 包含鼠标事件
#include "pushbuttontype.h" // 包含自定义按钮类型
#include "nodetreemodel.h" // 包含节点树模型
#include "nodetreeview.h" // 包含节点树视图
#include "notelistview.h" // 包含笔记列表视图
#include "labeledittype.h" // 包含标签编辑类型
#include "fontloader.h" // 包含字体加载器

// FolderTreeDelegateEditor构造函数
FolderTreeDelegateEditor::FolderTreeDelegateEditor(QTreeView *view,
                                                   const QStyleOptionViewItem &option,
                                                   const QModelIndex &index, QListView *listView,
                                                   QWidget *parent)
    : QWidget(parent), // 调用QWidget构造函数
      m_option(option), // 初始化选项
      m_index(index), // 初始化索引
#ifdef __APPLE__ // 如果是苹果系统
      m_displayFont(QFont(QStringLiteral("SF Pro Text")).exactMatch()
                            ? QStringLiteral("SF Pro Text") // 使用系统字体
                            : QStringLiteral("Roboto")), // 否则使用Roboto字体
#elif _WIN32 // 如果是Windows系统
      m_displayFont(QFont(QStringLiteral("Segoe UI")).exactMatch() ? QStringLiteral("Segoe UI")
                                                                   : QStringLiteral("Roboto")),
#else // 其他系统
      m_displayFont(QStringLiteral("Roboto")),
#endif
#ifdef __APPLE__ // 如果是苹果系统
      m_titleFont(m_displayFont, 13, QFont::DemiBold), // 设置标题字体
#else
      m_titleFont(m_displayFont, 10, QFont::DemiBold), // 设置标题字体
#endif
      m_titleColor(26, 26, 26), // 设置标题颜色
      m_titleSelectedColor(255, 255, 255), // 设置选中标题颜色
      m_activeColor(68, 138, 201), // 设置活动颜色
      m_hoverColor(207, 207, 207), // 设置悬浮颜色
      m_folderIconColor(68, 138, 201), // 设置文件夹图标颜色
      m_view(view), // 初始化视图
      m_listView(listView), // 初始化列表视图
      m_theme(Theme::Light) // 初始化主题为浅色
{
    setContentsMargins(0, 0, 0, 0); // 设置内容边距
    auto layout = new QHBoxLayout(this); // 创建水平布局
    layout->setContentsMargins(10, 0, 0, 0); // 设置布局边距
    layout->setSpacing(0); // 设置布局间隔
    setLayout(layout); // 设置布局

    m_expandIcon = new QLabel(this); // 创建展开图标标签
    m_expandIcon->setMinimumSize({ 11, 11 }); // 设置最小尺寸
    m_expandIcon->setMaximumSize({ 11, 11 }); // 设置最大尺寸

    // 根据索引数据判断是否可展开，并相应地添加布局间隔
    if (m_index.data(NodeItem::Roles::IsExpandable).toBool()) {
        if (!m_view->isExpanded(m_index)) {
            layout->addSpacing(2);
        }
    }

#ifdef __APPLE__ // 如果是苹果系统
    int iconPointSizeOffset = 0; // 图标点大小偏移量
#else
    int iconPointSizeOffset = -4; // 图标点大小偏移量
#endif
    m_expandIcon->setFont(FontLoader::getInstance().loadFont("Font Awesome 6 Free Solid", "",
                                                             10 + iconPointSizeOffset)); // 加载字体

    m_expandIcon->setScaledContents(true); // 设置缩放内容
    layout->addWidget(m_expandIcon); // 将展开图标添加到布局

    // 如果索引不可展开或已展开，添加布局间隔
    if (!m_index.data(NodeItem::Roles::IsExpandable).toBool()
        || (m_index.data(NodeItem::Roles::IsExpandable).toBool() && m_view->isExpanded(m_index))) {
        layout->addSpacing(2);
    }

    m_folderIcon = new PushButtonType(parent); // 创建文件夹图标按钮
    m_folderIcon->setMaximumSize({ 19, 20 }); // 设置最大尺寸
    m_folderIcon->setMinimumSize({ 19, 20 }); // 设置最小尺寸
    m_folderIcon->setIconSize(QSize(19, 20)); // 设置图标尺寸
    QFont materialSymbols("Material Symbols Outlined", 16 + iconPointSizeOffset); // 加载字体
    m_folderIcon->setFont(materialSymbols); // 设置字体
    m_folderIcon->setText(u8"\ue2c7"); // 设置文本为文件夹图标
    layout->addWidget(m_folderIcon); // 将文件夹图标添加到布局
    layout->addSpacing(5); // 添加布局间隔

    m_label = new LabelEditType(this); // 创建标签编辑类型
    m_label->setFont(m_titleFont); // 设置字体
    QSizePolicy labelPolicy; // 创建尺寸策略
    labelPolicy.setVerticalPolicy(QSizePolicy::Expanding); // 设置垂直策略为扩展
    labelPolicy.setHorizontalPolicy(QSizePolicy::Expanding); // 设置水平策略为扩展
    m_label->setSizePolicy(labelPolicy); // 设置尺寸策略
    m_label->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); // 设置对齐方式
    connect(m_label, &LabelEditType::editingStarted, this, [this] { // 连接编辑开始信号
        auto tree_view = dynamic_cast<NodeTreeView *>(m_view); // 转换视图为NodeTreeView类型
        tree_view->setIsEditing(true); // 设置编辑状态为真
    });
    connect(m_label, &LabelEditType::editingFinished, this,
            [this](const QString &label) { // 连接编辑结束信号
                auto tree_view = dynamic_cast<NodeTreeView *>(m_view); // 转换视图为NodeTreeView类型
                tree_view->onRenameFolderFinished(label); // 重命名文件夹
                tree_view->setIsEditing(false); // 设置编辑状态为假
            });
    connect(dynamic_cast<NodeTreeView *>(m_view), &NodeTreeView::renameFolderRequested,
            m_label, // 连接重命名请求信号
            &LabelEditType::openEditor); // 打开编辑器
    layout->addWidget(m_label); // 将标签添加到布局
    layout->addSpacing(5); // 添加布局间隔
    m_contextButton = new PushButtonType(parent); // 创建上下文按钮
    m_contextButton->setMaximumSize({ 33, 25 }); // 设置最大尺寸
    m_contextButton->setMinimumSize({ 33, 25 }); // 设置最小尺寸
    m_contextButton->setCursor(QCursor(Qt::PointingHandCursor)); // 设置鼠标指针为手形
    m_contextButton->setFocusPolicy(Qt::TabFocus); // 设置焦点策略为Tab焦点
    if (m_view->selectionModel()->isSelected(m_index)) { // 如果索引被选中
        m_contextButton->setStyleSheet(QStringLiteral(R"(QPushButton { )"
                                                      R"(    border: none; )"
                                                      R"(    padding: 0px; )"
                                                      R"(    color: white; )"
                                                      R"(})"
                                                      R"(QPushButton:pressed { )"
                                                      R"(    border: none; )"
                                                      R"(    padding: 0px; )"
                                                      R"(    color: rgb(210, 210, 210); )"
                                                      R"(})"));
    } else {
        m_contextButton->setStyleSheet(QStringLiteral(R"(QPushButton { )"
                                                      R"(    border: none; )"
                                                      R"(    padding: 0px; )"
                                                      R"(    color: rgb(68, 138, 201); )"
                                                      R"(})"
                                                      R"(QPushButton:pressed { )"
                                                      R"(    border: none; )"
                                                      R"(    padding: 0px; )"
                                                      R"(    color: rgb(39, 85, 125); )"
                                                      R"(})"));
    }

#ifdef __APPLE__
    int pointSizeOffset = 0;
#else
    int pointSizeOffset = -4;
#endif
    m_contextButton->setFont(FontLoader::getInstance().loadFont("Font Awesome 6 Free Solid", "",
                                                                14 + pointSizeOffset));
    m_contextButton->setText(u8"\uf141"); // fa-ellipsis-h

    connect(m_contextButton, &QPushButton::clicked, m_view, [this](bool) {
        auto tree_view = dynamic_cast<NodeTreeView *>(m_view);
        //        tree_view->setCurrentIndexC(m_index);
        tree_view->onCustomContextMenu(tree_view->visualRect(m_index).topLeft()
                                       + m_contextButton->geometry().bottomLeft());
    });
    layout->addWidget(m_contextButton, 0, Qt::AlignRight);
    layout->addSpacing(5);
    connect(m_view, &QTreeView::expanded, this, [this](const QModelIndex &) { update(); });
}

void FolderTreeDelegateEditor::updateDelegate()
{
    auto displayName = m_index.data(NodeItem::Roles::DisplayText).toString();
    QFontMetrics fm(m_titleFont);
    displayName = fm.elidedText(displayName, Qt::ElideRight, m_label->contentsRect().width());

    if (m_view->selectionModel()->isSelected(m_index)) {
        m_label->setStyleSheet(QStringLiteral("QLabel{color: rgb(%1, %2, %3);}")
                                       .arg(QString::number(m_titleSelectedColor.red()),
                                            QString::number(m_titleSelectedColor.green()),
                                            QString::number(m_titleSelectedColor.blue())));
        m_folderIcon->setStyleSheet(
                QStringLiteral("QPushButton{border: none; padding: 0px; color: rgb(%1, %2, %3);}")
                        .arg(QString::number(m_titleSelectedColor.red()),
                             QString::number(m_titleSelectedColor.green()),
                             QString::number(m_titleSelectedColor.blue())));
    } else {
        m_label->setStyleSheet(QStringLiteral("QLabel{color: rgb(%1, %2, %3);}")
                                       .arg(QString::number(m_titleColor.red()),
                                            QString::number(m_titleColor.green()),
                                            QString::number(m_titleColor.blue())));
        m_folderIcon->setStyleSheet(
                QStringLiteral("QPushButton{border: none; padding: 0px; color: rgb(%1, %2, %3);}")
                        .arg(QString::number(m_folderIconColor.red()),
                             QString::number(m_folderIconColor.green()),
                             QString::number(m_folderIconColor.blue())));
    }
    m_label->setText(displayName);
    auto theme = dynamic_cast<NodeTreeView *>(m_view)->theme();

    QColor chevronColor(theme == Theme::Dark ? QColor(169, 160, 172) : QColor(103, 99, 105));
    m_expandIcon->setStyleSheet(QStringLiteral("QLabel{color: rgb(%1, %2, %3);}")
                                        .arg(QString::number(chevronColor.red()),
                                             QString::number(chevronColor.green()),
                                             QString::number(chevronColor.blue())));

    if (m_index.data(NodeItem::Roles::IsExpandable).toBool()) {
        if (m_view->isExpanded(m_index)) {
            m_expandIcon->setText(u8"\uf078"); // fa-chevron-down
        } else {
            m_expandIcon->setText(u8"\uf054"); // fa-chevron-right
        }
    }
}

void FolderTreeDelegateEditor::paintEvent(QPaintEvent *event)
{
    updateDelegate();
    QPainter painter(this);
    if (m_view->selectionModel()->isSelected(m_index)) {
        painter.fillRect(rect(), QBrush(m_activeColor));
    } else {
        auto listView = dynamic_cast<NoteListView *>(m_listView);
        if (listView->isDragging()) {
            if (m_theme == Theme::Dark) {
                painter.fillRect(rect(), QBrush(QColor(35, 52, 69)));
            } else {
                painter.fillRect(rect(), QBrush(QColor(180, 208, 233)));
            }
        } else {
            painter.fillRect(rect(), QBrush(m_hoverColor));
        }
    }
    QWidget::paintEvent(event);
}

void FolderTreeDelegateEditor::mouseDoubleClickEvent(QMouseEvent *event)
{
    if (m_label->geometry().contains(event->pos())) {
        m_label->openEditor();
    } else {
        QWidget::mouseDoubleClickEvent(event);
    }
}

void FolderTreeDelegateEditor::setTheme(Theme::Value theme)
{
    m_theme = theme;
    switch (theme) {
    case Theme::Light: {
        m_hoverColor = QColor(247, 247, 247);
        m_titleColor = QColor(26, 26, 26);
        break;
    }
    case Theme::Dark: {
        m_hoverColor = QColor(25, 25, 25);
        m_titleColor = QColor(212, 212, 212);
        break;
    }
    case Theme::Sepia: {
        m_hoverColor = QColor(251, 240, 217);
        m_titleColor = QColor(26, 26, 26);
        break;
    }
    }
}
