import QtQuick
import QtQuick.Shapes
import QtQuick.Templates
import ZShell.Config
import qs.Services

Switch {
	id: root

	property int cLayer: 1

	implicitHeight: implicitIndicatorHeight
	implicitWidth: implicitIndicatorWidth

	indicator: CustomRect {
		color: {
			if (!root.enabled)
				return root.checked ? Qt.alpha(Colors.palette.m3onSurface, 0.12) : Qt.alpha(Colors.palette.m3surfaceContainerHighest, 0.38);
			return root.checked ? Colors.palette.m3primary : Colors.layer(Colors.palette.m3surfaceContainerHighest, root.cLayer);
		}
		implicitHeight: 14 + Tokens.padding.small * 2
		implicitWidth: implicitHeight * 1.7
		radius: Tokens.rounding.full

		CustomRect {
			readonly property real nonAnimWidth: root.pressed ? implicitHeight * 1.2 : implicitHeight

			anchors.verticalCenter: parent.verticalCenter
			color: {
				if (!root.enabled)
					return root.checked ? Qt.alpha(Colors.palette.m3surface, 0.7) : Qt.alpha(Colors.palette.m3onSurface, 0.12);
				return root.checked ? Colors.palette.m3onPrimary : Colors.layer(Colors.palette.m3outline, root.cLayer + 1);
			}
			implicitHeight: parent.implicitHeight - Tokens.padding.extraSmall
			implicitWidth: nonAnimWidth
			radius: Tokens.rounding.full
			x: root.checked ? parent.implicitWidth - nonAnimWidth - Tokens.padding.extraSmall / 2 : Tokens.padding.extraSmall / 2

			Behavior on implicitWidth {
				Anim {
					type: Anim.FastSpatial
				}
			}
			Behavior on x {
				Anim {
					type: Anim.FastSpatial
				}
			}

			CustomRect {
				anchors.fill: parent
				color: root.checked && root.enabled ? Colors.palette.m3primary : Colors.palette.m3onSurface
				opacity: root.pressed ? 0.1 : root.hovered ? 0.08 : 0
				radius: parent.radius

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

			Shape {
				id: icon

				property point end1: {
					if (root.pressed) {
						if (root.checked)
							return Qt.point(width * 0.4, height / 2);
						return Qt.point(width * 0.8, height / 2);
					}
					if (root.checked)
						return Qt.point(width * 0.4, height * 0.7);
					return Qt.point(width * 0.85, height * 0.85);
				}
				property point end2: {
					if (root.pressed)
						return Qt.point(width * 0.8, height / 2);
					if (root.checked)
						return Qt.point(width * 0.85, height * 0.2);
					return Qt.point(width * 0.85, height * 0.15);
				}
				property point start1: {
					if (root.pressed)
						return Qt.point(width * 0.2, height / 2);
					if (root.checked)
						return Qt.point(width * 0.15, height / 2);
					return Qt.point(width * 0.15, height * 0.15);
				}
				property point start2: {
					if (root.pressed) {
						if (root.checked)
							return Qt.point(width * 0.4, height / 2);
						return Qt.point(width * 0.2, height / 2);
					}
					if (root.checked)
						return Qt.point(width * 0.4, height * 0.7);
					return Qt.point(width * 0.15, height * 0.85);
				}

				anchors.centerIn: parent
				asynchronous: true
				height: parent.implicitHeight - Tokens.padding.medium
				preferredRendererType: Shape.CurveRenderer
				width: height

				Behavior on end1 {
					PropAnim {
					}
				}
				Behavior on end2 {
					PropAnim {
					}
				}
				Behavior on start1 {
					PropAnim {
					}
				}
				Behavior on start2 {
					PropAnim {
					}
				}

				ShapePath {
					capStyle: Tokens.rounding.scale === 0 ? ShapePath.SquareCap : ShapePath.RoundCap
					fillColor: "transparent"
					startX: icon.start1.x
					startY: icon.start1.y
					strokeColor: {
						if (!root.enabled)
							return root.checked ? Colors.palette.m3outline : Colors.palette.m3surfaceContainer;
						return root.checked ? Colors.palette.m3primary : Colors.palette.m3surfaceContainerHighest;
					}
					strokeWidth: 16 * 0.15

					Behavior on strokeColor {
						CAnim {
						}
					}

					PathLine {
						x: icon.end1.x
						y: icon.end1.y
					}

					PathMove {
						x: icon.start2.x
						y: icon.start2.y
					}

					PathLine {
						x: icon.end2.x
						y: icon.end2.y
					}
				}
			}
		}
	}

	MouseArea {
		anchors.fill: parent
		cursorShape: Qt.PointingHandCursor
		enabled: false
	}

	component PropAnim: PropertyAnimation {
		duration: Tokens.anim.durations.expressiveFastSpatial
		easing: Tokens.anim.expressiveFastSpatial
	}
}
