#ifndef CANCONTROLLER_H
#define CANCONTROLLER_H

#include <QObject>
#include <QVariant>
#include <QDateTime>

class QQmlEngine;
class QJSEngine;
class QTimer;

class CanMessage;

class CanController : public QObject
{
    Q_OBJECT

    Q_PROPERTY(QString inputVoltage MEMBER inputVoltage_ NOTIFY inputVoltageChanged)
    Q_PROPERTY(QString radiatorTemperature MEMBER radiatorTemperature_ NOTIFY radiatorTemperatureChanged)
    Q_PROPERTY(QString outputVoltage MEMBER outputVoltage_ NOTIFY outputVoltageChanged)
    Q_PROPERTY(QString emergencyCounter MEMBER emergencyCounter_ NOTIFY emergencyCounterChanged)
    Q_PROPERTY(QString inputCurrent MEMBER inputCurrent_ NOTIFY inputCurrentChanged)

    Q_PROPERTY(QString maximumCurrent MEMBER maximumCurrent_ NOTIFY maximumCurrentChanged)
    Q_PROPERTY(QString emergencyDelay MEMBER emergencyDelay_ NOTIFY emergencyDelayChanged)
    Q_PROPERTY(QString breakingDelay MEMBER breakingDelay_ NOTIFY breakingDelayChanged)
    Q_PROPERTY(QString retriesAfterEmergencyBreak MEMBER retriesAfterEmergencyBreak_ NOTIFY retriesAfterEmergencyBreakChanged)
    Q_PROPERTY(QString breakingCurrent MEMBER breakingCurrent_ NOTIFY breakingCurrentChanged)

    Q_PROPERTY(QVariantList statuses MEMBER statuses_ NOTIFY statusesChanged)
    Q_PROPERTY(bool isVkuClosed MEMBER isVkuClosed_ NOTIFY isVkuClosedChanged)

public:
    explicit CanController(QObject* parent = nullptr);
    ~CanController();

    static QObject* qmlInstance(QQmlEngine* engine, QJSEngine* scriptEngine);

public slots:
    void connectCan();
    void disconnectCan();
    void tryConnectCan();

    void switchVkuClosure();
    void emergencyReset();

private slots:
    void sendParameters();
    void sendVkuClosure();

signals:
    void inputVoltageChanged();
    void radiatorTemperatureChanged();
    void outputVoltageChanged();
    void emergencyCounterChanged();
    void inputCurrentChanged();

    void maximumCurrentChanged();
    void emergencyDelayChanged();
    void breakingDelayChanged();
    void retriesAfterEmergencyBreakChanged();
    void breakingCurrentChanged();

    void statusesChanged();
    void isVkuClosedChanged();

private slots:
    void handlePackage(int index);
    void handleCurrentState(const CanMessage* message);
    void handleStatus(const CanMessage* message);

    void showStatus(quint32 status);
    void updateCanStatus();

private:
    void setupDrivers();
    void setupDefaultParameters();

private:
    bool isConnected_ = false;
    bool isFirstCheck_ = true;
    QDateTime lastPackageDateTime_;
    QTimer* reconnectTimer_ = nullptr;

    QString inputVoltage_;
    QString radiatorTemperature_;
    QString outputVoltage_;
    QString emergencyCounter_;
    QString inputCurrent_;

    QString maximumCurrent_;
    QString emergencyDelay_;
    QString breakingDelay_;
    QString retriesAfterEmergencyBreak_;
    QString breakingCurrent_;

    bool isVkuClosed_ = false;

    QVariantList statuses_;
};

#endif // CANCONTROLLER_H
