pragma ComponentBehavior: Bound

import QtQuick
import QtQuick.Layouts
import Quickshell.Services.UPower
import ZShell.Config
import qs.Modules.Bar.Components.Common
import qs.Helpers
import qs.Components
import qs.Services

Column {
	id: root

	required property bool horizontal
	readonly property int panelRadius: ((profiles.height / 2) + Tokens.padding.extraSmall) * Tokens.rounding.scale

	spacing: Tokens.spacing.medium

	Loader {
		active: Battery.isLaptop

		CustomText {
			text: qsTr("Remaining: %1%").arg(Math.round(UPower.displayDevice.percentage * 100))
		}
	}

	Item {
		id: padding

		implicitHeight: root.horizontal ? 0 : Tokens.padding.small
		implicitWidth: 1
	}

	Repeater {
		model: Battery.allPeripherals

		RowLayout {
			id: layout

			required property var modelData

			anchors.left: parent.left
			anchors.leftMargin: Tokens.padding.small
			anchors.right: parent.right
			anchors.rightMargin: Tokens.padding.small

			CustomText {
				Layout.fillWidth: true
				text: layout.modelData.model
			}

			BatteryIcon {
				devState: layout.modelData.state
				percentage: layout.modelData.percentage
			}
		}
	}

	CustomText {
		function formatSeconds(s: int, fallback: string): string {
			const day = Math.floor(s / 86400);
			const hr = Math.floor(s / 3600) % 60;
			const min = Math.floor(s / 60) % 60;

			let comps = [];
			if (day > 0)
				comps.push(`${day} days`);
			if (hr > 0)
				comps.push(`${hr} hours`);
			if (min > 0)
				comps.push(`${min} mins`);

			return comps.join(", ") || fallback;
		}

		anchors.left: parent.left
		anchors.leftMargin: Tokens.padding.small
		text: Battery.isLaptop ? qsTr("Time %1: %2").arg(Battery.onBattery ? "remaining" : "until charged").arg(Battery.onBattery ? formatSeconds(Battery.timeToEmpty, "Calculating...") : formatSeconds(Battery.timeToFull, "Fully charged!")) : qsTr("Power profile: %1").arg(PowerProfile.toString(PowerProfiles.profile))
	}

	Loader {
		active: PowerProfiles.degradationReason !== PerformanceDegradationReason.None
		anchors.horizontalCenter: parent.horizontalCenter
		asynchronous: true
		height: active ? ((item as Item)?.implicitHeight ?? 0) : 0

		sourceComponent: CustomRect {
			color: Colors.palette.m3error
			implicitHeight: child.implicitHeight + Tokens.padding.large
			implicitWidth: child.implicitWidth + Tokens.padding.small * 2
			radius: Tokens.rounding.largeIncreased

			Column {
				id: child

				anchors.centerIn: parent

				Row {
					anchors.horizontalCenter: parent.horizontalCenter
					spacing: Tokens.spacing.small

					MaterialIcon {
						anchors.verticalCenter: parent.verticalCenter
						anchors.verticalCenterOffset: -font.pointSize / 10
						color: Colors.palette.m3onError
						text: "warning"
					}

					CustomText {
						anchors.verticalCenter: parent.verticalCenter
						color: Colors.palette.m3onError
						font.family: Config.appearance.font.family.mono
						text: qsTr("Performance Degraded")
					}

					MaterialIcon {
						anchors.verticalCenter: parent.verticalCenter
						anchors.verticalCenterOffset: -font.pointSize / 10
						color: Colors.palette.m3onError
						text: "warning"
					}
				}

				CustomText {
					anchors.horizontalCenter: parent.horizontalCenter
					color: Colors.palette.m3onError
					text: qsTr("Reason: %1").arg(PerformanceDegradationReason.toString(PowerProfiles.degradationReason))
				}
			}
		}
	}

	CustomRect {
		id: profiles

		property string current: {
			const p = PowerProfiles.profile;
			if (p === PowerProfile.PowerSaver)
				return saver.icon;
			if (p === PowerProfile.Performance)
				return perf.icon;
			return balance.icon;
		}

		anchors.horizontalCenter: parent.horizontalCenter
		color: Colors.tPalette.m3surfaceContainer
		implicitHeight: indicator.height + Tokens.padding.extraSmall * 2
		implicitWidth: saver.implicitHeight + balance.implicitHeight + perf.implicitHeight + Tokens.padding.small * 2 + Tokens.spacing.small * 8
		radius: Tokens.rounding.full

		CustomRect {
			id: indicator

			color: Colors.palette.m3primary
			radius: Tokens.rounding.full
			state: profiles.current

			states: [
				State {
					name: saver.icon

					Fill {
						item: saver
					}
				},
				State {
					name: balance.icon

					Fill {
						item: balance
					}
				},
				State {
					name: perf.icon

					Fill {
						item: perf
					}
				}
			]
			transitions: Transition {
				AnchorAnim {
				}
			}
		}

		Profile {
			id: saver

			anchors.left: parent.left
			anchors.leftMargin: Tokens.padding.extraSmall
			anchors.verticalCenter: parent.verticalCenter
			icon: "energy_savings_leaf"
			profile: PowerProfile.PowerSaver
		}

		Profile {
			id: balance

			anchors.centerIn: parent
			icon: "balance"
			profile: PowerProfile.Balanced
		}

		Profile {
			id: perf

			anchors.right: parent.right
			anchors.rightMargin: Tokens.padding.extraSmall
			anchors.verticalCenter: parent.verticalCenter
			icon: "bolt"
			profile: PowerProfile.Performance
		}
	}

	component Fill: AnchorChanges {
		required property Item item

		anchors.bottom: item.bottom
		anchors.left: item.left
		anchors.right: item.right
		anchors.top: item.top
		target: indicator
	}
	component Profile: Item {
		required property string icon
		required property int profile

		implicitHeight: icon.implicitHeight + Tokens.padding.extraSmall
		implicitWidth: icon.implicitHeight + Tokens.padding.extraSmall

		StateLayer {
			color: profiles.current === parent.icon ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
			radius: Tokens.rounding.full

			onClicked: {
				PowerProfiles.profile = parent.profile;
			}
		}

		MaterialIcon {
			id: icon

			anchors.centerIn: parent
			color: profiles.current === text ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
			fill: profiles.current === text ? 1 : 0
			font.pointSize: Tokens.font.size.large * 2
			grade: Colors.light ? 0 : (text === "balance" ? -25 : 0)
			text: parent.icon

			Behavior on fill {
				Anim {
					type: Anim.DefaultEffects
				}
			}
		}
	}
}
