import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Controls 2.15

import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core 2.1 as PlasmaCore

import "../_toolbox" as Tb
import "../service" as Sv

// Корневой элемент
Item {
  id: root

  property string appTitle: Plasmoid.configuration.title

  property string iconDefault: "../assets/default.svg"
  property string iconRefresh: "../assets/refresh.svg"
  property string iconReadyToUpgrade: "../assets/ready.svg"
  property string iconInstalling: "../assets/install.svg"
  property string iconError: "../assets/error.svg"

  property string mainIcon: iconDefault

  property int total: 0
  property string badgeText: ""

  property bool badgeVisible: false

  property bool showNotification: Plasmoid.configuration.showNotification
  property bool checkOnStart: Plasmoid.configuration.checkOnStart

  property string notifyText: ""
  property string errorText: ""

  property int defaultStatus: -1
  property int normalStatus: 0
  property int checkingUpdatesStatus: 1
  property int readyStatus: 2
  property int installingStatus: 3
  property int errorStatus: 4

  property int upgradeStatus: defaultStatus

  property string listOfPackages: ""

  Plasmoid.preferredRepresentation: Plasmoid.compactRepresentation
  Plasmoid.compactRepresentation: Compact {}
  Plasmoid.fullRepresentation: Full {}
  // load one instance of each needed service
  Sv.Updater{ id: updater }
  Tb.Cmd { id: cmd }

  PlasmaCore.DataSource {
    id: notificationSource
    engine: "notifications"
    connectedSources: "org.freedesktop.Notifications"
  }

  function strip(text) {
    return text.replace(/[^a-zA-Z0-9 \(\)\[\]:;\.,\_\-><\n\t]/g, "")
    //return text.replace(/[^a-zA-Z0-9 \n\t]/g, "")
  }

  function createNotification(text) {

    var service = notificationSource.serviceForSource("notification");
    var operation = service.operationDescription("createNotification");

    operation.appName = i18n(appTitle);
    operation["appIcon"] = iconDefault;
    operation.summary = text || i18n("Some text")
    operation["body"] = "";
    operation["timeout"] = 10000;

    service.startOperationCall(operation);
  }

  // updates the icon according to the refresh status
  function updateUi() {

    switch (upgradeStatus) {
      case normalStatus:
        mainIcon = iconDefault
        badgeVisible = false
        break
      case checkingUpdatesStatus:
        mainIcon = iconRefresh
        // badgeText = "↻"
        badgeVisible = false
        break
      case readyStatus:
        mainIcon = iconReadyToUpgrade
        badgeText = (total < 99 || isNaN(total)) ? total : "99+"
        badgeVisible = true
        break
      case installingStatus:
        mainIcon = iconInstalling
        badgeVisible = true
        break
      case errorStatus:
        mainIcon = iconError
        badgeVisible = false
        break
      default:
        mainIcon = iconDefault
        badgeVisible = false
    }
  }

  // map the cmd signal with the widget
  Connections {
    target: cmd

    function onExited(cmd, exitCode, exitStatus, stdout, stderr) {

      // Если запущена проверка обновлений
      if (cmd == Plasmoid.configuration.commandForCheckingUpdates) {

        // Если ошибок при проверке обновлений нет
        if (exitCode == 0) {

          var stdoutText = strip(stdout)
          var lines = parseInt(stdoutText.trim().split('\n').length, 10)

          // Если стандарный вывод можно подсчитать по строкам
          if (lines) {
            total = lines

            listOfPackages = stdoutText

            if (showNotification) {
              notifyText = i18n("Found %1 packages to update", total)
              createNotification(notifyText)
            }

            upgradeStatus = readyStatus
            updateUi()
          }

          // Иначе
          else {
            total = 0

            upgradeStatus = normalStatus
            updateUi()

            upgradeStatus = defaultStatus
          }
        }

        // Если есть ошибки при проверке обновлений
        else if (exitCode == 1) {
          if (stderr.length > 0) {
            errorText = strip(stderr).trim()

            if (showNotification) {
              notifyText = i18n("Update error: \n%1", errorText)
              createNotification(notifyText)
            }
          }

          upgradeStatus = errorStatus
          updateUi()

          upgradeStatus = defaultStatus
        }

        // Если нет пакетов для обновлений
        else if (exitCode == 2) {
          upgradeStatus = defaultStatus
          updateUi()
        }

        // Неправильно указана программа в настройках
        else if (exitCode == 127) {

          if (showNotification) {
            notifyText = i18n("Perhaps the program specified in the settings does not exist on this computer")
            createNotification(notifyText)
          }

          upgradeStatus = defaultStatus
          updateUi()
        }

        // Иначе
        else {
          upgradeStatus = defaultStatus
          updateUi()
        }
      }

      // Если запущено обновление пакетов
      else if (cmd == Plasmoid.configuration.commandForUpgrade) {

        // Если обновление было успешно
        if (exitCode == 0) {
          total = 0

          listOfPackages = ""

          // if (showNotification) {
          //   notifyText = i18n("Update succesed")
          //   createNotification(notifyText)
          // }

          upgradeStatus = normalStatus
          updateUi()

          upgradeStatus = defaultStatus
        }

        // Неправильно указана программа в настройках
        else if (exitCode == 127) {
          if (showNotification) {
            notifyText = i18n("Perhaps the program specified in the settings does not exist on this computer")
            createNotification(notifyText)
          }

          upgradeStatus = defaultStatus
          updateUi()
        }

        // Если есть ошибки при обновлении пакетов
        else {
          if (showNotification) {
            notifyText = i18n("Update failed")
            createNotification(notifyText)
          }

          upgradeStatus = errorStatus
          updateUi()

          upgradeStatus = defaultStatus
        }
      }
    }

    function onConnected(source) {
      // Если запущена проверка обновлений
      if (source == Plasmoid.configuration.commandForCheckingUpdates) {
        upgradeStatus = checkingUpdatesStatus
        updateUi()
        return
      }

      upgradeStatus = installingStatus
      updateUi()
    }
  }
}