#pragma once
#include "completion-model.hpp"
#include "config/config.hpp"
#include "service-registry.hpp"
#include <QObject>
#include <QVariantList>

class GeneralSettingsModel : public QObject {
  Q_OBJECT

  Q_PROPERTY(bool searchFilesInRoot READ searchFilesInRoot WRITE setSearchFilesInRoot NOTIFY configChanged)
  Q_PROPERTY(bool inputServerEnabled READ inputServerEnabled WRITE setInputServerEnabled NOTIFY configChanged)
  Q_PROPERTY(bool closeOnFocusLoss READ closeOnFocusLoss WRITE setCloseOnFocusLoss NOTIFY configChanged)
  Q_PROPERTY(bool closeOnEscape READ closeOnEscape WRITE setCloseOnEscape NOTIFY configChanged)
  Q_PROPERTY(bool considerPreedit READ considerPreedit WRITE setConsiderPreedit NOTIFY configChanged)
  Q_PROPERTY(bool popToRootOnClose READ popToRootOnClose WRITE setPopToRootOnClose NOTIFY configChanged)
  Q_PROPERTY(bool popOnBackspace READ popOnBackspace WRITE setPopOnBackspace NOTIFY configChanged)
  Q_PROPERTY(bool activateOnSingleClick READ activateOnSingleClick WRITE setActivateOnSingleClick NOTIFY
                 configChanged)
  Q_PROPERTY(bool wrapNavigation READ wrapNavigation WRITE setWrapNavigation NOTIFY configChanged)
  Q_PROPERTY(
      bool encryptSensitiveData READ encryptSensitiveData WRITE setEncryptSensitiveData NOTIFY configChanged)
  Q_PROPERTY(
      bool telemetrySystemInfo READ telemetrySystemInfo WRITE setTelemetrySystemInfo NOTIFY configChanged)
  Q_PROPERTY(bool layerShellEnabled READ layerShellEnabled WRITE setLayerShellEnabled NOTIFY configChanged)
  Q_PROPERTY(bool clientSideDecorations READ clientSideDecorations WRITE setClientSideDecorations NOTIFY
                 configChanged)
  Q_PROPERTY(QString rounding READ rounding WRITE setRounding NOTIFY configChanged)
  Q_PROPERTY(QString csdBorderWidth READ csdBorderWidth WRITE setCsdBorderWidth NOTIFY configChanged)
  Q_PROPERTY(QString csdShadowSize READ csdShadowSize WRITE setCsdShadowSize NOTIFY configChanged)
  Q_PROPERTY(bool compactMode READ compactMode WRITE setCompactMode NOTIFY configChanged)
  Q_PROPERTY(QString windowOpacity READ windowOpacity WRITE setWindowOpacity NOTIFY configChanged)
  Q_PROPERTY(
      bool nativeTextRendering READ nativeTextRendering WRITE setNativeTextRendering NOTIFY configChanged)
  Q_PROPERTY(QString fontSize READ fontSize WRITE setFontSize NOTIFY configChanged)
  Q_PROPERTY(CompletionModel *windowMaterialModel READ windowMaterialModel CONSTANT)
  Q_PROPERTY(QVariant currentWindowMaterial READ currentWindowMaterial NOTIFY configChanged)
  Q_PROPERTY(CompletionModel *themeModel READ themeModel CONSTANT)
  Q_PROPERTY(CompletionModel *fontModel READ fontModel CONSTANT)
  Q_PROPERTY(CompletionModel *iconThemeModel READ iconThemeModel CONSTANT)
  Q_PROPERTY(CompletionModel *faviconServiceModel READ faviconServiceModel CONSTANT)
  Q_PROPERTY(CompletionModel *keybindingSchemeModel READ keybindingSchemeModel CONSTANT)
  Q_PROPERTY(CompletionModel *languageModel READ languageModel CONSTANT)
  Q_PROPERTY(QVariant currentLanguage READ currentLanguage NOTIFY configChanged)
  Q_PROPERTY(QVariant currentTheme READ currentTheme NOTIFY configChanged)
  Q_PROPERTY(QVariant currentFont READ currentFont NOTIFY configChanged)
  Q_PROPERTY(QVariant currentIconTheme READ currentIconTheme NOTIFY configChanged)
  Q_PROPERTY(QVariant currentFaviconService READ currentFaviconService NOTIFY configChanged)
  Q_PROPERTY(QVariant currentKeybindingScheme READ currentKeybindingScheme NOTIFY configChanged)
  Q_PROPERTY(QString toggleShortcut READ toggleShortcut WRITE setToggleShortcut NOTIFY configChanged)

signals:
  void configChanged();

public:
  explicit GeneralSettingsModel(QObject *parent = nullptr);

