pragma ComponentBehavior: Bound

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

Item {
	id: root

	property string buffer
	required property var greeter
	readonly property alias placeholder: placeholder

	Layout.fillHeight: true
	Layout.fillWidth: true
	clip: true

	Connections {
		function onBufferChanged(): void {
			if (root.greeter.buffer.length > root.buffer.length) {
				charList.bindImWidth();
			} else if (root.greeter.buffer.length === 0) {
				charList.implicitWidth = charList.implicitWidth;
				placeholder.animate = true;
			}

			root.buffer = root.greeter.buffer;
		}

		target: root.greeter
	}

	CustomText {
		id: placeholder

		anchors.centerIn: parent
		animate: true
		color: root.greeter.launching ? Colors.palette.m3secondary : Colors.palette.m3outline
		font.family: Config.appearance.font.family.mono
		font.pointSize: Tokens.font.size.normal
		opacity: root.buffer ? 0 : 1
		text: {
			if (root.greeter.launching)
				return qsTr("Starting session...");
			if (root.greeter.awaitingResponse && root.greeter.promptMessage)
				return root.greeter.promptMessage;
			return qsTr("Enter your password");
		}

		Behavior on opacity {
			Anim {
			}
		}
	}

	CustomText {
		id: visibleBufferText

		anchors.left: parent.left
		anchors.right: parent.right
		anchors.verticalCenter: parent.verticalCenter
		color: Colors.palette.m3onSurface
		elide: Text.ElideLeft
		font.family: Config.appearance.font.family.mono
		font.pointSize: Tokens.font.size.normal
		horizontalAlignment: Qt.AlignHCenter
		opacity: root.greeter.echoResponse && root.buffer ? 1 : 0
		text: root.buffer

		Behavior on opacity {
			Anim {
			}
		}
	}

	ListView {
		id: charList

		readonly property int fullWidth: count * (implicitHeight + spacing) - spacing

		function bindImWidth(): void {
			imWidthBehavior.enabled = false;
			implicitWidth = Qt.binding(() => fullWidth);
			imWidthBehavior.enabled = true;
		}

		anchors.centerIn: parent
		anchors.horizontalCenterOffset: implicitWidth > root.width ? -(implicitWidth - root.width) / 2 : 0
		implicitHeight: Tokens.font.size.normal
		implicitWidth: fullWidth
		interactive: false
		opacity: root.greeter.echoResponse ? 0 : 1
		orientation: Qt.Horizontal
		spacing: Tokens.spacing.small / 2

		delegate: CustomRect {
			id: ch

			color: Colors.palette.m3onSurface
			implicitHeight: charList.implicitHeight
			implicitWidth: implicitHeight
			opacity: 0
			radius: Tokens.rounding.small / 2
			scale: 0

			Behavior on opacity {
				Anim {
				}
			}
			Behavior on scale {
				Anim {
					duration: Tokens.anim.durations.expressiveFastSpatial
					easing: Tokens.anim.expressiveFastSpatial
				}
			}

			Component.onCompleted: {
				opacity = 1;
				scale = 1;
			}
			ListView.onRemove: removeAnim.start()

			SequentialAnimation {
				id: removeAnim

				PropertyAction {
					property: "ListView.delayRemove"
					target: ch
					value: true
				}

				ParallelAnimation {
					Anim {
						property: "opacity"
						target: ch
						to: 0
					}

					Anim {
						property: "scale"
						target: ch
						to: 0.5
					}
				}

				PropertyAction {
					property: "ListView.delayRemove"
					target: ch
					value: false
				}
			}
		}
		Behavior on implicitWidth {
			id: imWidthBehavior

			Anim {
			}
		}
		model: ScriptModel {
			values: root.buffer.split("")
		}
		Behavior on opacity {
			Anim {
			}
		}
	}
}
