#ifndef TREEVIEWMANAGER_H
#define TREEVIEWMANAGER_H

#include <QWidget>
#include <QTreeView>
#include <QJsonObject>
#include <QStandardItemModel>
#include <QMap>
#include <QCheckBox>
#include <QJsonDocument>
#include <QJsonArray>
#include <QFile>
#include <QVBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QComboBox>
#include <QRadioButton>
#include <QButtonGroup>
#include <QDebug>
#include <QPushButton>
#include <QStyleFactory>
#include <QTimer>
#include <QPainter>
#include <QEvent>
#include <QStringList>
#include <QSettings>
#include <QSet>
#include <QVariant>
#include <QMenu>
#include <QAction>
#include <QMessageBox>
#include <QTimeEdit>
#include <QHBoxLayout>
#include <QCursor>
#include <QScrollArea>
#include <QToolButton>
#include <QFileInfo>


class OriginalWnd; // 前向声明


class TreeViewManager : public QWidget
{
    Q_OBJECT

public:
    /**
     * @brief 构造函数
     * @param parent 父窗口
     * @param downView 完整目录树的视图
     * @param widget2 父组件,用于确定导航栏位置
     */
    explicit TreeViewManager(OriginalWnd* originalWnd, QWidget *widget2, QWidget *parent = nullptr);
    virtual ~TreeViewManager();

    void applyCustomStyles();  //目录树样式

    void clearThirdLevelMenu();    //清理并隐藏三级目录菜单内容

    void switchConfig(const QString &configKey);    //切换配置文件

    void loadJsonFromFile(const QString &filePath);  //加载 JSON 数据

    void updateNavigationBar(const QModelIndex &index);  //更新导航栏内容,根据点击的目录项动态显示

    void preloadAllConfigs(const QStringList &configPaths);   // 加载多个配置文件到内存

    QModelIndex findLastVisibleChild(const QModelIndex &parentIndex);  // 分割线 找到最后一个可见子项

    void loadButtonConfigForThirdLevel(const QJsonObject &thirdLevelObj); //加载并显示三级目录的按钮配置信息

    void drawSiblingLine(const QModelIndex &childIndex, QPainter &painter);  //画竖线

    void paintAllBranches(const QModelIndex &parentIndex, QPainter &painter);   //画垂直线

    void drawParentChildLine(const QModelIndex &childIndex, QPainter &painter);  //L型拐角线,调整横向线段的长度

    void loadJsonDoc(const QJsonDocument &doc, const QString &configFilePath); // 直接传递 QJsonDocument 进行加载

private:
    QWidget *widget2;        // 父组件,用于确定导航栏位置

    QTreeView *treeViewDown;    // 完整目录树

    OriginalWnd *m_originalWnd;   // 声明指向 OriginalWnd 的指针

    QWidget *navigationWidget;    // 动态导航栏窗口

    QPushButton *buttonOpenFile;     // 返回一级菜单
    QPushButton *buttonUp;       // 遍历导航向上
    QPushButton *buttonDown;     // 遍历导航向下
    QPushButton *buttonLeft;     // 进入下一级目录
    QPushButton *buttonRight;     // 返回上一级目录

    QList<QWidget*> m_fieldWidgets; // 存储三级菜单中的可导航控件
    int m_currentFieldIndex = -1;   // 当前焦点控件的索引

    QStandardItemModel *downModel;   // 树状结构模型

    QVBoxLayout *navigationLayout;   // 导航栏布局

    bool m_blockItemChanged;   // 防止递归触发信号

    void updateChildItems(QStandardItem *parentItem, Qt::CheckState state);    // 更新所有子项的复选框状态

    void updateParentItems(QStandardItem *parentItem);   // 更新所有父项的复选框状态

    QSet<QString> checkedPaths;     // 记录被选中的复选框路径

    QString currentConfigFilePath;  // 当前配置文件路径

    QMap<QString, QJsonDocument> m_configCache;     // 用于缓存所有配置文件 JSON

    void clearAllSeparators();          // 隐藏并删除所有分割线

    QString currentConfigKey(const QString &configFilePath);        // 使用文件名作为唯一标识符

    QStandardItem* findFirstThirdLevelItemDFS(QStandardItem *parentItem);   // 查找非三级目录的内容添加分隔线

    void setCheckedPaths(const QStringList &checkedPaths);    // 根据路径设置复选框状态

    QStringList collectCheckedPaths();    // 收集所有被选中的复选框路径

    void saveCheckedPaths();   //保存复选框状态

    void loadCheckedPaths();   //加载复选框状态

    QJsonDocument m_jsonDoc;     // 存储已加载的 JSON 文档

    QSet<QString> visitedPaths;     // 用于存储选中路径

    QSet<QString> expandedPaths;     // 用于存储选中展开路径

    bool restoring;     // 标识当前是否处于“恢复”状态

    QFrame* createUnifiedSeparator(QWidget *parent, int height = 1);    //创建横线样式

    void updateSeparatorLine();    // 目录树的横线

    QMap<QStandardItem*, QFrame*> firstLevelSeparators;   // 遍历记录的一级目录

    void saveVisitedPaths();    //保存当前选中与展开路径到 QSettings

    void loadVisitedPaths();     //从 QSettings 中加载上一次的选中与展开路径

    void addVisitedPath(const QStringList &path);    //将某条选中路径添加到 visitedPaths

    void removeVisitedPath(const QStringList &path);   //将某条选中路径从 visitedPaths 中移除

    void addExpandedPath(const QStringList &path);    //将某条展开路径添加到 expandedPaths

    void removeExpandedPath(const QStringList &path);    //将某条展开路径从 expandedPaths 中移除

    QStringList buildItemPath(QStandardItem *item);    //构建给定 QStandardItem 的路径,如 "一级/二级/三级"

    QModelIndex findItemByPath(const QStringList &path);     //根据路径查找对应的 QModelIndex

    //QModelIndex getNextIndex(const QModelIndex &currentIndex);   //获取当前索引的下一个有效索引

    //QModelIndex getLastChildIndex(const QModelIndex &parentIndex); //获取最后一个子节点的索引

    void setupButton();  // 创建并初始化按钮

    void buildTree(const QJsonObject &jsonObj, QStandardItem *parent); //构建目录树

    void displayThirdLevelFields(const QJsonObject &fields); //显示三级目录的字段内容

    //根据分段路径依次往下层匹配
    QModelIndex findItemByPathRecursive(QStandardItem *parentItem,const QStringList &path,int depth);

    //各个节点间遍历最终输出的所有展开路径
    void storeExpandedItems(QStandardItem *parentItem,const QStringList &currentPath,QStringList &expandedPaths);

    // 收集所有被选中的复选框路径
    QStringList collectCheckedPathsRecursive(QStandardItem *item = nullptr, QStringList path = QStringList());


protected:

    bool eventFilter(QObject *watched, QEvent *event) override;   //拦截  Paint 事件

private slots:

    void onItemChanged(QStandardItem *item);   //处理复选框状态的变化

    void onButtonOpenFileClicked();    // 槽函数:返回一级菜单

    void onButtonUpClicked();    // 槽函数:遍历导航向上

    void onButtonDownClicked();     // 槽函数:遍历导航向下

    void onButtonLeftClicked();      // 槽函数:进入下一级目录

    void onButtonRightClicked();     // 槽函数:返回上一级目录

};

#endif // TREEVIEWMANAGER_H