// SPDX-FileCopyrightText: 2026, Shaun Reed <shaunrd0@gmail.com>
//
// SPDX-License-Identifier: GNU General Public License v3.0 or later

import QtQuick
import QtQuick.Effects
import QtQuick.Controls

import clide.module 1.0
import Logger 1.0

TreeView {
    id: fileSystemTreeView

    property int lastIndex: -1
    required property string originalRootDirectory
    property string rootDirectory

    signal fileClicked(string filePath)

    boundsBehavior: Flickable.StopAtBounds
    boundsMovement: Flickable.StopAtBounds
    clip: true
    leftMargin: 25
    model: FileSystem
    rootIndex: FileSystem.setDirectory(fileSystemTreeView.rootDirectory)

    // Provide our own custom ScrollIndicator for the TreeView.
    ScrollIndicator.vertical: ScrollIndicator {
        active: true
        implicitWidth: 15

        contentItem: Rectangle {
            color: RustColors.scrollbar
            implicitHeight: 6
            implicitWidth: 6
            opacity: fileSystemTreeView.movingVertically ? 0.5 : 0.0

            Behavior on opacity {
                OpacityAnimator {
                    duration: 500
                }
            }
        }
    }

    // The delegate represents a single entry in the filesystem.
    delegate: TreeViewDelegate {
        id: treeDelegate

        required property string fileName
        required property url filePath
        required property int index

        implicitHeight: 25
        implicitWidth: fileSystemTreeView.width > 0 ? fileSystemTreeView.width : 250
        indentation: 12

        background: Rectangle {
            color: current ? RustColors.explorer_folder_open : "transparent"
            radius: 2.5
        }
        contentItem: Text {
            anchors.left: directoryIcon.right
            anchors.leftMargin: 5
            color: RustColors.explorer_text
            text: treeDelegate.fileName
        }
        indicator: Label {
            id: directoryIcon

            anchors.verticalCenter: parent.verticalCenter
            antialiasing: true
            font.family: localFont.font.family
            font.pixelSize: 18
            smooth: true
            text: fileSystemTreeView.model.icon(filePath)
            x: treeDelegate.leftMargin + (treeDelegate.depth * treeDelegate.indentation) + (indicator.visible ? indicator.width : 0)
        }

        FontLoader {
            id: localFont

            source: "qrc:/fonts/saucecodepro-xlight.ttf"
        }
        Label {
            id: indicator

            anchors.verticalCenter: parent.verticalCenter
            font.family: localFont.font.family
            font.pixelSize: 10
            font.weight: localFont.font.weight
            text: expanded ? "⮟" : "⮞"
            visible: isTreeNode && hasChildren
            x: padding + (depth * indentation)
        }
        MultiEffect {
            id: iconOverlay

            anchors.fill: directoryIcon
            brightness: 1.0
            colorization: 1.0
            colorizationColor: {
                const isFile = !treeDelegate.hasChildren;
                if (isFile)
                    return Qt.lighter(RustColors.explorer_folder, 2);
                const isExpandedFolder = treeDelegate.expanded && treeDelegate.hasChildren;
                if (isExpandedFolder)
                    return Qt.darker(RustColors.explorer_folder, 2);
                else
                    return RustColors.explorer_folder;
            }
            source: directoryIcon
        }
        HoverHandler {
            id: hoverHandler

            acceptedDevices: PointerDevice.Mouse
        }
        TapHandler {
            acceptedButtons: Qt.LeftButton | Qt.RightButton

            onSingleTapped: (eventPoint, button) => {
                switch (button) {
                case Qt.LeftButton:
                    if (treeDelegate.hasChildren) {
                        fileSystemTreeView.toggleExpanded(treeDelegate.row);
                    } else {
                        // If this model item doesn't have children, it means it's representing a file.
                        fileSystemTreeView.fileClicked(treeDelegate.filePath);
                    }
                    break;
                case Qt.RightButton:
                    contextMenu.popup();
                    break;
                }
            }
        }
        ClideMenu {
            id: contextMenu

            ClideMenuItem {
                action: Action {
                    enabled: treeDelegate.hasChildren
                    text: qsTr("Set root")

                    onTriggered: {
                        Logger.debug("Setting new root directory: " + treeDelegate.filePath);
                        fileSystemTreeView.rootDirectory = treeDelegate.filePath;
                    }
                }
            }
            ClideMenuItem {
                action: Action {
                    text: qsTr("Reset root")

                    onTriggered: {
                        Logger.log("Resetting root directory: " + fileSystemTreeView.originalRootDirectory);
                        fileSystemTreeView.rootDirectory = fileSystemTreeView.originalRootDirectory;
                    }
                }
            }
        }
    }
    selectionModel: ItemSelectionModel {
    }
}
