import QtQuick
import qs.Common
import qs.Services
import qs.Modules.ControlCenter.Widgets
import qs.Modules.ControlCenter.Components
import "../utils/layout.js" as LayoutUtils

Column {
    id: root

    property bool editMode: false
    property string expandedSection: ""
    property int expandedWidgetIndex: -1
    property var model: null
    property var expandedWidgetData: null
    property var bluetoothCodecSelector: null
    property bool darkModeTransitionPending: false
    property string screenName: ""
    property string screenModel: ""
    property var parentScreen: null

    signal expandClicked(var widgetData, int globalIndex)
    signal removeWidget(int index)
    signal moveWidget(int fromIndex, int toIndex)
    signal toggleWidgetSize(int index)
    signal collapseRequested

    function requestCollapse() {
        collapseRequested();
    }

    spacing: editMode ? Theme.spacingL : Theme.spacingS

    property real maxPopoutHeight: 9999
    property var currentRowWidgets: []
    property real currentRowWidth: 0
    property int expandedRowIndex: -1
    property var colorPickerModal: null

    readonly property real _maxDetailHeight: {
        const rows = layoutResult.rows;
        let totalRowHeight = 0;
        for (let i = 0; i < rows.length; i++) {
            const sliderOnly = rows[i].every(w => {
                const id = w.id || "";
                return id === "volumeSlider" || id === "brightnessSlider" || id === "inputVolumeSlider";
            });
            totalRowHeight += sliderOnly ? 36 : 60;
        }
        const rowSpacing = Math.max(0, rows.length - 1) * spacing;
        return Math.max(100, maxPopoutHeight - totalRowHeight - rowSpacing);
    }

    function calculateRowsAndWidgets() {
        return LayoutUtils.calculateRowsAndWidgets(root, expandedSection, expandedWidgetIndex);
    }

    property var layoutResult: {
        const dummy = [expandedSection, expandedWidgetIndex, model?.controlCenterWidgets];
        return calculateRowsAndWidgets();
    }

    onLayoutResultChanged: {
        expandedRowIndex = layoutResult.expandedRowIndex;
    }

    function moveToTop(item) {
        const children = root.children;
        for (var i = 0; i < children.length; i++) {
            if (children[i] === item)
                continue;
            if (children[i].z)
                children[i].z = Math.min(children[i].z, 999);
        }
        item.z = 1000;
    }

    Repeater {
        model: root.layoutResult.rows

        Column {
            width: root.width
            spacing: 0
            property int rowIndex: index
            property var rowWidgets: modelData
            property bool isSliderOnlyRow: {
                const widgets = rowWidgets || [];
                if (widgets.length === 0)
                    return false;
                return widgets.every(w => w.id === "volumeSlider" || w.id === "brightnessSlider" || w.id === "inputVolumeSlider");
            }
            topPadding: isSliderOnlyRow ? (root.editMode ? 4 : -6) : 0
            bottomPadding: isSliderOnlyRow ? (root.editMode ? 4 : -6) : 0

            Flow {
                width: parent.width
                spacing: Theme.spacingS

                Repeater {
                    model: rowWidgets || []

                    DragDropWidgetWrapper {
                        widgetData: modelData
                        property int globalWidgetIndex: {
                            const widgets = SettingsData.controlCenterWidgets || [];
                            for (var i = 0; i < widgets.length; i++) {
                                if (widgets[i].id === modelData.id) {
                                    if (modelData.id === "diskUsage" || modelData.id === "brightnessSlider") {
                                        if (widgets[i].instanceId === modelData.instanceId) {
                                            return i;
                                        }
                                    } else {
                                        return i;
                                    }
                                }
                            }
                            return -1;
                        }
                        property int widgetWidth: modelData.width || 50
                        width: {
                            const baseWidth = root.width;
                            const spacing = Theme.spacingS;
                            if (widgetWidth <= 25) {
                                return (baseWidth - spacing * 3) / 4;
                            } else if (widgetWidth <= 50) {
                                return (baseWidth - spacing) / 2;
                            } else if (widgetWidth <= 75) {
                                return (baseWidth - spacing * 2) * 0.75;
                            } else {
                                return baseWidth;
                            }
                        }
                        height: isSliderOnlyRow ? 48 : 60

                        editMode: root.editMode
                        widgetIndex: globalWidgetIndex
                        gridCellWidth: width
                        gridCellHeight: height
                        gridColumns: 4
                        gridLayout: root
                        isSlider: {
                            const id = modelData.id || "";
                            return id === "volumeSlider" || id === "brightnessSlider" || id === "inputVolumeSlider";
                        }

                        widgetComponent: {
                            const id = modelData.id || "";
                            if (id.startsWith("builtin_")) {
                                return builtinPluginWidgetComponent;
                            } else if (id.startsWith("plugin_")) {
                                return pluginWidgetComponent;
                            } else if (id === "wifi" || id === "bluetooth" || id === "audioOutput" || id === "audioInput") {
                                return compoundPillComponent;
                            } else if (id === "volumeSlider") {
                                return audioSliderComponent;
                            } else if (id === "brightnessSlider") {
                                return brightnessSliderComponent;
                            } else if (id === "inputVolumeSlider") {
                                return inputAudioSliderComponent;
                            } else if (id === "battery") {
                                return widgetWidth <= 25 ? smallBatteryComponent : batteryPillComponent;
                            } else if (id === "diskUsage") {
                                return widgetWidth <= 25 ? smallDiskUsageComponent : diskUsagePillComponent;
                            } else if (id === "colorPicker") {
                                return colorPickerPillComponent;
                            } else {
                                return widgetWidth <= 25 ? smallToggleComponent : toggleButtonComponent;
                            }
                        }

                        onWidgetMoved: (fromIndex, toIndex) => root.moveWidget(fromIndex, toIndex)
                        onRemoveWidget: index => root.removeWidget(index)
                        onToggleWidgetSize: index => root.toggleWidgetSize(index)
                    }
                }
            }

            DetailHost {
                id: detailHost
                width: parent.width
                maxAvailableHeight: root._maxDetailHeight
                height: active ? (getDetailHeight(root.expandedSection) + Theme.spacingS) : 0
                property bool active: {
                    if (root.expandedSection === "")
                        return false;

                    if (root.expandedSection.startsWith("diskUsage_") && root.expandedWidgetData) {
                        const expandedInstanceId = root.expandedWidgetData.instanceId;
                        return rowWidgets.some(w => w.id === "diskUsage" && w.instanceId === expandedInstanceId);
                    }

                    if (root.expandedSection.startsWith("brightnessSlider_") && root.expandedWidgetData) {
                        const expandedInstanceId = root.expandedWidgetData.instanceId;
                        return rowWidgets.some(w => w.id === "brightnessSlider" && w.instanceId === expandedInstanceId);
                    }

                    return rowIndex === root.expandedRowIndex;
                }
                visible: active
                expandedSection: root.expandedSection
                expandedWidgetData: root.expandedWidgetData
                bluetoothCodecSelector: root.bluetoothCodecSelector
                widgetModel: root.model
                collapseCallback: root.requestCollapse
                screenName: root.screenName
                screenModel: root.screenModel
            }
        }
    }

    Component {
        id: errorPillComponent
        ErrorPill {
            property var widgetData: parent.widgetData || {}
            width: parent.width
            height: 60
            primaryMessage: {
                if (!DMSService.dmsAvailable) {
                    return I18n.tr("DMS_SOCKET not available");
                }
                return I18n.tr("NM not supported");
            }
            secondaryMessage: I18n.tr("update dms for NM integration.")
        }
    }

    Component {
        id: compoundPillComponent
        CompoundPill {
            property var widgetData: parent.widgetData || {}
            property int widgetIndex: parent.widgetIndex || 0
            property var widgetDef: root.model?.getWidgetForId(widgetData.id || "")
            width: parent.width
            height: 60
            iconName: {
                switch (widgetData.id || "") {
                case "wifi":
                    {
                        if (NetworkService.wifiToggling)
                            return "sync";

                        const status = NetworkService.networkStatus;
                        if (status === "ethernet")
                            return "settings_ethernet";
                        if (status === "vpn")
                            return NetworkService.ethernetConnected ? "settings_ethernet" : NetworkService.wifiSignalIcon;
                        if (status === "wifi")
                            return NetworkService.wifiSignalIcon;
                        if (NetworkService.wifiEnabled)
                            return "wifi_off";
                        return "wifi_off";
                    }
                case "bluetooth":
                    {
                        if (!BluetoothService.available)
                            return "bluetooth_disabled";
                        if (!BluetoothService.adapter || !BluetoothService.adapter.enabled)
                            return "bluetooth_disabled";
                        return "bluetooth";
                    }
                case "audioOutput":
                    {
                        if (!AudioService.sink)
                            return "volume_off";
                        let volume = AudioService.sink.audio.volume;
                        let muted = AudioService.sink.audio.muted;
                        if (muted)
                            return "volume_off";
                        if (volume === 0.0)
                            return "volume_mute";
                        if (volume <= 0.33)
                            return "volume_down";
                        if (volume <= 0.66)
                            return "volume_up";
                        return "volume_up";
                    }
                case "audioInput":
                    {
                        if (!AudioService.source)
                            return "mic_off";
                        let muted = AudioService.source.audio.muted;
                        return muted ? "mic_off" : "mic";
                    }
                default:
                    return widgetDef?.icon || "help";
                }
            }
            primaryText: {
                switch (widgetData.id || "") {
                case "wifi":
                    {
                        if (NetworkService.wifiToggling)
                            return NetworkService.wifiEnabled ? I18n.tr("Disabling WiFi...", "network status") : I18n.tr("Enabling WiFi...", "network status");

                        const status = NetworkService.networkStatus;
                        if (status === "ethernet")
                            return I18n.tr("Ethernet", "network status");
                        if (status === "vpn") {
                            if (NetworkService.ethernetConnected)
                                return I18n.tr("Ethernet", "network status");
                            if (NetworkService.wifiConnected && NetworkService.currentWifiSSID)
                                return NetworkService.currentWifiSSID;
                        }
                        if (status === "wifi" && NetworkService.currentWifiSSID)
                            return NetworkService.currentWifiSSID;
                        if (NetworkService.wifiEnabled)
                            return I18n.tr("Not connected", "network status");
                        return I18n.tr("WiFi off", "network status");
                    }
                case "bluetooth":
                    {
                        if (!BluetoothService.available)
                            return I18n.tr("Bluetooth", "bluetooth status");
                        if (!BluetoothService.adapter)
                            return I18n.tr("No adapter", "bluetooth status");
                        if (!BluetoothService.adapter.enabled)
                            return I18n.tr("Disabled", "bluetooth status");
                        return I18n.tr("Enabled", "bluetooth status");
                    }
                case "audioOutput":
                    return AudioService.sink?.description || I18n.tr("No output device", "audio status");
                case "audioInput":
                    return AudioService.source?.description || I18n.tr("No input device", "audio status");
                default:
                    return widgetDef?.text || I18n.tr("Unknown", "widget status");
                }
            }
            secondaryText: {
                switch (widgetData.id || "") {
                case "wifi":
                    {
                        if (NetworkService.wifiToggling)
                            return I18n.tr("Please wait...", "network status");

                        const status = NetworkService.networkStatus;
                        if (status === "ethernet")
                            return I18n.tr("Connected", "network status");
                        if (status === "vpn") {
                            if (NetworkService.ethernetConnected)
                                return I18n.tr("Connected", "network status");
                            if (NetworkService.wifiConnected)
                                return NetworkService.wifiSignalStrength > 0 ? NetworkService.wifiSignalStrength + "%" : I18n.tr("Connected", "network status");
                        }
                        if (status === "wifi")
                            return NetworkService.wifiSignalStrength > 0 ? NetworkService.wifiSignalStrength + "%" : I18n.tr("Connected", "network status");
                        if (NetworkService.wifiEnabled)
                            return I18n.tr("Select network", "network status");
                        return "";
                    }
                case "bluetooth":
                    {
                        if (!BluetoothService.available)
                            return I18n.tr("No adapters", "bluetooth status");
                        if (!BluetoothService.adapter || !BluetoothService.adapter.enabled)
                            return I18n.tr("Off", "bluetooth status");
                        const primaryDevice = (() => {
                                if (!BluetoothService.adapter || !BluetoothService.adapter.devices)
                                    return null;
                                let devices = [...BluetoothService.adapter.devices.values.filter(dev => dev && (dev.paired || dev.trusted))];
                                for (let device of devices) {
                                    if (device && device.connected)
                                        return device;
                                }
                                return null;
                            })();
                        if (primaryDevice)
                            return primaryDevice.name || primaryDevice.alias || primaryDevice.deviceName || I18n.tr("Connected Device", "bluetooth status");
                        return I18n.tr("No devices", "bluetooth status");
                    }
                case "audioOutput":
                    {
                        if (!AudioService.sink)
                            return I18n.tr("Select device", "audio status");
                        if (AudioService.sink.audio.muted)
                            return I18n.tr("Muted", "audio status");
                        const volume = AudioService.sink.audio.volume;
                        if (typeof volume !== "number" || isNaN(volume))
                            return "0%";
                        return Math.round(volume * 100) + "%";
                    }
                case "audioInput":
                    {
                        if (!AudioService.source)
                            return I18n.tr("Select device", "audio status");
                        if (AudioService.source.audio.muted)
                            return I18n.tr("Muted", "audio status");
                        const volume = AudioService.source.audio.volume;
                        if (typeof volume !== "number" || isNaN(volume))
                            return "0%";
                        return Math.round(volume * 100) + "%";
                    }
                default:
                    return widgetDef?.description || "";
                }
            }
            isActive: {
                switch (widgetData.id || "") {
                case "wifi":
                    {
                        if (NetworkService.wifiToggling)
                            return false;

                        const status = NetworkService.networkStatus;
                        if (status === "ethernet")
                            return true;
                        if (status === "vpn")
                            return NetworkService.ethernetConnected || NetworkService.wifiConnected;
                        if (status === "wifi")
                            return true;
                        return NetworkService.wifiEnabled;
                    }
                case "bluetooth":
                    return !!(BluetoothService.available && BluetoothService.adapter && BluetoothService.adapter.enabled);
                case "audioOutput":
                    return !!(AudioService.sink && !AudioService.sink.audio.muted);
                case "audioInput":
                    return !!(AudioService.source && !AudioService.source.audio.muted);
                default:
                    return false;
                }
            }
            enabled: widgetDef?.enabled ?? true
            onToggled: {
                if (root.editMode)
                    return;
                switch (widgetData.id || "") {
                case "wifi":
                    {
                        if (NetworkService.networkStatus !== "ethernet" && !NetworkService.wifiToggling) {
                            NetworkService.toggleWifiRadio();
                        }
                        break;
                    }
                case "bluetooth":
                    {
                        if (BluetoothService.available && BluetoothService.adapter) {
                            BluetoothService.adapter.enabled = !BluetoothService.adapter.enabled;
                        }
                        break;
                    }
                case "audioOutput":
                    {
                        if (AudioService.sink && AudioService.sink.audio) {
                            AudioService.sink.audio.muted = !AudioService.sink.audio.muted;
                        }
                        break;
                    }
                case "audioInput":
                    {
                        if (AudioService.source && AudioService.source.audio) {
                            AudioService.source.audio.muted = !AudioService.source.audio.muted;
                        }
                        break;
                    }
                }
            }
            onExpandClicked: {
                if (root.editMode)
                    return;
                root.expandClicked(widgetData, widgetIndex);
            }
            onWheelEvent: function (wheelEvent) {
                if (root.editMode)
                    return;
                const id = widgetData.id || "";
                if (id === "audioOutput") {
                    if (!AudioService.sink || !AudioService.sink.audio)
                        return;
                    let delta = wheelEvent.angleDelta.y;
                    let maxVol = AudioService.sinkMaxVolume;
                    let currentVolume = AudioService.sink.audio.volume * 100;
                    let newVolume;
                    if (delta > 0)
                        newVolume = Math.min(maxVol, currentVolume + 5);
                    else
                        newVolume = Math.max(0, currentVolume - 5);
                    AudioService.sink.audio.muted = false;
                    AudioService.sink.audio.volume = newVolume / 100;
                    wheelEvent.accepted = true;
                } else if (id === "audioInput") {
                    if (!AudioService.source || !AudioService.source.audio)
                        return;
                    let delta = wheelEvent.angleDelta.y;
                    let currentVolume = AudioService.source.audio.volume * 100;
                    let newVolume;
                    if (delta > 0)
                        newVolume = Math.min(100, currentVolume + 5);
                    else
                        newVolume = Math.max(0, currentVolume - 5);
                    AudioService.source.audio.muted = false;
                    AudioService.source.audio.volume = newVolume / 100;
                    wheelEvent.accepted = true;
                }
            }
        }
    }

    Component {
        id: audioSliderComponent
        Item {
            property var widgetData: parent.widgetData || {}
            property int widgetIndex: parent.widgetIndex || 0
            width: parent.width
            height: 16

            AudioSliderRow {
                anchors.centerIn: parent
                width: parent.width
                height: 14
                property color sliderTrackColor: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
            }
        }
    }

    Component {
        id: brightnessSliderComponent
        Item {
            property var widgetData: parent.widgetData || {}
            property int widgetIndex: parent.widgetIndex || 0
            width: parent.width
            height: 16

            BrightnessSliderRow {
                id: brightnessSliderRow
                anchors.centerIn: parent
                width: parent.width
                height: 14
                deviceName: widgetData.deviceName || ""
                instanceId: widgetData.instanceId || ""
                screenName: root.screenName
                parentScreen: root.parentScreen
                property color sliderTrackColor: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)

                onIconClicked: {
                    if (!root.editMode && DisplayService.devices && DisplayService.devices.length > 1) {
                        root.expandClicked(widgetData, widgetIndex);
                    }
                }
            }
        }
    }

    Component {
        id: inputAudioSliderComponent
        Item {
            property var widgetData: parent.widgetData || {}
            property int widgetIndex: parent.widgetIndex || 0
            width: parent.width
            height: 16

            InputAudioSliderRow {
                anchors.centerIn: parent
                width: parent.width
                height: 14
                property color sliderTrackColor: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
            }
        }
    }

    Component {
        id: batteryPillComponent
        BatteryPill {
            property var widgetData: parent.widgetData || {}
            property int widgetIndex: parent.widgetIndex || 0
            width: parent.width
            height: 60

            onExpandClicked: {
                if (!root.editMode) {
                    root.expandClicked(widgetData, widgetIndex);
                }
            }
        }
    }

    Component {
        id: smallBatteryComponent
        SmallBatteryButton {
            property var widgetData: parent.widgetData || {}
            property int widgetIndex: parent.widgetIndex || 0
            width: parent.width
            height: 48

            onClicked: {
                if (!root.editMode) {
                    root.expandClicked(widgetData, widgetIndex);
                }
            }
        }
    }

    Component {
        id: toggleButtonComponent
        ToggleButton {
            property var widgetData: parent.widgetData || {}
            property int widgetIndex: parent.widgetIndex || 0
            width: parent.width
            height: 60

            iconName: {
                switch (widgetData.id || "") {
                case "nightMode":
                    return DisplayService.nightModeEnabled ? "nightlight" : "dark_mode";
                case "darkMode":
                    return "contrast";
                case "doNotDisturb":
                    return SessionData.doNotDisturb ? "do_not_disturb_on" : "do_not_disturb_off";
                case "idleInhibitor":
                    return SessionService.idleInhibited ? "motion_sensor_active" : "motion_sensor_idle";
                default:
                    return "help";
                }
            }

            text: {
                switch (widgetData.id || "") {
                case "nightMode":
                    return I18n.tr("Night Mode");
                case "darkMode":
                    return I18n.tr("Dark Mode");
                case "doNotDisturb":
                    return I18n.tr("Do Not Disturb");
                case "idleInhibitor":
                    return SessionService.idleInhibited ? I18n.tr("Keeping Awake") : I18n.tr("Keep Awake");
                default:
                    return I18n.tr("Unknown", "widget status");
                }
            }

            iconRotation: {
                if (widgetData.id !== "darkMode")
                    return 0;
                if (darkModeTransitionPending) {
                    return SessionData.isLightMode ? 180 : 0;
                }
                return SessionData.isLightMode ? 180 : 0;
            }

            isActive: {
                switch (widgetData.id || "") {
                case "nightMode":
                    return DisplayService.nightModeEnabled || false;
                case "darkMode":
                    return !SessionData.isLightMode;
                case "doNotDisturb":
                    return SessionData.doNotDisturb || false;
                case "idleInhibitor":
                    return SessionService.idleInhibited || false;
                default:
                    return false;
                }
            }

            enabled: !root.editMode

            onClicked: {
                if (root.editMode)
                    return;
                switch (widgetData.id || "") {
                case "nightMode":
                    {
                        if (DisplayService.automationAvailable)
                            DisplayService.toggleNightMode();
                        break;
                    }
                case "darkMode":
                    {
                        const newMode = !SessionData.isLightMode;
                        Theme.screenTransition();
                        Theme.setLightMode(newMode);
                        break;
                    }
                case "doNotDisturb":
                    {
                        SessionData.setDoNotDisturb(!SessionData.doNotDisturb);
                        break;
                    }
                case "idleInhibitor":
                    {
                        SessionService.toggleIdleInhibit();
                        break;
                    }
                }
            }
        }
    }

    Component {
        id: smallToggleComponent
        SmallToggleButton {
            property var widgetData: parent.widgetData || {}
            property int widgetIndex: parent.widgetIndex || 0
            width: parent.width
            height: 48

            iconName: {
                switch (widgetData.id || "") {
                case "nightMode":
                    return DisplayService.nightModeEnabled ? "nightlight" : "dark_mode";
                case "darkMode":
                    return "contrast";
                case "doNotDisturb":
                    return SessionData.doNotDisturb ? "do_not_disturb_on" : "do_not_disturb_off";
                case "idleInhibitor":
                    return SessionService.idleInhibited ? "motion_sensor_active" : "motion_sensor_idle";
                default:
                    return "help";
                }
            }

            iconRotation: {
                if (widgetData.id !== "darkMode")
                    return 0;
                if (darkModeTransitionPending) {
                    return SessionData.isLightMode ? 180 : 0;
                }
                return SessionData.isLightMode ? 180 : 0;
            }

            isActive: {
                switch (widgetData.id || "") {
                case "nightMode":
                    return DisplayService.nightModeEnabled || false;
                case "darkMode":
                    return !SessionData.isLightMode;
                case "doNotDisturb":
                    return SessionData.doNotDisturb || false;
                case "idleInhibitor":
                    return SessionService.idleInhibited || false;
                default:
                    return false;
                }
            }

            enabled: !root.editMode

            onClicked: {
                if (root.editMode)
                    return;
                switch (widgetData.id || "") {
                case "nightMode":
                    {
                        if (DisplayService.automationAvailable)
                            DisplayService.toggleNightMode();
                        break;
                    }
                case "darkMode":
                    {
                        const newMode = !SessionData.isLightMode;
                        Theme.screenTransition();
                        Theme.setLightMode(newMode);
                        break;
                    }
                case "doNotDisturb":
                    {
                        SessionData.setDoNotDisturb(!SessionData.doNotDisturb);
                        break;
                    }
                case "idleInhibitor":
                    {
                        SessionService.toggleIdleInhibit();
                        break;
                    }
                }
            }
        }
    }

    Component {
        id: diskUsagePillComponent
        DiskUsagePill {
            property var widgetData: parent.widgetData || {}
            property int widgetIndex: parent.widgetIndex || 0
            width: parent.width
            height: 60

            mountPath: widgetData.mountPath || "/"
            instanceId: widgetData.instanceId || ""

            onExpandClicked: {
                if (!root.editMode) {
                    root.expandClicked(widgetData, widgetIndex);
                }
            }
        }
    }

    Component {
        id: smallDiskUsageComponent
        SmallDiskUsageButton {
            property var widgetData: parent.widgetData || {}
            property int widgetIndex: parent.widgetIndex || 0
            width: parent.width
            height: 48

            mountPath: widgetData.mountPath || "/"
            instanceId: widgetData.instanceId || ""

            onClicked: {
                if (!root.editMode) {
                    root.expandClicked(widgetData, widgetIndex);
                }
            }
        }
    }

    Component {
        id: colorPickerPillComponent
        ColorPickerPill {
            property var widgetData: parent.widgetData || {}
            property int widgetIndex: parent.widgetIndex || 0
            width: parent.width
            height: 60

            colorPickerModal: root.colorPickerModal
        }
    }

    Component {
        id: builtinPluginWidgetComponent
        Loader {
            property var widgetData: parent.widgetData || {}
            property int widgetIndex: parent.widgetIndex || 0
            property int widgetWidth: widgetData.width || 50
            width: parent.width
            height: 60

            property var builtinInstance: null

            Component.onCompleted: {
                const id = widgetData.id || "";
                if (id === "builtin_vpn") {
                    if (root.model?.vpnLoader) {
                        root.model.vpnLoader.active = true;
                    }
                    builtinInstance = Qt.binding(() => root.model?.vpnBuiltinInstance);
                }
                if (id === "builtin_cups") {
                    if (root.model?.cupsLoader) {
                        root.model.cupsLoader.active = true;
                    }
                    builtinInstance = Qt.binding(() => root.model?.cupsBuiltinInstance);
                }
            }

            sourceComponent: {
                if (!builtinInstance)
                    return null;

                const hasDetail = builtinInstance.ccDetailContent !== null;

                if (widgetWidth <= 25) {
                    return builtinSmallToggleComponent;
                } else if (hasDetail) {
                    return builtinCompoundPillComponent;
                } else {
                    return builtinToggleComponent;
                }
            }
        }
    }

    Component {
        id: builtinCompoundPillComponent
        CompoundPill {
            property var widgetData: parent.widgetData || {}
            property int widgetIndex: parent.widgetIndex || 0
            property var builtinInstance: parent.builtinInstance

            iconName: builtinInstance?.ccWidgetIcon || "extension"
            primaryText: builtinInstance?.ccWidgetPrimaryText || "Built-in"
            secondaryText: builtinInstance?.ccWidgetSecondaryText || ""
            isActive: builtinInstance?.ccWidgetIsActive || false

            onToggled: {
                if (root.editMode)
                    return;
                if (builtinInstance) {
                    builtinInstance.ccWidgetToggled();
                }
            }

            onExpandClicked: {
                if (root.editMode)
                    return;
                if (builtinInstance) {
                    builtinInstance.ccWidgetExpanded();
                }
                root.expandClicked(widgetData, widgetIndex);
            }
        }
    }

    Component {
        id: builtinToggleComponent
        ToggleButton {
            property var widgetData: parent.widgetData || {}
            property int widgetIndex: parent.widgetIndex || 0
            property var builtinInstance: parent.builtinInstance

            iconName: builtinInstance?.ccWidgetIcon || "extension"
            text: builtinInstance?.ccWidgetPrimaryText || "Built-in"
            isActive: builtinInstance?.ccWidgetIsActive || false
            enabled: !root.editMode

            onClicked: {
                if (root.editMode)
                    return;
                if (builtinInstance) {
                    builtinInstance.ccWidgetToggled();
                }
            }
        }
    }

    Component {
        id: builtinSmallToggleComponent
        SmallToggleButton {
            property var widgetData: parent.widgetData || {}
            property int widgetIndex: parent.widgetIndex || 0
            property var builtinInstance: parent.builtinInstance

            iconName: builtinInstance?.ccWidgetIcon || "extension"
            isActive: builtinInstance?.ccWidgetIsActive || false
            enabled: !root.editMode

            onClicked: {
                if (root.editMode)
                    return;
                if (builtinInstance) {
                    builtinInstance.ccWidgetToggled();
                }
            }
        }
    }

    Component {
        id: pluginWidgetComponent
        Loader {
            property var widgetData: parent.widgetData || {}
            property int widgetIndex: parent.widgetIndex || 0
            property int widgetWidth: widgetData.width || 50
            width: parent.width
            height: 60

            property var pluginInstance: null
            property string pluginId: widgetData.id?.replace("plugin_", "") || ""

            sourceComponent: {
                if (!pluginInstance)
                    return null;

                const hasDetail = pluginInstance.ccDetailContent !== null;

                if (widgetWidth <= 25) {
                    return pluginSmallToggleComponent;
                } else if (hasDetail) {
                    return pluginCompoundPillComponent;
                } else {
                    return pluginToggleComponent;
                }
            }

            function tryCreatePluginInstance() {
                const pluginComponent = PluginService.pluginWidgetComponents[pluginId];
                if (!pluginComponent)
                    return false;
                try {
                    const instance = pluginComponent.createObject(null, {
                        "pluginId": pluginId,
                        "pluginService": PluginService,
                        "visible": false,
                        "width": 0,
                        "height": 0
                    });
                    if (instance) {
                        pluginInstance = instance;
                        return true;
                    }
                } catch (e) {
                    console.warn("DragDropGrid: stale plugin component for", pluginId, "- reloading");
                    PluginService.reloadPlugin(pluginId);
                }
                return false;
            }

            Component.onCompleted: {
                Qt.callLater(() => tryCreatePluginInstance());
            }

            Connections {
                target: PluginService
                function onPluginDataChanged(changedPluginId) {
                    if (changedPluginId === pluginId && pluginInstance) {
                        pluginInstance.loadPluginData();
                    }
                }
                function onPluginLoaded(loadedPluginId) {
                    if (loadedPluginId !== pluginId || pluginInstance)
                        return;
                    Qt.callLater(() => tryCreatePluginInstance());
                }
            }

            Component.onDestruction: {
                if (pluginInstance) {
                    pluginInstance.destroy();
                }
            }
        }
    }

    Component {
        id: pluginCompoundPillComponent
        CompoundPill {
            property var widgetData: parent.widgetData || {}
            property int widgetIndex: parent.widgetIndex || 0
            property var pluginInstance: parent.pluginInstance

            iconName: pluginInstance?.ccWidgetIcon || "extension"
            primaryText: pluginInstance?.ccWidgetPrimaryText || "Plugin"
            secondaryText: pluginInstance?.ccWidgetSecondaryText || ""
            isActive: pluginInstance?.ccWidgetIsActive || false

            onToggled: {
                if (root.editMode)
                    return;
                if (pluginInstance) {
                    pluginInstance.ccWidgetToggled();
                }
            }

            onExpandClicked: {
                if (root.editMode)
                    return;
                if (pluginInstance) {
                    pluginInstance.ccWidgetExpanded();
                }
                root.expandClicked(widgetData, widgetIndex);
            }
        }
    }

    Component {
        id: pluginToggleComponent
        ToggleButton {
            property var widgetData: parent.widgetData || {}
            property int widgetIndex: parent.widgetIndex || 0
            property var pluginInstance: parent.pluginInstance
            property var widgetDef: root.model?.getWidgetForId(widgetData.id || "")

            iconName: pluginInstance?.ccWidgetIcon || widgetDef?.icon || "extension"
            text: pluginInstance?.ccWidgetPrimaryText || widgetDef?.text || "Plugin"
            secondaryText: pluginInstance?.ccWidgetSecondaryText || ""
            isActive: pluginInstance?.ccWidgetIsActive || false
            enabled: !root.editMode

            onClicked: {
                if (root.editMode)
                    return;
                if (pluginInstance) {
                    pluginInstance.ccWidgetToggled();
                }
            }
        }
    }

    Component {
        id: pluginSmallToggleComponent
        SmallToggleButton {
            property var widgetData: parent.widgetData || {}
            property int widgetIndex: parent.widgetIndex || 0
            property var pluginInstance: parent.pluginInstance
            property var widgetDef: root.model?.getWidgetForId(widgetData.id || "")

            iconName: pluginInstance?.ccWidgetIcon || widgetDef?.icon || "extension"
            isActive: pluginInstance?.ccWidgetIsActive || false
            enabled: !root.editMode

            onClicked: {
                if (root.editMode)
                    return;
                if (pluginInstance && pluginInstance.ccDetailContent) {
                    root.expandClicked(widgetData, widgetIndex);
                } else if (pluginInstance) {
                    pluginInstance.ccWidgetToggled();
                }
            }
        }
    }
}
