#pragma once
#include <QMainWindow>
#include <QMap>
#include <QIcon>
#include <QMetaObject>
#include <QStringList>

#include "../core/models/ProjectModel.h"
#include "../editor/scene/LadderScene.h"     // EditorMode 枚举
#include "../sim/simdebugsession.h"

class ProjectManager;
class QMdiArea;
class QMdiSubWindow;
class QTabWidget;
class QTableWidget;
class QTreeWidget;
class QTreeWidgetItem;
class QPlainTextEdit;
class QLabel;
class PlcOpenViewer;
class LadderView;
class SmartSimWidget;
class QMenu;

// ─────────────────────────────────────────────────────────────
// PLC 连接状态
// ─────────────────────────────────────────────────────────────
enum class PlcConnState {
    Disconnected,   // 未连接（灰色）
    Connecting,     // 正在连接（黄色）
    Connected,      // 已连接（绿色）
};

// PLC 运行状态（仅 Connected 时有意义）
enum class PlcRunState {
    Unknown,        // 未知（灰色）
    Stopped,        // 已停止（橙色）
    Running,        // 运行中（绿色）
    Paused,         // 暂停（黄色）
    Error,          // 错误（红色）
};

// ─────────────────────────────────────────────────────────────
class MainWindow : public QMainWindow {
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    // 供外部（网络线程等）更新 PLC 状态
    void setPlcConnState(PlcConnState state);
    void setPlcRunState (PlcRunState  state);

private:
    // ---- 初始化各区域 ----
    void setupMenuBar();
    void setupToolBar();
    void setupProjectPanel();
    void setupLibraryPanel();
    void setupConsolePanel();
    void setupCentralArea();
    void setupStatusBar();   // 状态栏 PLC 状态指示器

    // ---- 项目操作（委托给 ProjectManager）----
    void newProject();
    void openProject();
    void openRecentProject(const QString& path);
    void saveProject();
    void saveProjectAs();
    void buildProject();     // 编译：生成 C 代码
    void downloadProject();  // 下载：打开下载对话框
    void connectToPlc();     // 连接/断开 PLC

    // ---- 项目树 ----
    void rebuildProjectTree();
    void onTreeDoubleClicked(QTreeWidgetItem* item, int column);
    void onTreeContextMenu(const QPoint& pos);

    // ---- 子窗口管理 ----
    void openPouTab(PouModel* pou);
    void closeAllPouTabs();
    void openProjectProperties();            // 打开项目属性面板（单例）
    void openSmartSim();                     // 打开 PC 仿真面板（单例）
    void updateDebuggerValues(const QVector<SimDebugValue>& vars);
    void appendPlcLog(const QString& message);
    QString selectedDebuggerVariable() const;
    void forceDebuggerVariable();
    void releaseDebuggerVariable();
    QString debuggerForceTarget(const QString& name) const;
    void showDebuggerContextMenu(const QPoint& pos);
    void addDebuggerVariableToSimIo(const QString& role, int index);
    void removeDebuggerVariableFromSimIo();
    void syncSimIoMappings();
    QString simIoRoleForVariable(const QString& name) const;

    // ---- POU 编辑器工厂 ----
    QWidget* createPouEditorWidget(PouModel* pou);
    QWidget* createVarDeclWidget(PouModel* pou);
    QWidget* createProjectPropertiesWidget();    // 项目属性面板

    // ---- Driver 安装 ----
    void installDriverCab(const QString& cabPath);

    // ---- 窗口标题 ----
    void updateWindowTitle();
    QStringList recentProjectPaths() const;
    void addRecentProject(const QString& path);
    void removeRecentProject(const QString& path);
    void updateRecentProjectsMenu();

    // ---- 主题 ----
    void applyTheme(const QString& qrcPath);  // 加载并应用 QSS

    // ---- 视图缩放 ----
    LadderView* activeView() const;   // 当前活跃的图形视图（可能为 nullptr）
    void zoomIn();
    void zoomOut();
    void zoomFit();

