import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell
import Quickshell.Services.UPower
import qs.Commons
import qs.Modules.Bar.Extras
import qs.Services.Hardware
import qs.Services.UI
import qs.Widgets

Item {
  id: root

  property ShellScreen screen

  // Widget properties passed from Bar.qml for per-instance settings
  property string widgetId: ""
  property string section: ""
  property int sectionWidgetIndex: -1
  property int sectionWidgetsCount: 0

  property var widgetMetadata: BarWidgetRegistry.widgetMetadata[widgetId]
  property var widgetSettings: {
    if (section && sectionWidgetIndex >= 0) {
      var widgets = Settings.data.bar.widgets[section];
      if (widgets && sectionWidgetIndex < widgets.length) {
        return widgets[sectionWidgetIndex];
      }
    }
    return {};
  }

  readonly property bool isBarVertical: Settings.data.bar.position === "left" || Settings.data.bar.position === "right"
  readonly property string displayMode: widgetSettings.displayMode !== undefined ? widgetSettings.displayMode : widgetMetadata.displayMode
  readonly property real warningThreshold: widgetSettings.warningThreshold !== undefined ? widgetSettings.warningThreshold : widgetMetadata.warningThreshold
  readonly property bool isLowBattery: !charging && percent <= warningThreshold

  // Test mode
  readonly property bool testMode: false
  readonly property int testPercent: 15
  readonly property bool testCharging: false

  // Main properties
  readonly property var battery: UPower.displayDevice
  readonly property bool isReady: testMode ? true : (battery && battery.ready && battery.isLaptopBattery && battery.isPresent)
  readonly property real percent: testMode ? testPercent : (isReady ? (battery.percentage * 100) : 0)
  readonly property bool charging: testMode ? testCharging : (isReady ? battery.state === UPowerDeviceState.Charging : false)
  property bool hasNotifiedLowBattery: false

  implicitWidth: pill.width
  implicitHeight: pill.height

  // Helper to evaluate and possibly notify
  function maybeNotify(percent, charging) {
    // Only notify once we are a below threshold
    if (!charging && !root.hasNotifiedLowBattery && percent <= warningThreshold) {
      root.hasNotifiedLowBattery = true;
      ToastService.showWarning(I18n.tr("toast.battery.low"), I18n.tr("toast.battery.low-desc", {
                                                                       "percent": Math.round(percent)
                                                                     }));
    } else if (root.hasNotifiedLowBattery && (charging || percent > warningThreshold + 5)) {
      // Reset when charging starts or when battery recovers 5% above threshold
      root.hasNotifiedLowBattery = false;
    }
  }

  // Watch for battery changes
  Connections {
    target: UPower.displayDevice
    function onPercentageChanged() {
      var currentPercent = UPower.displayDevice.percentage * 100;
      var isCharging = UPower.displayDevice.state === UPowerDeviceState.Charging;
      root.maybeNotify(currentPercent, isCharging);
    }

    function onStateChanged() {
      var isCharging = UPower.displayDevice.state === UPowerDeviceState.Charging;
      // Reset notification flag when charging starts
      if (isCharging) {
        root.hasNotifiedLowBattery = false;
      }
      // Also re-evaluate maybeNotify, as state might have changed
      var currentPercent = UPower.displayDevice.percentage * 100;
      root.maybeNotify(currentPercent, isCharging);
    }
  }

  NPopupContextMenu {
    id: contextMenu

    model: [
      {
        "label": I18n.tr("context-menu.widget-settings"),
        "action": "widget-settings",
        "icon": "settings"
      },
    ]

    onTriggered: action => {
                   var popupMenuWindow = PanelService.getPopupMenuWindow(screen);
                   if (popupMenuWindow) {
                     popupMenuWindow.close();
                   }

                   if (action === "widget-settings") {
                     BarService.openWidgetSettings(screen, section, sectionWidgetIndex, widgetId, widgetSettings);
                   }
                 }
  }

  BarPill {
    id: pill

    screen: root.screen
    density: Settings.data.bar.density
    oppositeDirection: BarService.getPillDirection(root)
    icon: testMode ? BatteryService.getIcon(testPercent, testCharging, true) : BatteryService.getIcon(percent, charging, isReady)
    text: (isReady || testMode) ? Math.round(percent) : "-"
    suffix: "%"
    autoHide: false
    forceOpen: isReady && (testMode || battery.isLaptopBattery) && displayMode === "alwaysShow"
    forceClose: displayMode === "alwaysHide" || !isReady || (!testMode && !battery.isLaptopBattery)
    customBackgroundColor: isLowBattery ? Color.mError : Qt.rgba(0, 0, 0, 0)
    customTextIconColor: isLowBattery ? Color.mOnError : charging ? Color.mPrimary : Qt.rgba(0, 0, 0, 0)

    tooltipText: {
      let lines = [];
      if (testMode) {
        lines.push(`Time left: ${Time.formatVagueHumanReadableDuration(12345)}.`);
        return lines.join("\n");
      }
      if (!isReady || !battery.isLaptopBattery) {
        return I18n.tr("battery.no-battery-detected");
      }
      if (battery.timeToEmpty > 0) {
        lines.push(I18n.tr("battery.time-left", {
                             "time": Time.formatVagueHumanReadableDuration(battery.timeToEmpty)
                           }));
      }
      if (battery.timeToFull > 0) {
        lines.push(I18n.tr("battery.time-until-full", {
                             "time": Time.formatVagueHumanReadableDuration(battery.timeToFull)
                           }));
      }
      if (battery.changeRate !== undefined) {
        const rate = battery.changeRate;
        if (rate > 0) {
          lines.push(charging ? I18n.tr("battery.charging-rate", {
                                          "rate": rate.toFixed(2)
                                        }) : I18n.tr("battery.discharging-rate", {
                                                       "rate": rate.toFixed(2)
                                                     }));
        } else if (rate < 0) {
          lines.push(I18n.tr("battery.discharging-rate", {
                               "rate": Math.abs(rate).toFixed(2)
                             }));
        } else {
          // Rate is 0 - check if plugged in (charging state) or idle
          lines.push(charging ? I18n.tr("battery.plugged-in") : I18n.tr("battery.idle"));
        }
      } else {
        lines.push(charging ? I18n.tr("battery.charging") : I18n.tr("battery.discharging"));
      }
      if (battery.healthPercentage !== undefined && battery.healthPercentage > 0) {
        lines.push(I18n.tr("battery.health", {
                             "percent": Math.round(battery.healthPercentage)
                           }));
      }
      return lines.join("\n");
    }
    onClicked: PanelService.getPanel("batteryPanel", screen)?.toggle(this)
    onRightClicked: {
      var popupMenuWindow = PanelService.getPopupMenuWindow(screen);
      if (popupMenuWindow) {
        const pos = BarService.getContextMenuPosition(pill, contextMenu.implicitWidth, contextMenu.implicitHeight);
        contextMenu.openAtItem(pill, pos.x, pos.y);
        popupMenuWindow.showContextMenu(contextMenu);
      }
    }
  }
}
