pragma Singleton

import QtQuick
import Quickshell
import Quickshell.Io

// Centralized shell state management for small cache files
Singleton {
  id: root

  property string stateFile: ""
  property bool isLoaded: false

  // State properties for different services
  readonly property alias data: adapter

  // Signals for state changes
  signal displayStateChanged
  signal notificationsStateChanged
  signal changelogStateChanged
  signal colorSchemesListChanged

  Component.onCompleted: {
    // Setup state file path (needs Settings to be available)
    Qt.callLater(() => {
                   if (typeof Settings !== 'undefined' && Settings.cacheDir) {
                     stateFile = Settings.cacheDir + "shell-state.json";
                     stateFileView.path = stateFile;
                   }
                 });
  }

  // FileView for shell state
  FileView {
    id: stateFileView
    printErrors: false
    watchChanges: false

    adapter: JsonAdapter {
      id: adapter

      // CompositorService: display scales
      property var display: ({})

      // NotificationService: notification state
      property var notificationsState: ({
                                          lastSeenTs: 0
                                        })

      // UpdateService: changelog state
      property var changelogState: ({
                                      lastSeenVersion: ""
                                    })

      // SchemeDownloader: color schemes list
      property var colorSchemesList: ({
                                        schemes: [],
                                        timestamp: 0
                                      })

      // WallpaperService: current wallpapers per screen
      property var wallpapers: ({})
    }

    onLoaded: {
      root.isLoaded = true;
      Logger.d("ShellState", "Loaded state file");
    }

    onLoadFailed: error => {
      if (error === 2) {
        // File doesn't exist, will be created on first write
        root.isLoaded = true;
        Logger.d("ShellState", "State file doesn't exist, will create on first write");
      } else {
        Logger.e("ShellState", "Failed to load state file:", error);
        root.isLoaded = true;
      }
    }
  }

  // Debounced save timer
  Timer {
    id: saveTimer
    interval: 300
    onTriggered: performSave()
  }

  property bool saveQueued: false

  function save() {
    saveQueued = true;
    saveTimer.restart();
  }

  function performSave() {
    if (!saveQueued || !stateFile) {
      return;
    }

    saveQueued = false;

    try {
      // Ensure cache directory exists
      Quickshell.execDetached(["mkdir", "-p", Settings.cacheDir]);

      Qt.callLater(() => {
                     try {
                       stateFileView.writeAdapter();
                       Logger.d("ShellState", "Saved state file");
                     } catch (writeError) {
                       Logger.e("ShellState", "Failed to write state file:", writeError);
                     }
                   });
    } catch (error) {
      Logger.e("ShellState", "Failed to save state:", error);
    }
  }

  // Convenience functions for each service

  // Display state (CompositorService)
  function setDisplay(displayData) {
    adapter.display = displayData;
    save();
    displayStateChanged();
  }

  function getDisplay() {
    return adapter.display || {};
  }

  // Notifications state (NotificationService)
  function setNotificationsState(stateData) {
    adapter.notificationsState = stateData;
    save();
    notificationsStateChanged();
  }

  function getNotificationsState() {
    return adapter.notificationsState || {
      lastSeenTs: 0
    };
  }

  // Changelog state (UpdateService)
  function setChangelogState(stateData) {
    adapter.changelogState = stateData;
    save();
    changelogStateChanged();
  }

  function getChangelogState() {
    return adapter.changelogState || {
      lastSeenVersion: ""
    };
  }

  // Color schemes list (SchemeDownloader)
  function setColorSchemesList(listData) {
    adapter.colorSchemesList = listData;
    save();
    colorSchemesListChanged();
  }

  function getColorSchemesList() {
    return adapter.colorSchemesList || {
      schemes: [],
      timestamp: 0
    };
  }

  // Wallpapers (WallpaperService)
  function setWallpapers(wallpapersData) {
    adapter.wallpapers = wallpapersData;
    save();
  }

  function getWallpapers() {
    return adapter.wallpapers || {};
  }
}