  bool searchFilesInRoot() const;
  void setSearchFilesInRoot(bool v);
  bool closeOnFocusLoss() const;
  void setCloseOnFocusLoss(bool v);
  bool closeOnEscape() const;
  void setCloseOnEscape(bool v);
  bool considerPreedit() const;
  void setConsiderPreedit(bool v);
  bool popToRootOnClose() const;
  void setPopToRootOnClose(bool v);
  bool popOnBackspace() const;
  void setPopOnBackspace(bool v);
  bool activateOnSingleClick() const;
  void setActivateOnSingleClick(bool v);
  bool wrapNavigation() const;
  void setWrapNavigation(bool v);
  bool encryptSensitiveData() const;
  void setEncryptSensitiveData(bool v);
  bool telemetrySystemInfo() const;
  void setTelemetrySystemInfo(bool v);
  bool layerShellEnabled() const;
  void setLayerShellEnabled(bool v);
  bool clientSideDecorations() const;
  void setClientSideDecorations(bool v);
  QString rounding() const;
  void setRounding(const QString &v);
  QString csdBorderWidth() const;
  void setCsdBorderWidth(const QString &v);
  QString csdShadowSize() const;
  void setCsdShadowSize(const QString &v);
  bool compactMode() const;
  void setCompactMode(bool v);
  QString windowOpacity() const;
  void setWindowOpacity(const QString &v);
  bool nativeTextRendering() const;
  void setNativeTextRendering(bool v);
  bool inputServerEnabled() const;
  void setInputServerEnabled(bool v);
  QString fontSize() const;
  void setFontSize(const QString &v);

  CompletionModel *windowMaterialModel() { return &m_windowMaterialModel; }
  CompletionModel *themeModel() { return &m_themeModel; }
  CompletionModel *fontModel() { return &m_fontModel; }
  CompletionModel *iconThemeModel() { return &m_iconThemeModel; }
  CompletionModel *faviconServiceModel() { return &m_faviconServiceModel; }
  CompletionModel *keybindingSchemeModel() { return &m_keybindingSchemeModel; }
  CompletionModel *languageModel() { return &m_languageModel; }

  QVariant currentWindowMaterial() const;
  Q_INVOKABLE void selectWindowMaterial(const QString &id);

  QVariant currentLanguage() const;
  QVariant currentTheme() const;
  QVariant currentFont() const;
  QVariant currentIconTheme() const;
  QVariant currentFaviconService() const;
  QVariant currentKeybindingScheme() const;

  Q_INVOKABLE void selectTheme(const QString &id);
  Q_INVOKABLE void selectFont(const QString &id);
  Q_INVOKABLE void selectIconTheme(const QString &id);
  Q_INVOKABLE void selectFaviconService(const QString &id);
  Q_INVOKABLE void selectKeybindingScheme(const QString &id);
  Q_INVOKABLE void selectLanguage(const QString &id);

  QString toggleShortcut() const;
  void setToggleShortcut(const QString &shortcut);

private:
  const config::ConfigValue &cfg() const;
  config::Manager &cfgManager() const;

  QVariantList windowMaterialItems() const;
  QVariantList themeItems() const;
  QVariantList fontItems() const;
  QVariantList iconThemeItems() const;
  QVariantList faviconServiceItems() const;
  QVariantList keybindingSchemeItems() const;
  QVariantList languageItems() const;
  void refreshDynamicModels();

  CompletionModel m_windowMaterialModel{this};
  CompletionModel m_themeModel{this};
  CompletionModel m_fontModel{this};
  CompletionModel m_iconThemeModel{this};
  CompletionModel m_faviconServiceModel{this};
  CompletionModel m_keybindingSchemeModel{this};
  CompletionModel m_languageModel{this};
  QVariantList m_themeItems;
  QVariantList m_iconThemeItems;
};
