pragma ComponentBehavior: Bound

import QtQuick
import QtQuick.Layouts
import ZShell.Blobs
import qs.Components
import ZShell.Config
import qs.Services

Item {
	id: root

	property bool acceptAllowed: true
	required property string acceptLabel
	required property Component content
	required property string header
	property int horizontalContentMargin
	property string icon
	required property string label
	property alias iconLabel: openButton.iconText
	property alias rowButton: openButton
	property alias contentItem: dialogContent.item
	property string subtext: ""
	property bool open
	property real openHeight: Math.min(rootParent.height * 0.8, 400)
	property real openWidth: Math.min(rootParent.width * 0.8, 600)
	required property Item rootParent
	property bool first: false
	property bool last: false
	required property string settingAnchor
	property color openColor: Colors.palette.m3surfaceContainerHighest

	signal accepted
	signal cancelled

	function reparentWrapper(): void {
		const newParent = open ? rootParent : root;
		const pos = dialogWrapper.mapToItem(newParent, 0, 0);
		dialogWrapper.parent = newParent;
		dialogWrapper.x = pos.x;
		dialogWrapper.y = pos.y;
	}

	Layout.fillWidth: true
	implicitHeight: openButton.implicitHeight
	z: open || dialogTransition.running ? 2 : 0

	BlobGroup {
		id: blobGroup

		color: root.open ? root.openColor : Colors.tPalette.m3surfaceContainer

		Behavior on color {
			CAnim {}
		}
	}

	MouseArea {
		id: backdrop

		anchors.fill: parent
		enabled: false
		hoverEnabled: enabled
		preventStealing: true
		parent: root.open ? root.rootParent : root

		onClicked: root.open = false
	}

	Item {
		id: dialogWrapper

		height: openButton.implicitHeight
		width: root.width
		z: 1

		states: State {
			name: "open"
			when: root.open

			PropertyChanges {
				backdrop.enabled: true
				dialogBg.bottomLeftRadius: Tokens.rounding.largeIncreased
				dialogBg.bottomRightRadius: Tokens.rounding.largeIncreased
				dialogBg.topRightRadius: Tokens.rounding.largeIncreased
				dialogBg.topLeftRadius: Tokens.rounding.largeIncreased
				dialogContent.opacity: 1
				dialogWrapper.height: root.openHeight
				dialogWrapper.width: root.openWidth
				dialogWrapper.x: (root.rootParent.width - root.openWidth) / 2
				dialogWrapper.y: (root.rootParent.height - root.openHeight) / 2
				elevation.opacity: 1
				openButton.opacity: 0
			}
		}
		transitions: Transition {
			id: dialogTransition

			SequentialAnimation {
				ScriptAction {
					script: root.reparentWrapper()
				}

				Anim {
					properties: "x,y"
				}
			}

			PropertyAction {
				property: "enabled"
			}

			Anim {
				properties: "opacity,topLeftRadius,topRightRadius,bottomLeftRadius,bottomRightRadius"
				type: Anim.DefaultEffects
			}

			Anim {
				properties: "width,height"
			}
		}

		Elevation {
			id: elevation

			anchors.fill: parent
			bottomLeftRadius: dialogBg.bottomLeftRadius
			bottomRightRadius: dialogBg.bottomRightRadius
			level: 4
			opacity: 0
			radius: dialogBg.radius

			transform: Matrix4x4 {
				matrix: dialogBg.deformMatrix
			}
		}

		BlobRect {
			id: dialogBg

			anchors.fill: parent
			bottomLeftRadius: root.last ? Tokens.rounding.largeIncreased : Tokens.rounding.extraSmall
			bottomRightRadius: root.last ? Tokens.rounding.largeIncreased : Tokens.rounding.extraSmall
			topRightRadius: root.first ? Tokens.rounding.largeIncreased : Tokens.rounding.extraSmall
			topLeftRadius: root.first ? Tokens.rounding.largeIncreased : Tokens.rounding.extraSmall
			deformScale: 0
			group: blobGroup
			opacity: blobGroup.color.a * (root.enabled ? 1 : 0.5)
		}

		TimeDialogToggle {
			id: openButton

			anchors.left: parent.left
			anchors.right: parent.right
			color: "transparent"
			height: Math.min(implicitHeight, parent.height)
			subtext: root.subtext
			last: root.last
			first: root.first
			text: root.label

			transform: Matrix4x4 {
				matrix: dialogBg.deformMatrix
			}

			onClicked: root.open = true
		}

		Loader {
			id: dialogContent

			active: opacity > 0
			anchors.fill: parent
			asynchronous: false
			opacity: 0

			sourceComponent: MouseArea {
				onWheel: event => event.accepted = true
				preventStealing: true
				clip: true
				implicitWidth: innerLayout.implicitWidth + innerLayout.anchors.margins * 2
				implicitHeight: innerLayout.implicitHeight + innerLayout.anchors.margins + innerLayout.anchors.bottomMargin

				ColumnLayout {
					id: innerLayout
					anchors.bottomMargin: Tokens.padding.largeIncreased
					anchors.fill: parent
					anchors.margins: Tokens.padding.extraLarge
					spacing: 0

					CustomText {
						font.pointSize: Tokens.font.size.large
						text: root.header
					}

					Loader {
						Layout.fillWidth: true
						Layout.leftMargin: root.horizontalContentMargin
						Layout.topMargin: Tokens.spacing.medium
						Layout.bottomMargin: Tokens.spacing.medium
						Layout.rightMargin: root.horizontalContentMargin
						sourceComponent: root.content
					}

					RowLayout {
						Layout.alignment: Qt.AlignRight
						spacing: Tokens.spacing.extraSmall

						TextButton {
							horizontalPadding: Tokens.padding.largeIncreased
							isRound: true
							text: qsTr("Cancel")
							type: TextButton.Text
							verticalPadding: Tokens.padding.small
							stateLayer.preventStealing: true

							onClicked: {
								root.cancelled();
								root.open = false;
							}
						}

						TextButton {
							enabled: root.acceptAllowed
							horizontalPadding: Tokens.padding.largeIncreased
							isRound: true
							text: root.acceptLabel
							type: TextButton.Text
							stateLayer.preventStealing: true
							verticalPadding: Tokens.padding.small

							onClicked: {
								root.accepted();
								root.open = false;
							}
						}
					}
				}
			}
			transform: Matrix4x4 {
				matrix: dialogBg.deformMatrix
			}
		}
	}
}