    // ---- 工具栏辅助 ----
    static QIcon makeLdIcon(const QString& type, int size = 24);
    void onLdModeChanged(EditorMode mode);
    static QString debugValueText(const QVariant& value);
    static QVariant parseDebugForceValue(const QString& type, const QString& text, bool* ok);

    // ---- 状态栏辅助 ----
    static QString ledStyle(const QString& color);  // 生成圆形 LED 样式

    // ---- 事件过滤（状态栏点击）────────────────────────────────
    bool eventFilter(QObject* obj, QEvent* ev) override;

    // ---- 成员变量 ----
    ProjectManager* m_projectManager = nullptr;
    ProjectModel*   m_project        = nullptr;
    PlcOpenViewer*  m_scene       = nullptr;   // 当前活跃图形场景
    QMdiArea*       m_mdiArea     = nullptr;
    QTreeWidget*    m_projectTree = nullptr;
    QTreeWidget*    m_libraryTree = nullptr;
    QTabWidget*     m_libraryTabs = nullptr;
    QTableWidget*   m_debuggerTable = nullptr;
    QTabWidget*     m_consoleTabs = nullptr;
    QPlainTextEdit* m_consoleEdit = nullptr;
    QPlainTextEdit* m_plcLogEdit = nullptr;
    QMenu* m_recentProjectsMenu = nullptr;
    QStringList m_simDiVars;
    QStringList m_simDoVars;
    QStringList m_simAiVars;
    QStringList m_simAoVars;
    QVector<SimDebugValue> m_lastDebugValues;

    // ---- PLC 状态 ----
    PlcConnState    m_connState = PlcConnState::Disconnected;
    PlcRunState     m_runState  = PlcRunState::Unknown;
    QString         m_plcUri;               // e.g. "PYRO://localhost:61131"

    // 状态栏永久控件
    QLabel* m_connLed      = nullptr;       // 连接状态 LED
    QLabel* m_connLabel    = nullptr;       // 连接状态文字
    QLabel* m_stateLed     = nullptr;       // 运行状态 LED
    QLabel* m_stateLabel   = nullptr;       // 运行状态文字
    QLabel* m_uriLabel     = nullptr;       // PLC 地址

    // 项目属性面板（单例子窗口）
    QMdiSubWindow* m_projPropSubWin = nullptr;
    // PC 仿真面板（独立窗口，单例）
    SmartSimWidget* m_smartSimWindow = nullptr;

    // 每个 MDI 子窗口对应的 PouModel
    QMap<QMdiSubWindow*, PouModel*> m_subWinPouMap;
    // 每个 PouModel 对应的图形场景（LD / FBD / SFC，关闭后保留复用）
    QMap<PouModel*, PlcOpenViewer*> m_sceneMap;
    // LD 工具栏模式按钮映射（Escape / signal 时同步状态）
    QMap<EditorMode, QAction*> m_ldModeActions;
    // LD 专属工具栏动作（含前置分隔符），切换到文本视图时隐藏
    QList<QAction*> m_ldToolActions;

    // 工具栏动作（需随状态动态 enable/disable）
    QAction* m_aUndo    = nullptr;
    QAction* m_aRedo    = nullptr;
    // 当前图形场景 undo stack 的 canUndo/canRedo 连接（切换窗口时断开重连）
    QMetaObject::Connection m_undoConn;
    QMetaObject::Connection m_redoConn;
    QString  m_currentTheme;         // 当前主题 QRC 路径
    QString  m_lastBuildOutput;      // 最近一次成功构建出的可下载产物
    QAction* m_aConnect  = nullptr;  // 连接/断开（图标随状态切换）
    QAction* m_aTransfer = nullptr;  // 下载程序
    QAction* m_aRun      = nullptr;
    QAction* m_aStop     = nullptr;
};
