pragma ComponentBehavior: Bound

import Quickshell
import QtQuick
import QtQuick.Layouts
import qs.Components
import ZShell.Config
import qs.Helpers
import qs.Services

CustomRect {
	id: root

	required property var props
	required property PersistentProperties visibilities

	Layout.fillWidth: true
	color: Colors.tPalette.m3surfaceContainer
	implicitHeight: layout.implicitHeight + layout.anchors.margins * 2
	radius: Tokens.rounding.small

	ColumnLayout {
		id: layout

		anchors.fill: parent
		anchors.margins: Tokens.padding.large
		spacing: Tokens.spacing.medium

		RowLayout {
			spacing: Tokens.spacing.medium
			z: 1

			CustomRect {
				color: Recorder.running ? Colors.palette.m3secondary : Colors.palette.m3secondaryContainer
				implicitHeight: {
					const h = icon.implicitHeight + Tokens.padding.small * 2;
					return h - (h % 2);
				}
				implicitWidth: implicitHeight
				radius: Tokens.rounding.full

				MaterialIcon {
					id: icon

					anchors.centerIn: parent
					anchors.horizontalCenterOffset: -0.5
					anchors.verticalCenterOffset: 1.5
					color: Recorder.running ? Colors.palette.m3onSecondary : Colors.palette.m3onSecondaryContainer
					font.pointSize: Tokens.font.size.large
					text: "screen_record"
				}
			}

			ColumnLayout {
				Layout.fillWidth: true
				spacing: 0

				CustomText {
					Layout.fillWidth: true
					elide: Text.ElideRight
					font.pointSize: Tokens.font.size.normal
					text: qsTr("Screen Recorder")
				}

				CustomText {
					Layout.fillWidth: true
					color: Colors.palette.m3onSurfaceVariant
					elide: Text.ElideRight
					font.pointSize: Tokens.font.size.small
					text: Recorder.paused ? qsTr("Recording paused") : Recorder.running ? qsTr("Recording running") : qsTr("Recording off")
				}
			}

			SplitButton {
				active: menuItems.find(m => root.props.recordingMode === m.icon + m.text) ?? menuItems[0]
				enabled: !Recorder.running
				menuOnTop: true

				menuItems: [
					MenuItem {
						activeText: qsTr("Fullscreen")
						icon: "fullscreen"
						text: qsTr("Record fullscreen")

						onClicked: Recorder.start()
					},
					MenuItem {
						activeText: qsTr("Region")
						icon: "screenshot_region"
						text: qsTr("Record region")

						onClicked: Recorder.start(["-r"])
					},
					MenuItem {
						activeText: qsTr("Fullscreen")
						icon: "select_to_speak"
						text: qsTr("Record fullscreen with sound")

						onClicked: Recorder.start(["-s"])
					},
					MenuItem {
						activeText: qsTr("Region")
						icon: "volume_up"
						text: qsTr("Record region with sound")

						onClicked: Recorder.start(["-s", "-r"])
					}
				]

				menu.onItemSelected: item => root.props.recordingMode = item.icon + item.text
			}
		}

		Loader {
			id: listOrControls

			property bool running: Recorder.running

			Layout.fillWidth: true
			Layout.preferredHeight: implicitHeight
			asynchronous: true
			sourceComponent: running ? recordingControls : recordingList

			Behavior on Layout.preferredHeight {
				id: locHeightAnim

				enabled: false

				Anim {
				}
			}
			Behavior on running {
				SequentialAnimation {
					ParallelAnimation {
						Anim {
							duration: Tokens.anim.durations.small
							easing: Tokens.anim.standardAccel
							property: "scale"
							target: listOrControls
							to: 0.7
						}

						Anim {
							duration: Tokens.anim.durations.small
							easing: Tokens.anim.standardAccel
							property: "opacity"
							target: listOrControls
							to: 0
						}
					}

					PropertyAction {
						property: "enabled"
						target: locHeightAnim
						value: true
					}

					PropertyAction {
					}

					PropertyAction {
						property: "enabled"
						target: locHeightAnim
						value: false
					}

					ParallelAnimation {
						Anim {
							duration: Tokens.anim.durations.small
							easing: Tokens.anim.standardDecel
							property: "scale"
							target: listOrControls
							to: 1
						}

						Anim {
							duration: Tokens.anim.durations.small
							easing: Tokens.anim.standardDecel
							property: "opacity"
							target: listOrControls
							to: 1
						}
					}
				}
			}
		}
	}

	Component {
		id: recordingList

		RecordingList {
			props: root.props
			visibilities: root.visibilities
		}
	}

	Component {
		id: recordingControls

		RowLayout {
			spacing: Tokens.spacing.medium

			CustomRect {
				color: Recorder.paused ? Colors.palette.m3tertiary : Colors.palette.m3error
				implicitHeight: recText.implicitHeight + Tokens.padding.small * 2
				implicitWidth: recText.implicitWidth + Tokens.padding.small * 2
				radius: Tokens.rounding.full

				Behavior on implicitWidth {
					Anim {
					}
				}
				SequentialAnimation on opacity {
					alwaysRunToEnd: true
					loops: Animation.Infinite
					running: !Recorder.paused

					Anim {
						duration: Tokens.anim.durations.large
						easing: Tokens.anim.emphasizedAccel
						from: 1
						to: 0
					}

					Anim {
						duration: Tokens.anim.durations.extraLarge
						easing: Tokens.anim.emphasizedDecel
						from: 0
						to: 1
					}
				}

				CustomText {
					id: recText

					anchors.centerIn: parent
					animate: true
					color: Recorder.paused ? Colors.palette.m3onTertiary : Colors.palette.m3onError
					font.family: Config.appearance.font.family.mono
					text: Recorder.paused ? "PAUSED" : "REC"
				}
			}

			CustomText {
				font.pointSize: Tokens.font.size.normal
				text: {
					const elapsed = Recorder.elapsed;

					const hours = Math.floor(elapsed / 3600);
					const mins = Math.floor((elapsed % 3600) / 60);
					const secs = Math.floor(elapsed % 60).toString().padStart(2, "0");

					let time;
					if (hours > 0)
						time = `${hours}:${mins.toString().padStart(2, "0")}:${secs}`;
					else
						time = `${mins}:${secs}`;

					return qsTr("Recording for %1").arg(time);
				}
			}

			Item {
				Layout.fillWidth: true
			}

			IconButton {
				checked: Recorder.paused
				font.pointSize: Tokens.font.size.large
				icon: Recorder.paused ? "play_arrow" : "pause"
				isToggle: true
				label.animate: true
				type: IconButton.Tonal

				onClicked: {
					Recorder.togglePause();
					internalChecked = Recorder.paused;
				}
			}

			IconButton {
				font.pointSize: Tokens.font.size.large
				icon: "stop"
				inactiveColor: Colors.palette.m3error
				inactiveOnColor: Colors.palette.m3onError

				onClicked: Recorder.stop()
			}
		}
	}
}
