import QtQuick
import ZShell.Components
import ZShell.Config
import ZShell.Llm
import qs.Effects
import qs.Components
import qs.Services

CustomClippingRect {
	id: root

	property bool expanded: false
	property bool highlighted: false
	property bool slim: false
	required property ChatSession modelData

	signal clicked(content: ChatSession)
	signal remove(content: ChatSession)

	color: highlighted ? Qt.alpha(Colors.palette.m3primaryContainer, 0.3) : Qt.alpha(Colors.tPalette.m3surfaceContainer, 0.2)
	implicitHeight: {
		let h = 0;

		if (slim)
			return chatIcon.implicitHeight + chatIcon.anchors.topMargin * 2;

		h += infoContainer.implicitHeight;

		if (expanded)
			h += body.implicitHeight + body.topMargin + actionRow.implicitHeight + actionRow.anchors.topMargin;
		else
			h += preview.implicitHeight + preview.topMargin;

		h += Tokens.padding.small;

		const icon = chatIcon.implicitHeight + chatIcon.anchors.topMargin * 2;
		if (h < icon)
			return icon;
		return h;
	}
	radius: Tokens.rounding.large
	clip: true

	CustomRect {
		id: borderHighlight

		anchors.fill: parent
		border.width: root.highlighted ? 2 : 0
		border.color: Colors.palette.m3secondary
		radius: root.radius - border.width + 1

		Behavior on border.width {
			Anim {}
		}
	}

	Behavior on implicitHeight {
		enabled: titleText.readOnly

		Anim {}
	}

	MaterialIcon {
		id: chatIcon

		anchors.left: parent.left
		anchors.leftMargin: Tokens.padding.large
		anchors.top: parent.top
		anchors.topMargin: Tokens.padding.large
		font.pointSize: Tokens.font.size.extraLarge
		text: root.modelData.icon || "check"
		color: Colors.palette.m3onSurface
	}

	Item {
		id: infoContainer

		anchors.left: chatIcon.right
		anchors.leftMargin: Tokens.spacing.medium
		anchors.top: parent.top
		anchors.right: expandBtn.left
		anchors.rightMargin: Tokens.spacing.medium
		implicitHeight: {
			let h = 0;
			h += title.implicitHeight + title.anchors.topMargin;
			h += timestamp.implicitHeight + timestamp.anchors.topMargin;
			if (root.expanded)
				h += created.implicitHeight + created.anchors.topMargin;
			return h;
		}

		opacity: root.slim ? 0 : 1

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

		CustomRect {
			id: title

			anchors.left: parent.left
			anchors.topMargin: Tokens.padding.extraSmall
			anchors.top: parent.top
			color: Colors.layer(Colors.palette.m3surfaceContainerHighest, 1)
			implicitHeight: titleText.implicitHeight + Tokens.padding.extraSmall * 2
			radius: Tokens.rounding.full
			implicitWidth: titleText.implicitWidth + Tokens.padding.large * 2
			opacity: titleText.readOnly ? 0 : 1

			Behavior on opacity {
				Anim {}
			}
		}

		Item {
			id: titleWrapper

			anchors.left: parent.left
			anchors.top: parent.top
			anchors.right: parent.right
			implicitHeight: titleText.implicitHeight + Tokens.padding.small * 2

			layer.enabled: true
			layer.effect: OpacityMask {
				maskSource: fadeMask
			}

			TextFieldBase {
				id: titleText

				anchors.left: parent.left
				anchors.leftMargin: readOnly ? 0 : Tokens.padding.large
				anchors.top: parent.top
				anchors.topMargin: readOnly ? Tokens.padding.small : Tokens.padding.extraSmall * 2
				font.pointSize: Tokens.font.size.normal
				text: root.modelData.title || qsTr("New chat")
				readOnly: true
				color: Colors.palette.m3onSurface

				Behavior on anchors.leftMargin {
					Anim {}
				}
				Behavior on anchors.topMargin {
					Anim {}
				}

				onEditingFinished: root.modelData.title = text
				onReadOnlyChanged: {
					if (!readOnly) {
						this.forceActiveFocus();
						cursorPosition = text.length;
					} else {
						root.forceActiveFocus();
					}
				}
			}
		}

		CustomRect {
			id: fadeMask

			// anchors.top: titleText.top
			// anchors.bottom: titleText.bottom
			// anchors.left: titleText.left
			// anchors.right: parent.right
			anchors.fill: titleWrapper

			layer.enabled: true
			visible: false

			gradient: Gradient {
				orientation: Gradient.Horizontal

				GradientStop {
					color: Qt.rgba(1, 1, 1, 1.0)
					position: 0.85
				}

				GradientStop {
					color: Qt.rgba(1, 1, 1, 0)
					position: 1.0
				}
			}
		}

		CustomText {
			id: created

			anchors.top: title.bottom
			anchors.topMargin: Tokens.spacing.extraSmall
			anchors.left: parent.left
			anchors.right: parent.right
			font.pointSize: Tokens.font.size.small
			color: Colors.palette.m3onSurfaceVariant
			text: qsTr("Created on: %1").arg(root.modelData.createdAt.toLocaleString(Qt.locale("en_US"), "MMM d, yyyy - h:mm AP"))
			opacity: root.expanded ? 1 : 0

			Behavior on opacity {
				Anim {}
			}
		}

		CustomText {
			id: updated

			anchors.top: created.bottom
			anchors.topMargin: Tokens.spacing.small
			anchors.left: parent.left
			font.pointSize: Tokens.font.size.small
			color: Colors.palette.m3onSurfaceVariant
			text: qsTr("Updated on: ")
			opacity: root.expanded ? 1 : 0

			Behavior on opacity {
				Anim {}
			}
		}

		CustomText {
			id: timestamp

			anchors.left: parent.left
			anchors.top: title.bottom
			anchors.topMargin: Tokens.spacing.extraSmall
			color: Colors.palette.m3onSurfaceVariant
			font.pointSize: Tokens.font.size.small
			text: root.modelData.updatedAt.toLocaleString(Qt.locale("en_US"), "MMM d, yyyy - h:mm AP")

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

				AnchorChanges {
					target: timestamp
					anchors.left: updated.right
					anchors.top: undefined
					anchors.verticalCenter: updated.verticalCenter
				}
			}
			transitions: Transition {
				AnchorAnim {}
			}
		}
	}

	CustomText {
		id: preview

		readonly property int topMargin: Tokens.spacing.extraSmall

		anchors.left: chatIcon.right
		anchors.margins: Tokens.spacing.medium
		anchors.right: parent.right
		y: infoContainer.implicitHeight + topMargin
		elide: Text.ElideRight
		color: Colors.palette.m3onSurfaceVariant
		font.pointSize: Tokens.font.size.small
		maximumLineCount: 1
		opacity: !root.expanded && !root.slim ? 1 : 0
		text: root.modelData.messagesModel.lastMessage?.activeGeneration.content.replace(/\s+/g, " ").trim() ?? qsTr("No messages yet")

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

	CustomText {
		id: body

		readonly property int topMargin: root.expanded ? Tokens.spacing.medium : Tokens.spacing.extraSmall

		anchors.left: chatIcon.right
		anchors.margins: Tokens.spacing.medium
		anchors.right: parent.right
		y: infoContainer.implicitHeight + topMargin
		animate: true
		color: Colors.palette.m3onSurfaceVariant
		maximumLineCount: 5
		opacity: root.expanded ? 1 : 0
		text: root.modelData.messagesModel.lastMessage?.activeGeneration.content ?? qsTr("No messages yet")
		wrapMode: Text.WrapAtWordBoundaryOrAnywhere

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

	StateLayer {
		id: sLayer

		property int startY

		onClicked: {
			root.clicked(root.modelData);
		}
	}

	ButtonRow {
		id: actionRow

		anchors.top: body.bottom
		anchors.left: chatIcon.right
		anchors.right: parent.right
		anchors.topMargin: Tokens.spacing.small
		anchors.leftMargin: Tokens.spacing.medium
		anchors.rightMargin: Tokens.padding.medium
		spacing: Tokens.spacing.medium

		IconButton {
			icon: "close"
			fillWidth: true
			shapeMorph: true
			isRound: true
			font.pointSize: Tokens.font.size.large
			inactiveColor: Colors.layer(Colors.palette.m3surfaceContainerHighest, 3)
			inactiveOnColor: Colors.palette.m3onSurfaceVariant

			onClicked: root.remove(root.modelData)
		}

		IconButton {
			icon: titleText.readOnly ? "edit" : "check"
			label.animate: true
			isToggle: true
			fillWidth: true
			shapeMorph: true
			font.pointSize: Tokens.font.size.large
			isRound: true
			inactiveColor: Colors.layer(Colors.palette.m3surfaceContainerHighest, 3)
			inactiveOnColor: Colors.palette.m3onSurfaceVariant
			activeColor: Colors.palette.m3secondary
			activeOnColor: Colors.palette.m3onSecondary
			checked: !titleText.readOnly

			onClicked: titleText.readOnly = !titleText.readOnly
		}
	}

	CustomRect {
		id: expandBtn

		anchors.right: parent.right
		anchors.top: parent.top
		anchors.margins: Tokens.padding.small
		implicitHeight: expandIcon.implicitHeight
		implicitWidth: expandIcon.implicitHeight
		radius: Tokens.rounding.full
		color: Colors.layer(Colors.palette.m3surfaceContainerHighest, 3)

		opacity: root.slim ? 0 : 1
		visible: opacity > 0
		enabled: visible

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

		StateLayer {
			onClicked: root.expanded = !root.expanded
		}

		MaterialIcon {
			id: expandIcon

			anchors.centerIn: parent
			anchors.verticalCenterOffset: root.expanded ? -1 : 1
			rotation: root.expanded ? 180 : 0
			color: Colors.palette.m3onSurface
			text: "expand_more"

			Behavior on anchors.verticalCenterOffset {
				Anim {}
			}
			Behavior on rotation {
				Anim {}
			}
		}
	}
}
