pragma ComponentBehavior: Bound

import QtQuick
import Quickshell
import ZShell.Services
import qs.Helpers
import ZShell.Config
import qs.Services
import qs.Components
import qs.Paths

Item {
	id: root

	property int cellHeight: 110
	property int cellWidth: 100
	property var contextMenu: desktopMenu
	property string dragLeader: ""
	property string editingFilePath: ""
	property real groupDragX: 0
	property real groupDragY: 0
	property bool lassoActive: false
	property var selectedIcons: []
	property real startX: 0
	property real startY: 0

	function exec(filePath, isDir) {
		let type = DesktopUtils.getFileType(filePath, isDir);
		let cmd = [];
		switch (type) {
		case "image":
			cmd = [Config.general.apps.image, filePath];
			break;
		case "video":
			cmd = [Config.general.apps.playback, filePath];
			break;
		case "audio":
			cmd = [Config.general.apps.audio, filePath];
			break;
		case "archive":
			cmd = [Config.general.apps.archiver, filePath];
			break;
		case "directory":
			cmd = [Config.general.apps.explorer, filePath];
			break;
		case "text":
			cmd = [Config.general.apps.editor, filePath];
			break;
		case "document":
			cmd = [Config.general.apps.document, filePath];
			break;
		default:
			cmd = ["xdg-open", filePath];
		}
		Quickshell.execDetached(cmd);
	}

	function performMassDrop(leaderPath, targetX, targetY) {
		let maxCol = Math.max(0, Math.floor(gridArea.width / cellWidth) - 1);
		let maxRow = Math.max(0, Math.floor(gridArea.height / cellHeight) - 1);

		let visuals = [];
		for (let i = 0; i < gridArea.children.length; i++) {
			let child = gridArea.children[i];
			if (child.filePath && root.selectedIcons.includes(child.filePath)) {
				let isLeader = (root.dragLeader === child.filePath);
				let offsetX = isLeader ? child.getDragX() : root.groupDragX;
				let offsetY = isLeader ? child.getDragY() : root.groupDragY;
				visuals.push({
					childRef: child,
					absX: child.x + offsetX,
					absY: child.y + offsetY
				});
			}
		}

		desktopModel.massMove(root.selectedIcons, leaderPath, targetX, targetY, maxCol, maxRow);

		for (let i = 0; i < visuals.length; i++) {
			visuals[i].childRef.compensateAndSnap(visuals[i].absX, visuals[i].absY);
		}

		root.dragLeader = "";
		root.groupDragX = 0;
		root.groupDragY = 0;
	}

	anchors.fill: parent
	focus: true

	Keys.onPressed: event => {
		if (event.key === Qt.Key_F2 && selectedIcons.length > 0)
			editingFilePath = selectedIcons[0];
	}

	DesktopModel {
		id: desktopModel

		rows: Math.max(1, Math.floor(gridArea.height / root.cellHeight))

		Component.onCompleted: loadDirectory(FileUtils.trimFileProtocol(Paths.desktop))
	}

	CustomRect {
		id: lasso

		function hideLasso() {
			fadeIn.stop();
			fadeOut.start();
			root.lassoActive = false;
		}

		function showLasso() {
			root.lassoActive = true;
			fadeOut.stop();
			visible = true;
			fadeIn.start();
		}

		border.color: Colors.palette.m3primary
		border.pixelAligned: true
		border.width: 1
		color: Colors.tPalette.m3primary
		opacity: 0
		radius: Tokens.rounding.small
		visible: false
		z: 99

		NumberAnimation {
			id: fadeIn

			duration: 120
			from: 0
			property: "opacity"
			target: lasso
			to: 1
		}

		SequentialAnimation {
			id: fadeOut

			NumberAnimation {
				duration: 120
				from: lasso.opacity
				property: "opacity"
				target: lasso
				to: 0
			}

			ScriptAction {
				script: lasso.visible = false
			}
		}
	}

	MouseArea {
		acceptedButtons: Qt.LeftButton | Qt.RightButton
		anchors.fill: parent

		onPositionChanged: mouse => {
			if (lasso.visible) {
				lasso.x = Math.min(mouse.x, root.startX);
				lasso.y = Math.min(mouse.y, root.startY);
				lasso.width = Math.abs(mouse.x - root.startX);
				lasso.height = Math.abs(mouse.y - root.startY);

				let minCol = Math.floor((lasso.x - gridArea.x) / root.cellWidth);
				let maxCol = Math.floor((lasso.x + lasso.width - gridArea.x) / root.cellWidth);
				let minRow = Math.floor((lasso.y - gridArea.y) / root.cellHeight);
				let maxRow = Math.floor((lasso.y + lasso.height - gridArea.y) / root.cellHeight);

				let newSelection = [];
				for (let i = 0; i < gridArea.children.length; i++) {
					let child = gridArea.children[i];
					if (child.filePath !== undefined && child.gridX >= minCol && child.gridX <= maxCol && child.gridY >= minRow && child.gridY <= maxRow) {
						newSelection.push(child.filePath);
					}
				}
				root.selectedIcons = newSelection;
			}
		}
		onPressed: mouse => {
			root.editingFilePath = "";
			desktopMenu.close();

			if (mouse.button === Qt.RightButton) {
				root.selectedIcons = [];
				bgContextMenu.openAt(mouse.x, mouse.y, root.width, root.height);
			} else {
				bgContextMenu.close();
				root.selectedIcons = [];
				root.startX = mouse.x;
				root.startY = mouse.y;
				lasso.x = mouse.x;
				lasso.y = mouse.y;
				lasso.width = 0;
				lasso.height = 0;
				lasso.showLasso();
			}
		}
		onReleased: {
			lasso.hideLasso();
		}
	}

	Item {
		id: gridArea

		anchors.fill: parent
		anchors.margins: 20
		anchors.topMargin: 40

		Repeater {
			model: desktopModel

			delegate: DesktopIconDelegate {
				required property int index

				contextMenu: desktopMenu
				iconsRoot: root
			}
		}
	}

	DesktopIconContextMenu {
		id: desktopMenu

		onOpenFileRequested: (path, isDir) => root.exec(path, isDir)
		onRenameRequested: path => {
			root.editingFilePath = path;
		}
	}

	BackgroundContextMenu {
		id: bgContextMenu
	}
}
