#ifndef FORMTXDEFAULTPROFILEDETAIL_H
#define FORMTXDEFAULTPROFILEDETAIL_H

#include <QWidget>
#include <QListWidgetItem>
#include <QTableWidgetItem>
#include <QStyledItemDelegate>
#include <QStyleOptionViewItem>

#include "BaseWidget.h"
#include "DataTypeDef.h"
#include "OcppSettings/ChargingProfiles/DialogLimitEdit.h"
#include "OcppSettings/ChargingProfiles/DialogWeekDayDetail.h"

namespace Ui {
class FormTxDefaultProfileDetail;
}

#define LIST_ROW_HEIGHT 60

/**
 * @class CustomItemDelegate
 * @brief CustomItemDelegate 是一个自定义的项委托类，继承自 QStyledItemDelegate。
 * 它主要用于在 QListView 或 QTableView 中自定义项的显示方式，特别是设置项的高度。
 * 
 * @note 本类主要重写了 sizeHint 方法，用于设置项的高度。
 * 
 * @param parent 指向父对象的指针，默认为 nullptr。
 * 
 * @example
 * CustomItemDelegate *delegate = new CustomItemDelegate(parentWidget);
 * listView->setItemDelegate(delegate);
 * 
 * @sa QStyledItemDelegate
 */
class CustomItemDelegate : public QStyledItemDelegate {
public:
    /**
     * @brief 构造函数，创建一个 CustomItemDelegate 对象。
     * 
     * @param parent 指向父对象的指针，默认为 nullptr。
     */
    explicit CustomItemDelegate(QObject *parent = nullptr) : QStyledItemDelegate(parent) {}

    /**
     * @brief 重写 sizeHint 方法，用于设置项的大小提示。
     * 
     * @param option 描述项的样式选项。
     * @param index 项的模型索引。
     * 
     * @return 项的大小，高度被设置为 LIST_ROW_HEIGHT。
     */
    QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override {
        QSize size = QStyledItemDelegate::sizeHint(option, index);
        size.setHeight(LIST_ROW_HEIGHT); // 设置行高
        return size;
    }
};

/**
 * @class FormTxDefaultProfileDetail
 * @brief FormTxDefaultProfileDetail 类用于显示和编辑充电配置文件详细信息。
 * 
 * 这个类继承自 BaseWidget，用于创建和管理充电配置文件详细信息界面。它包含多个初始化函数，用于设置界面组件，并提供了刷新数据的方法。
 * 
 * 核心功能包括：
 * - 初始化界面组件
 * - 刷新数据
 * - 更新数据
 * - 获取配置文件信息
 * 
 * 构造函数参数：
 * - BaseWidget *parent: 父窗口指针，默认为 nullptr。
 * 
 * 使用示例：
 * @code
 * FormTxDefaultProfileDetail *form = new FormTxDefaultProfileDetail(parentWidget);
 * form->setGun_id(1);
 * form->show();
 * @endcode
 * 
 * 注意事项：
 * - 在使用该类之前，请确保已经正确初始化了父窗口。
 * - 该类中的某些方法可能具有副作用，例如更新数据时可能会改变界面状态。
 */
class FormTxDefaultProfileDetail : public BaseWidget
{
    Q_OBJECT

public:
    explicit FormTxDefaultProfileDetail(BaseWidget *parent = nullptr);
    ~FormTxDefaultProfileDetail();

    bool returnParent() override;

    void setGun_id(int newGun_id);

    charging_profiles_detail_info_t profile_info() const;
    void setProfile_info(charging_profiles_detail_info_t newProfile_info);

private:
    void initWidget();
    void initConnect();
    void initComboBox();
    void initTableWidget();
    void initListWidget();

    void refreshData();
    void refreshGeneralData();
    void refreshDailyData();
    void refreshWeeklyData();
    void refreshDefaultData();
    void appendRowTableWidget(const QString& startTime,
                              const QString& limitType,
                              const QString& limit);

    bool updateData();
    QList<charging_profiles_detail_info_t> getProfileInfo(const QList<charging_profiles_detail_info_t>& dataList,
                                                          const int& connectorId,
                                                          const QString& purpose,
                                                          const QString& kind,
                                                          const QString& recurrencyKind);
    charging_profiles_detail_info_t getMaxStackLevel(const QList<charging_profiles_detail_info_t>& dataList);
    charging_profiles_detail_info_t getProfileInfo(const QList<charging_profiles_detail_info_t>& dataList,
                                                   const int& connectorId,
                                                   const QString& purpose,
                                                   const QString& kind,
                                                   const QString& recurrencyKind,
                                                   const int& stackLevel);
    void updateData(QList<charging_profiles_detail_info_t>& dataList,
                    const charging_profiles_detail_info_t& data,
                    const int& connectorId,
                    const QString& purpose,
                    const QString& kind,
                    const QString& recurrencyKind,
                    const int& stackLevel);

    bool isExistByConnectorId(const QList<charging_profiles_detail_info_t>& dataList,
                              const int& connectorId);
    bool isExistByPurpose(const QList<charging_profiles_detail_info_t>& dataList,
                          const int& connectorId,
                          const QString& purpose);
    bool isExistByKind(const QList<charging_profiles_detail_info_t>& dataList,
                       const int& connectorId,
                       const QString& purpose,
                       const QString& kind);
    bool isExistByRecurrencyKind(const QList<charging_profiles_detail_info_t>& dataList,
                                 const int& connectorId,
                                 const QString& purpose,
                                 const QString& kind,
                                 const QString& recurrencyKind);
    bool isExistByStackLevel(const QList<charging_profiles_detail_info_t>& dataList,
                             const int& connectorId,
                             const QString& purpose,
                             const QString& kind,
                             const QString& recurrencyKind,
                             const int& stackLevel);

    QList<charging_schedule_period_info_t> getDayOfWeekLimitList(const QList<charging_schedule_period_info_t>& dataList,
                                                                 const QString& startTime,
                                                                 const int& curDay);

    bool isDayOfWeek(const QString& startTime, const int& curDay, const int& seconds);
    void updateWeekPeriodList(QList<charging_schedule_period_info_t>& dataList,
                              const QList<charging_schedule_period_info_t>& newDataList,
                              const QString& startTime,
                              const int& curDay);
    int indexOfWeekPeriodList(const QList<charging_schedule_period_info_t>& dataList,
                              const charging_schedule_period_info_t& data);

signals:
    void valueChanged();

private slots:
    void dialyTableWidgetClicked(QTableWidgetItem* item);
    void weekdayTableWidgetDoubleClicked(QListWidgetItem* item);
    void addBtnClicked();
    void deleteBtnClicked();

protected:
    void showEvent(QShowEvent* event) override;

private:
    Ui::FormTxDefaultProfileDetail *ui;
    charging_profiles_detail_info_t m_profile_info;
    QScopedPointer<DialogLimitEdit> m_limit_dialog;
    QScopedPointer<DialogWeekDayDetail> m_weekday_dialog;
    int m_gun_id;
};

#endif // FORMTXDEFAULTPROFILEDETAIL_H
