import "root:/"
import "root:/modules/common"
import "root:/modules/common/widgets"
import "root:/modules/common/functions/string_utils.js" as StringUtils
import QtQml
import Qt.labs.platform
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell.Io
import Quickshell.Hyprland
import Qt5Compat.GraphicalEffects

Button {
    id: root
    property var imageData
    property var rowHeight
    property bool manualDownload: false
    property string previewDownloadPath
    property string downloadPath
    property string nsfwPath
    property string fileName: decodeURIComponent((imageData.file_url).substring((imageData.file_url).lastIndexOf('/') + 1))
    property string filePath: `${root.previewDownloadPath}/${root.fileName}`

    property bool showActions: false

    Process {
        id: downloadProcess
        running: false
        command: ["bash", "-c", `[ -f ${root.filePath} ] || curl '${root.imageData.preview_url ?? root.imageData.sample_url}' -o '${root.filePath}'`]
        onExited: (exitCode, exitStatus) => {
            imageObject.source = `${previewDownloadPath}/${root.fileName}`
        }
    }

    Component.onCompleted: {
        if (root.manualDownload) {
            downloadProcess.running = true
        }
    }

    padding: 0
    implicitWidth: imageObject.width
    implicitHeight: imageObject.height

    // PointingHandInteraction {}

    background: Rectangle {
        implicitWidth: imageObject.width
        implicitHeight: imageObject.height
        radius: Appearance.rounding.small
        color: Appearance.colors.colLayer2
    }

    contentItem: Item {
        anchors.fill: parent

        Image {
            id: imageObject
            anchors.fill: parent
            sourceSize.width: root.rowHeight * modelData.aspect_ratio
            sourceSize.height: root.rowHeight
            fillMode: Image.PreserveAspectFit
            source: modelData.preview_url
            width: root.rowHeight * modelData.aspect_ratio
            height: root.rowHeight
            visible: opacity > 0
            opacity: status === Image.Ready ? 1 : 0

            layer.enabled: true
            layer.effect: OpacityMask {
                maskSource: Rectangle {
                    width: imageObject.width
                    height: imageObject.height
                    radius: Appearance.rounding.small
                }
            }

            Behavior on opacity {
                NumberAnimation {
                    duration: Appearance.animation.elementMoveEnter.duration
                    easing.type: Appearance.animation.elementMoveEnter.type
                    easing.bezierCurve: Appearance.animation.elementMoveEnter.bezierCurve
                }
            }
        }

        Button {
            id: menuButton
            anchors.top: parent.top
            anchors.right: parent.right
            anchors.margins: 8
            implicitHeight: 30
            implicitWidth: 30

            PointingHandInteraction {}

            background: Rectangle {
                color: menuButton.down ? Appearance.transparentize(Appearance.mix(Appearance.m3colors.m3surface, Appearance.m3colors.m3onSurface, 0.6), 0.1) :
                    menuButton.hovered ? Appearance.transparentize(Appearance.mix(Appearance.m3colors.m3surface, Appearance.m3colors.m3onSurface, 0.8), 0.2) :
                    Appearance.transparentize(Appearance.m3colors.m3surface, 0.3)
                radius: Appearance.rounding.full
            }

            contentItem: MaterialSymbol {
                horizontalAlignment: Text.AlignHCenter
                iconSize: Appearance.font.pixelSize.large
                color: Appearance.m3colors.m3onSurface
                text: "more_vert"
            }

            onClicked: {
                root.showActions = !root.showActions
            }
        }

        Rectangle {
            id: contextMenu
            opacity: root.showActions ? 1 : 0
            visible: opacity > 0
            radius: Appearance.rounding.small
            color: Appearance.m3colors.m3surfaceContainer
            anchors.top: menuButton.bottom
            anchors.right: parent.right
            anchors.margins: 8
            implicitHeight: contextMenuColumnLayout.implicitHeight + radius * 2
            implicitWidth: contextMenuColumnLayout.implicitWidth

            Behavior on opacity {
                NumberAnimation {
                    duration: Appearance.animation.elementMoveFast.duration
                    easing.type: Appearance.animation.elementMoveFast.type
                    easing.bezierCurve: Appearance.animation.elementMoveFast.bezierCurve
                }
            }

            ColumnLayout {
                id: contextMenuColumnLayout
                anchors.centerIn: parent
                spacing: 0

                MenuButton {
                    id: openFileLinkButton
                    Layout.fillWidth: true
                    buttonText: qsTr("Open file link")
                    onClicked: {
                        root.showActions = false
                        Qt.openUrlExternally(root.imageData.file_url)
                    }
                }
                MenuButton {
                    id: sourceButton
                    visible: root.imageData.source && root.imageData.source.length > 0
                    Layout.fillWidth: true
                    buttonText: StringUtils.format(qsTr("Go to source ({0})"), StringUtils.getDomain(root.imageData.source))
                    enabled: root.imageData.source && root.imageData.source.length > 0
                    onClicked: {
                        root.showActions = false
                        Hyprland.dispatch("global quickshell:sidebarLeftClose")
                        Qt.openUrlExternally(root.imageData.source)
                    }
                }
                MenuButton {
                    id: downloadButton
                    Layout.fillWidth: true
                    buttonText: "Download"
                    onClicked: {
                        root.showActions = false
                        Hyprland.dispatch(`exec curl '${root.imageData.file_url}' -o '${root.imageData.is_nsfw ? root.nsfwPath : root.downloadPath}/${root.fileName}' && notify-send '${qsTr("Download complete")}' '${root.downloadPath}/${root.fileName}'`)
                    }
                }
            }
        }

        DropShadow {
            opacity: root.showActions ? 1 : 0
            visible: opacity > 0
            anchors.fill: contextMenu
            source: contextMenu
            radius: Appearance.sizes.elevationMargin
            samples: radius * 2 + 1
            color: Appearance.colors.colShadow
            verticalOffset: 2
            horizontalOffset: 0

            Behavior on opacity {
                NumberAnimation {
                    duration: Appearance.animation.elementMoveFast.duration
                    easing.type: Appearance.animation.elementMoveFast.type
                    easing.bezierCurve: Appearance.animation.elementMoveFast.bezierCurve
                }
            }
        }

    }
}