pragma ComponentBehavior: Bound

import QtQuick
import QtQuick.Controls
import Quickshell
import Quickshell.Io
import qs.Common
import qs.Modals.Common
import qs.Services
import qs.Widgets

DankModal {
    id: clipboardHistoryModal

    property int totalCount: 0
    property var clipboardEntries: []
    property string searchText: ""
    property int selectedIndex: 0
    property bool keyboardNavigationActive: false
    property bool showKeyboardHints: false
    property Component clipboardContent
    property int activeImageLoads: 0
    readonly property int maxConcurrentLoads: 3

    function updateFilteredModel() {
        filteredClipboardModel.clear()
        for (var i = 0; i < clipboardModel.count; i++) {
            const entry = clipboardModel.get(i).entry
            if (searchText.trim().length === 0) {
                filteredClipboardModel.append({
                                                  "entry": entry
                                              })
            } else {
                const content = getEntryPreview(entry).toLowerCase()
                if (content.includes(searchText.toLowerCase())) {
                    filteredClipboardModel.append({
                                                      "entry": entry
                                                  })
                }
            }
        }
        clipboardHistoryModal.totalCount = filteredClipboardModel.count
        if (filteredClipboardModel.count === 0) {
            keyboardNavigationActive = false
            selectedIndex = 0
        } else if (selectedIndex >= filteredClipboardModel.count) {
            selectedIndex = filteredClipboardModel.count - 1
        }
    }

    function toggle() {
        if (shouldBeVisible) {
            hide()
        } else {
            show()
        }
    }

    function show() {
        open()
        clipboardHistoryModal.searchText = ""
        clipboardHistoryModal.activeImageLoads = 0
        clipboardHistoryModal.shouldHaveFocus = true
        refreshClipboard()
        keyboardController.reset()

        Qt.callLater(function () {
            if (contentLoader.item && contentLoader.item.searchField) {
                contentLoader.item.searchField.text = ""
                contentLoader.item.searchField.forceActiveFocus()
            }
        })
    }

    function hide() {
        close()
        clipboardHistoryModal.searchText = ""
        clipboardHistoryModal.activeImageLoads = 0
        updateFilteredModel()
        keyboardController.reset()
        cleanupTempFiles()
    }

    function cleanupTempFiles() {
        Quickshell.execDetached(["sh", "-c", "rm -f /tmp/clipboard_*.png"])
    }

    function refreshClipboard() {
        clipboardProcesses.refresh()
    }

    function copyEntry(entry) {
        const entryId = entry.split('\t')[0]
        Quickshell.execDetached(["sh", "-c", `cliphist decode ${entryId} | wl-copy`])
        ToastService.showInfo(I18n.tr("Copied to clipboard"))
        hide()
    }

    function deleteEntry(entry) {
        clipboardProcesses.deleteEntry(entry)
    }

    function clearAll() {
        clipboardProcesses.clearAll()
    }

    function getEntryPreview(entry) {
        let content = entry.replace(/^\s*\d+\s+/, "")
        if (content.includes("image/") || content.includes("binary data") || /\.(png|jpg|jpeg|gif|bmp|webp)/i.test(content)) {
            const dimensionMatch = content.match(/(\d+)x(\d+)/)
            if (dimensionMatch) {
                return `Image ${dimensionMatch[1]}×${dimensionMatch[2]}`
            }
            const typeMatch = content.match(/\b(png|jpg|jpeg|gif|bmp|webp)\b/i)
            if (typeMatch) {
                return `Image (${typeMatch[1].toUpperCase()})`
            }
            return "Image"
        }
        if (content.length > ClipboardConstants.previewLength) {
            return content.substring(0, ClipboardConstants.previewLength) + "..."
        }
        return content
    }

    function getEntryType(entry) {
        if (entry.includes("image/") || entry.includes("binary data") || /\.(png|jpg|jpeg|gif|bmp|webp)/i.test(entry) || /\b(png|jpg|jpeg|gif|bmp|webp)\b/i.test(entry)) {
            return "image"
        }
        if (entry.length > ClipboardConstants.longTextThreshold) {
            return "long_text"
        }
        return "text"
    }

    visible: false
    width: ClipboardConstants.modalWidth
    height: ClipboardConstants.modalHeight
    backgroundColor: Theme.popupBackground()
    cornerRadius: Theme.cornerRadius
    borderColor: Theme.outlineMedium
    borderWidth: 1
    enableShadow: true
    onBackgroundClicked: hide()
    modalFocusScope.Keys.onPressed: function (event) {
        keyboardController.handleKey(event)
    }
    content: clipboardContent

    ClipboardKeyboardController {
        id: keyboardController
        modal: clipboardHistoryModal
    }

    ConfirmModal {
        id: clearConfirmDialog
        confirmButtonText: I18n.tr("Clear All")
        confirmButtonColor: Theme.primary
        onVisibleChanged: {
            if (visible) {
                clipboardHistoryModal.shouldHaveFocus = false
            } else if (clipboardHistoryModal.shouldBeVisible) {
                clipboardHistoryModal.shouldHaveFocus = true
                clipboardHistoryModal.modalFocusScope.forceActiveFocus()
                if (clipboardHistoryModal.contentLoader.item && clipboardHistoryModal.contentLoader.item.searchField) {
                    clipboardHistoryModal.contentLoader.item.searchField.forceActiveFocus()
                }
            }
        }
    }

    property alias filteredClipboardModel: filteredClipboardModel
    property alias clipboardModel: clipboardModel
    property var confirmDialog: clearConfirmDialog

    ListModel {
        id: clipboardModel
    }

    ListModel {
        id: filteredClipboardModel
    }

    ClipboardProcesses {
        id: clipboardProcesses
        modal: clipboardHistoryModal
        clipboardModel: clipboardModel
        filteredClipboardModel: filteredClipboardModel
    }

    IpcHandler {
        function open(): string {
            clipboardHistoryModal.show()
            return "CLIPBOARD_OPEN_SUCCESS"
        }

        function close(): string {
            clipboardHistoryModal.hide()
            return "CLIPBOARD_CLOSE_SUCCESS"
        }

        function toggle(): string {
            clipboardHistoryModal.toggle()
            return "CLIPBOARD_TOGGLE_SUCCESS"
        }

        target: "clipboard"
    }

    clipboardContent: Component {
        ClipboardContent {
            modal: clipboardHistoryModal
            filteredModel: filteredClipboardModel
            clearConfirmDialog: clipboardHistoryModal.confirmDialog
        }
    }
}
