import QtQuick
import Quickshell.Io
import qs.Common

Item {
    id: root

    property string layerNamespacePlugin: "plugin"

    property var axis: null
    property string section: "center"
    property var parentScreen: null
    property real widgetThickness: 30
    property real barThickness: 48
    property real barSpacing: 4
    property var barConfig: null
    property var blurBarWindow: null
    property string pluginId: ""
    property var pluginService: null

    property string visibilityCommand: ""
    property int visibilityInterval: 0
    property bool conditionVisible: true
    property bool _visibilityOverride: false
    property bool _visibilityOverrideValue: true
    readonly property bool _barRevealed: blurBarWindow?.barRevealed ?? true

    readonly property bool effectiveVisible: {
        if (_visibilityOverride)
            return _visibilityOverrideValue;
        if (!visibilityCommand)
            return true;
        return conditionVisible;
    }

    property Component horizontalBarPill: null
    property Component verticalBarPill: null
    property Component popoutContent: null
    property real popoutWidth: 400
    property real popoutHeight: 0
    property var pillClickAction: null
    property var pillRightClickAction: null

    property Component controlCenterWidget: null
    property string ccWidgetIcon: ""
    property string ccWidgetPrimaryText: ""
    property string ccWidgetSecondaryText: ""
    property bool ccWidgetIsActive: false
    property bool ccWidgetIsToggle: true
    property Component ccDetailContent: null
    property real ccDetailHeight: 250

    signal ccWidgetToggled
    signal ccWidgetExpanded

    property var pluginData: ({})
    property var variants: []

    readonly property bool isVertical: axis?.isVertical ?? false
    readonly property bool hasHorizontalPill: horizontalBarPill !== null
    readonly property bool hasVerticalPill: verticalBarPill !== null
    readonly property bool hasPopout: popoutContent !== null

    readonly property int iconSize: Theme.barIconSize(barThickness, -4, root.barConfig?.maximizeWidgetIcons, root.barConfig?.iconScale)
    readonly property int iconSizeLarge: Theme.barIconSize(barThickness, undefined, root.barConfig?.maximizeWidgetIcons, root.barConfig?.iconScale)

    Component.onCompleted: {
        loadPluginData();
        if (visibilityCommand)
            Qt.callLater(checkVisibility);
    }

    onPluginServiceChanged: {
        loadPluginData();
    }

    onPluginIdChanged: {
        loadPluginData();
    }

    Connections {
        target: pluginService
        function onPluginDataChanged(changedPluginId) {
            if (changedPluginId === pluginId) {
                loadPluginData();
            }
        }
    }

    function loadPluginData() {
        if (!pluginService || !pluginId) {
            pluginData = {};
            variants = [];
            return;
        }
        pluginData = SettingsData.getPluginSettingsForPlugin(pluginId);
        variants = pluginService.getPluginVariants(pluginId);
    }

    function checkVisibility() {
        if (!visibilityCommand) {
            conditionVisible = true;
            return;
        }
        visibilityProcess.running = true;
    }

    function setVisibilityOverride(visible) {
        _visibilityOverride = true;
        _visibilityOverrideValue = visible;
    }

    function clearVisibilityOverride() {
        _visibilityOverride = false;
        if (visibilityCommand)
            checkVisibility();
    }

    onVisibilityCommandChanged: {
        if (visibilityCommand)
            Qt.callLater(checkVisibility);
        else
            conditionVisible = true;
    }

    on_BarRevealedChanged: {
        if (_barRevealed && visibilityCommand && !_visibilityOverride)
            checkVisibility();
    }

    onVisibilityIntervalChanged: {
        if (visibilityInterval > 0 && visibilityCommand) {
            visibilityTimer.restart();
        } else {
            visibilityTimer.stop();
        }
    }

    Timer {
        id: visibilityTimer
        interval: root.visibilityInterval * 1000
        repeat: true
        running: root.visibilityInterval > 0 && root.visibilityCommand !== "" && root._barRevealed && !root._visibilityOverride
        onTriggered: root.checkVisibility()
    }

    Process {
        id: visibilityProcess
        command: ["sh", "-c", root.visibilityCommand]
        running: false
        onExited: (exitCode, exitStatus) => {
            root.conditionVisible = (exitCode === 0);
        }
    }

    function createVariant(variantName, variantConfig) {
        if (!pluginService || !pluginId) {
            return null;
        }
        return pluginService.createPluginVariant(pluginId, variantName, variantConfig);
    }

    function removeVariant(variantId) {
        if (!pluginService || !pluginId) {
            return;
        }
        pluginService.removePluginVariant(pluginId, variantId);
    }

    function updateVariant(variantId, variantConfig) {
        if (!pluginService || !pluginId) {
            return;
        }
        pluginService.updatePluginVariant(pluginId, variantId, variantConfig);
    }

    width: isVertical ? (hasVerticalPill ? verticalPill.width : 0) : (hasHorizontalPill ? horizontalPill.width : 0)
    height: isVertical ? (hasVerticalPill ? verticalPill.height : 0) : (hasHorizontalPill ? horizontalPill.height : 0)

    BasePill {
        id: horizontalPill
        visible: !isVertical && hasHorizontalPill
        opacity: root.effectiveVisible ? 1 : 0
        axis: root.axis
        section: root.section
        popoutTarget: hasPopout ? pluginPopout : null
        parentScreen: root.parentScreen
        widgetThickness: root.widgetThickness
        barThickness: root.barThickness
        barSpacing: root.barSpacing
        barConfig: root.barConfig
        blurBarWindow: root.blurBarWindow
        content: root.horizontalBarPill

        states: State {
            name: "hidden"
            when: !root.effectiveVisible
            PropertyChanges {
                target: horizontalPill
                width: 0
            }
        }

        transitions: Transition {
            NumberAnimation {
                properties: "width,opacity"
                duration: Theme.shortDuration
                easing.type: Theme.standardEasing
            }
        }

        onClicked: {
            if (pillClickAction) {
                if (pillClickAction.length === 0) {
                    pillClickAction();
                } else {
                    const globalPos = mapToItem(null, 0, 0);
                    const currentScreen = parentScreen || Screen;
                    const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, width);
                    pillClickAction(pos.x, pos.y, pos.width, section, currentScreen);
                }
            } else if (hasPopout) {
                pluginPopout.toggle();
            }
        }
        onRightClicked: {
            if (pillRightClickAction) {
                if (pillRightClickAction.length === 0) {
                    pillRightClickAction();
                } else {
                    const globalPos = mapToItem(null, 0, 0);
                    const currentScreen = parentScreen || Screen;
                    const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, width);
                    pillRightClickAction(pos.x, pos.y, pos.width, section, currentScreen);
                }
            }
        }
    }

    BasePill {
        id: verticalPill
        visible: isVertical && hasVerticalPill
        opacity: root.effectiveVisible ? 1 : 0
        axis: root.axis
        section: root.section
        popoutTarget: hasPopout ? pluginPopout : null
        parentScreen: root.parentScreen
        widgetThickness: root.widgetThickness
        barThickness: root.barThickness
        barSpacing: root.barSpacing
        barConfig: root.barConfig
        blurBarWindow: root.blurBarWindow
        content: root.verticalBarPill
        isVerticalOrientation: true

        states: State {
            name: "hidden"
            when: !root.effectiveVisible
            PropertyChanges {
                target: verticalPill
                height: 0
            }
        }

        transitions: Transition {
            NumberAnimation {
                properties: "height,opacity"
                duration: Theme.shortDuration
                easing.type: Theme.standardEasing
            }
        }

        onClicked: {
            if (pillClickAction) {
                if (pillClickAction.length === 0) {
                    pillClickAction();
                } else {
                    const globalPos = mapToItem(null, 0, 0);
                    const currentScreen = parentScreen || Screen;
                    const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, width);
                    pillClickAction(pos.x, pos.y, pos.width, section, currentScreen);
                }
            } else if (hasPopout) {
                pluginPopout.toggle();
            }
        }
        onRightClicked: {
            if (pillRightClickAction) {
                if (pillRightClickAction.length === 0) {
                    pillRightClickAction();
                } else {
                    const globalPos = mapToItem(null, 0, 0);
                    const currentScreen = parentScreen || Screen;
                    const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, width);
                    pillRightClickAction(pos.x, pos.y, pos.width, section, currentScreen);
                }
            }
        }
    }

    function closePopout() {
        if (pluginPopout) {
            pluginPopout.close();
        }
    }

    function triggerPopout() {
        if (pillClickAction) {
            if (pillClickAction.length === 0) {
                pillClickAction();
                return;
            }
            const pill = isVertical ? verticalPill : horizontalPill;
            const globalPos = pill.mapToItem(null, 0, 0);
            const currentScreen = parentScreen || Screen;
            const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, pill.width);
            pillClickAction(pos.x, pos.y, pos.width, section, currentScreen);
            return;
        }
        if (!hasPopout)
            return;

        const pill = isVertical ? verticalPill : horizontalPill;
        const globalPos = pill.visualContent.mapToItem(null, 0, 0);
        const currentScreen = parentScreen || Screen;
        const barPosition = axis?.edge === "left" ? 2 : (axis?.edge === "right" ? 3 : (axis?.edge === "top" ? 0 : 1));
        const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, pill.visualWidth, barSpacing, barPosition, barConfig);

        pluginPopout.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen, barPosition, barThickness, barSpacing, barConfig);
        pluginPopout.toggle();
    }

    function triggerHoverPopout(widgetHostId) {
        if (pillClickAction) {
            triggerPopout();
            return;
        }
        if (!hasPopout)
            return;

        const pill = isVertical ? verticalPill : horizontalPill;
        const globalPos = pill.visualContent.mapToItem(null, 0, 0);
        const currentScreen = parentScreen || Screen;
        const barPosition = axis?.edge === "left" ? 2 : (axis?.edge === "right" ? 3 : (axis?.edge === "top" ? 0 : 1));
        const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, pill.visualWidth, barSpacing, barPosition, barConfig);

        pluginPopout.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen, barPosition, barThickness, barSpacing, barConfig);
        PopoutManager.requestHoverPopout(pluginPopout, undefined, widgetHostId || pluginId);
    }

    PluginPopout {
        id: pluginPopout
        contentWidth: root.popoutWidth
        contentHeight: root.popoutHeight
        pluginContent: root.popoutContent
    }
}
