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

Item {
	id: contextMenu

	property real menuX: 0
	property real menuY: 0
	property var targetAppEntry: null
	property string targetFilePath: ""
	property bool targetIsDir: false
	property var targetPaths: []

	signal openFileRequested(string path, bool isDir)
	signal renameRequested(string path)

	function close() {
		visible = false;
	}

	function openAt(mouseX, mouseY, path, isDir, appEnt, parentW, parentH, selectionArray) {
		targetFilePath = path;
		targetIsDir = isDir;
		targetAppEntry = appEnt;

		targetPaths = (selectionArray && selectionArray.length > 0) ? selectionArray : [path];

		menuX = Math.floor(Math.min(mouseX, parentW - popupBackground.implicitWidth));
		menuY = Math.floor(Math.min(mouseY, parentH - popupBackground.implicitHeight));

		visible = true;
	}

	anchors.fill: parent
	visible: false
	z: 999

	CustomClippingRect {
		id: popupBackground

		readonly property real padding: Tokens.padding.extraSmall

		color: Colors.tPalette.m3surface
		implicitHeight: menuLayout.implicitHeight + padding * 2
		implicitWidth: menuLayout.implicitWidth + padding * 2
		opacity: contextMenu.visible ? 1 : 0
		radius: Tokens.rounding.medium
		x: contextMenu.menuX
		y: contextMenu.menuY

		Behavior on opacity {
			Anim {
			}
		}

		ColumnLayout {
			id: menuLayout

			anchors.centerIn: parent
			spacing: 0

			CustomRect {
				Layout.preferredWidth: 160
				implicitHeight: openRow.implicitHeight + Tokens.padding.extraSmall * 2
				radius: popupBackground.radius - popupBackground.padding

				RowLayout {
					id: openRow

					anchors.fill: parent
					anchors.leftMargin: Tokens.padding.small
					spacing: 8

					MaterialIcon {
						font.pointSize: 20
						text: "open_in_new"
					}

					CustomText {
						Layout.fillWidth: true
						text: "Open"
					}
				}

				StateLayer {
					anchors.fill: parent

					onClicked: {
						for (let i = 0; i < contextMenu.targetPaths.length; i++) {
							let p = contextMenu.targetPaths[i];
							if (p === contextMenu.targetFilePath) {
								if (p.endsWith(".desktop") && contextMenu.targetAppEntry)
									contextMenu.targetAppEntry.execute();
								else
									contextMenu.openFileRequested(p, contextMenu.targetIsDir);
							} else {
								Quickshell.execDetached(["xdg-open", p]);
							}
						}
						contextMenu.close();
					}
				}
			}

			CustomRect {
				Layout.fillWidth: true
				implicitHeight: openWithRow.implicitHeight + Tokens.padding.extraSmall * 2
				radius: popupBackground.radius - popupBackground.padding

				RowLayout {
					id: openWithRow

					anchors.fill: parent
					anchors.leftMargin: Tokens.padding.small
					spacing: 8

					MaterialIcon {
						font.pointSize: 20
						text: contextMenu.targetIsDir ? "terminal" : "apps"
					}

					CustomText {
						Layout.fillWidth: true
						text: contextMenu.targetIsDir ? "Open in terminal" : "Open with..."
					}
				}

				StateLayer {
					anchors.fill: parent

					onClicked: {
						if (contextMenu.targetIsDir) {
							Quickshell.execDetached([Config.general.apps.terminal, "--working-directory", contextMenu.targetFilePath]);
						} else {
							Quickshell.execDetached(["xdg-open", contextMenu.targetFilePath]);
						}
						contextMenu.close();
					}
				}
			}

			CustomRect {
				Layout.bottomMargin: 4
				Layout.fillWidth: true
				Layout.topMargin: 4
				color: Colors.palette.m3outlineVariant
				implicitHeight: 1
			}

			CustomRect {
				Layout.fillWidth: true
				implicitHeight: copyPathRow.implicitHeight + Tokens.padding.extraSmall * 2
				radius: popupBackground.radius - popupBackground.padding

				RowLayout {
					id: copyPathRow

					anchors.fill: parent
					anchors.leftMargin: Tokens.padding.small
					spacing: 8

					MaterialIcon {
						font.pointSize: 20
						text: "content_copy"
					}

					CustomText {
						Layout.fillWidth: true
						text: "Copy path"
					}
				}

				StateLayer {
					anchors.fill: parent

					onClicked: {
						Quickshell.execDetached(["wl-copy", contextMenu.targetPaths.join("\n")]);
						contextMenu.close();
					}
				}
			}

			CustomRect {
				Layout.fillWidth: true
				implicitHeight: renameRow.implicitHeight + Tokens.padding.extraSmall * 2
				radius: popupBackground.radius - popupBackground.padding
				visible: contextMenu.targetPaths.length === 1

				RowLayout {
					id: renameRow

					anchors.fill: parent
					anchors.leftMargin: Tokens.padding.small
					spacing: 8

					MaterialIcon {
						font.pointSize: 20
						text: "edit"
					}

					CustomText {
						Layout.fillWidth: true
						text: "Rename"
					}
				}

				StateLayer {
					anchors.fill: parent

					onClicked: {
						contextMenu.renameRequested(contextMenu.targetFilePath);
						contextMenu.close();
					}
				}
			}

			Rectangle {
				Layout.bottomMargin: 4
				Layout.fillWidth: true
				Layout.topMargin: 4
				color: Colors.palette.m3outlineVariant
				implicitHeight: 1
			}

			CustomRect {
				Layout.fillWidth: true
				implicitHeight: deleteRow.implicitHeight + Tokens.padding.extraSmall * 2
				radius: popupBackground.radius - popupBackground.padding

				RowLayout {
					id: deleteRow

					anchors.fill: parent
					anchors.leftMargin: Tokens.padding.small
					spacing: 8

					MaterialIcon {
						color: deleteButton.hovered ? Colors.palette.m3onError : Colors.palette.m3error
						font.pointSize: 20
						text: "delete"
					}

					CustomText {
						Layout.fillWidth: true
						color: deleteButton.hovered ? Colors.palette.m3onError : Colors.palette.m3error
						text: "Move to trash"
					}
				}

				StateLayer {
					id: deleteButton

					anchors.fill: parent
					color: Colors.tPalette.m3error

					onClicked: {
						let cmd = ["gio", "trash"].concat(contextMenu.targetPaths);
						Quickshell.execDetached(cmd);
						contextMenu.close();
					}
				}
			}
		}
	}
}
