import QtQuick
import qs.config
import qs.services

SettingsPage {
    id: root

    objectName: "system-health-page"

    title: "System Health"
    lede: "Checks the parts of the desktop this app owns, and explains what needs attention."

    property var pendingConfirmation: null
    property string instructionTarget: ""

    readonly property var issueChecks: Health.checks.filter(check => check.status === "warning" || check.status === "error")
    readonly property var groups: [
        {
            group: "desktop-foundation",
            title: "Desktop foundation",
            subtitle: "Compositor, shell, portals, wallpaper, idle policy, and launcher."
        },
        {
            group: "input-media",
            title: "Input & media",
            subtitle: "Sound, clipboard, capture, OCR, and display controls."
        },
        {
            group: "integrations",
            title: "Integrations",
            subtitle: "Only configured integrations affect health."
        },
        {
            group: "panama-tools",
            title: "Desktop tools",
            subtitle: "Tracked links, launcher commands, apps, and inhibitors."
        }
    ]
    readonly property var applicationTargets: ({
        "integration.nextcloud": "nextcloud",
        "integration.rustdesk": "rustdesk",
        "integration.kdeconnect": "kdeconnect",
        "integration.bluebubbles": "bluebubbles"
    })

    function statusLabel(status: string): string {
        if (status === "ok") return "Healthy";
        if (status === "warning") return "Needs attention";
        if (status === "error") return "Action required";
        return "Not set up";
    }

    function checksForGroup(group: string): var {
        return Health.checks.filter(check => check.group === group
            && (check.status === "ok" || check.status === "unconfigured"));
    }

    function handleAction(check: var): void {
        if (!check || !check.action)
            return;

        if (check.action.kind === "open") {
            if (check.action.target) {
                ShellState.openSettings(check.action.target);
                return;
            }
            const application = root.applicationTargets[check.id];
            if (application)
                SystemSettings.openApplication(application);
            return;
        }

        if (check.action.kind === "instructions") {
            root.instructionTarget = check.action.target || "";
            return;
        }

        if (check.action.kind !== "repair")
            return;
        if (check.action.confirm) {
            root.pendingConfirmation = check;
            return;
        }
        Health.repair(check.id, false);
    }

    function confirmRepair(): void {
        const check = root.pendingConfirmation;
        root.pendingConfirmation = null;
        if (check)
            Health.repair(check.id, false);
    }

    function descendants(item: var, prefix: string): var {
        let matches = [];
        if (!item)
            return matches;
        if (String(item.objectName || "").indexOf(prefix) === 0)
            matches.push(item);
        for (const child of item.children || [])
            matches = matches.concat(root.descendants(child, prefix));
        return matches;
    }

    function activateRenderedAction(id: string): bool {
        const suffix = `:${id}`;
        const rows = root.descendants(root, "health-check-row:").filter(row =>
            row.visible && String(row.objectName).endsWith(suffix));
        return rows.length === 1 && rows[0].activateAction();
    }

    function renderedFocusChain(): var {
        // Repeater delegates enter Qt's tab chain lazily after their enabled
        // binding changes at the end of a scan. Touch each rendered action's
        // real next-focus link before traversing from the first hero control.
        const renderedActions = root.descendants(root, "health-row-action:").filter(item =>
            item.visible && item.enabled && item.activeFocusOnTab);
        for (const action of renderedActions)
            action.nextItemInFocusChain(true);

        const starts = root.descendants(root, "health-copy-report-button").filter(item => item.visible && item.enabled);
        if (starts.length !== 1)
            return [];

        const names = [];
        const start = starts[0];
        let current = start;
        for (let index = 0; index < 128; index++) {
            const name = String(current.objectName || "");
            if (name !== "" && names.indexOf(name) < 0)
                names.push(name);
            current = current.nextItemInFocusChain(true);
            if (!current || current === start)
                break;
        }
        return names;
    }

    // Deterministic, read-only fixture seam used by the offscreen contract.
    function uiDiagnostics(): var {
        const summaries = root.descendants(root, "health-summary");
        const rows = root.descendants(root, "health-check-row:").filter(row => row.visible);
        const checkingLabels = root.descendants(root, "health-checking-label").filter(label => label.visible);
        const confirmationSheets = root.descendants(root, "health-confirmation-sheet:").filter(sheet => sheet.visible);
        const emptyGroups = root.descendants(root, "health-empty-group:").filter(label => label.visible);
        const fedoraHandoffs = root.descendants(root, "health-fedora-handoff:").filter(row => row.visible);
        return {
            renderedRows: rows.map(row => {
                const objectName = String(row.objectName);
                const parts = objectName.split(":");
                const statusTexts = root.descendants(row, "health-status-text:").filter(text => text.visible);
                return {
                    objectName: objectName,
                    id: parts.slice(2).join(":"),
                    section: parts[1],
                    statusText: statusTexts.length === 1 ? statusTexts[0].text : ""
                };
            }),
            summaryHeight: summaries.length > 0 ? summaries[0].height : 0,
            rowHeights: rows.map(row => row.height),
            checking: Health.busy,
            checkingText: checkingLabels.length > 0 ? checkingLabels[0].text : "",
            focusChain: root.renderedFocusChain(),
            activatedRows: rows.filter(row => row.actionActivationCount > 0).map(row => String(row.objectName)),
            emptyQuietGroups: emptyGroups.map(label => String(label.objectName).slice("health-empty-group:".length)),
            fedoraHandoffs: fedoraHandoffs.map(row => ({
                id: String(row.objectName).slice("health-fedora-handoff:".length),
                label: row.label,
                action: row.action
            })),
            confirmationVisible: confirmationSheets.length === 1,
            confirmationId: confirmationSheets.length === 1
                ? String(confirmationSheets[0].objectName).slice("health-confirmation-sheet:".length)
                : ""
        };
    }

    Component.onCompleted: Health.refresh()

    header: Component {
        Rectangle {
            objectName: `health-confirmation-sheet:${root.pendingConfirmation ? root.pendingConfirmation.id : ""}`
            visible: root.pendingConfirmation !== null
            implicitHeight: visible ? confirmRow.implicitHeight + 28 : 0
            radius: Theme.cardRadius
            color: Theme.mix(Theme.bgPanel, Theme.warn, 0.1)
            border.width: 1
            border.color: Theme.alpha(Theme.warn, 0.34)

            Row {
                id: confirmRow
                anchors.left: parent.left
                anchors.right: parent.right
                anchors.verticalCenter: parent.verticalCenter
                anchors.margins: 16
                spacing: 14

                Column {
                    width: parent.width - cancelButton.width - repairButton.width - 28
                    anchors.verticalCenter: parent.verticalCenter
                    spacing: 3

                    Text {
                        width: parent.width
                        text: root.pendingConfirmation
                            ? `${root.pendingConfirmation.action.label}?`
                            : "Restart the shell?"
                        color: Theme.fg
                        font.family: Theme.fontFamily
                        font.pixelSize: Theme.fontSize
                        font.weight: Font.DemiBold
                    }

                    Text {
                        width: parent.width
                        text: "The desktop chrome will disappear briefly and return when Quickshell restarts."
                        color: Theme.fgDim
                        font.family: Theme.fontFamily
                        font.pixelSize: Theme.fontSizeSmall
                        wrapMode: Text.WordWrap
                    }
                }

                SettingsButton {
                    id: cancelButton
                    text: "Cancel"
                    activeFocusOnTab: true
                    border.width: activeFocus ? 2 : 1
                    border.color: activeFocus ? Theme.accent : Theme.alpha(Theme.fg, 0.08)
                    onClicked: root.pendingConfirmation = null
                    Keys.onReturnPressed: root.pendingConfirmation = null
                    Keys.onSpacePressed: root.pendingConfirmation = null
                }

                SettingsButton {
                    id: repairButton
                    text: root.pendingConfirmation ? root.pendingConfirmation.action.label : "Restart the shell"
                    activeFocusOnTab: true
                    border.width: activeFocus ? 2 : 1
                    border.color: activeFocus ? Theme.accent : Theme.alpha(Theme.fg, 0.08)
                    onClicked: root.confirmRepair()
                    Keys.onReturnPressed: root.confirmRepair()
                    Keys.onSpacePressed: root.confirmRepair()
                }
            }
        }
    }

    HealthSummary {}

    SettingsCard {
        visible: root.issueChecks.length > 0
        title: Health.status === "error" ? "Action required" : "Needs attention"
        subtitle: Health.status === "error"
            ? "Resolve these items first. Healthy systems remain listed below."
            : "Nothing here prevents you from using the desktop."

        Item {
            width: parent.width
            implicitHeight: issueRows.implicitHeight

            Rectangle {
                anchors.left: parent.left
                anchors.leftMargin: 4
                anchors.top: parent.top
                anchors.topMargin: 25
                anchors.bottom: parent.bottom
                anchors.bottomMargin: 25
                width: 1
                visible: root.issueChecks.length > 1
                color: Theme.alpha(Health.status === "error" ? Theme.danger : Theme.warn, 0.44)
            }

            Column {
                id: issueRows
                width: parent.width

                Repeater {
                    id: issueRepeater
                    model: root.issueChecks

                    HealthCheckRow {
                        required property var modelData
                        required property int index

                        width: issueRows.width
                        check: modelData
                        issue: true
                        divider: index < issueRepeater.count - 1
                        onActionRequested: check => root.handleAction(check)
                    }
                }
            }
        }
    }

    SettingsCard {
        visible: root.instructionTarget === "ddc-permissions"
        title: "External monitor brightness"
        subtitle: "The monitor reports DDC/CI support, but this session cannot reach the monitor bus."

        Item {
            width: parent.width
            implicitHeight: Math.max(instructionCopy.implicitHeight, doneButton.implicitHeight) + 8

            Text {
                id: instructionCopy
                anchors.left: parent.left
                anchors.right: doneButton.left
                anchors.rightMargin: 18
                anchors.verticalCenter: parent.verticalCenter
                text: "Reload the installed udev rules and trigger the i2c-dev and DRM devices. Sign out and back in if monitor access is still unavailable."
                color: Theme.fgDim
                font.family: Theme.fontFamily
                font.pixelSize: Theme.fontSizeSmall
                wrapMode: Text.WordWrap
            }

            SettingsButton {
                id: doneButton
                anchors.right: parent.right
                anchors.verticalCenter: parent.verticalCenter
                text: "Done"
                activeFocusOnTab: true
                border.width: activeFocus ? 2 : 1
                border.color: activeFocus ? Theme.accent : Theme.alpha(Theme.fg, 0.08)
                onClicked: root.instructionTarget = ""
                Keys.onReturnPressed: root.instructionTarget = ""
                Keys.onSpacePressed: root.instructionTarget = ""
            }
        }
    }

    Grid {
        id: groupGrid

        width: parent.width
        columns: width >= 700 ? 2 : 1
        columnSpacing: 16
        rowSpacing: 16

        Repeater {
            model: root.groups

            SettingsCard {
                required property var modelData
                readonly property var quietChecks: root.checksForGroup(modelData.group)

                width: groupGrid.columns === 2
                    ? (groupGrid.width - groupGrid.columnSpacing) / 2
                    : groupGrid.width
                title: modelData.title
                subtitle: modelData.subtitle

                Column {
                    id: groupRows
                    width: parent.width

                    Text {
                        objectName: `health-empty-group:${modelData.group}`
                        width: parent.width
                        visible: quietChecks.length === 0
                        text: "Items needing attention are listed above."
                        color: Theme.fgMuted
                        font.family: Theme.fontFamily
                        font.pixelSize: Theme.fontSizeSmall
                        topPadding: 8
                        bottomPadding: 8
                        wrapMode: Text.WordWrap
                    }

                    Repeater {
                        id: groupRepeater
                        model: quietChecks

                        HealthCheckRow {
                            required property var modelData
                            required property int index

                            width: groupRows.width
                            check: modelData
                            divider: index < groupRepeater.count - 1
                            onActionRequested: check => root.handleAction(check)
                        }
                    }
                }
            }
        }
    }

    SettingsCard {
        title: "Fedora system settings"
        subtitle: "These areas remain owned by Fedora and GNOME's mature system panels."

        Item {
            width: parent.width
            implicitHeight: 42

            Text {
                anchors.left: parent.left
                anchors.right: gnomeSettingsButton.left
                anchors.rightMargin: 18
                anchors.verticalCenter: parent.verticalCenter
                text: "Use GNOME Settings for the parts of the system this app does not manage."
                color: Theme.fgDim
                font.family: Theme.fontFamily
                font.pixelSize: Theme.fontSizeSmall
                wrapMode: Text.WordWrap
            }

            SettingsButton {
                id: gnomeSettingsButton
                anchors.right: parent.right
                anchors.verticalCenter: parent.verticalCenter
                text: "Open GNOME Settings"
                activeFocusOnTab: true
                border.width: activeFocus ? 2 : 1
                border.color: activeFocus ? Theme.accent : Theme.alpha(Theme.fg, 0.08)
                onClicked: SystemSettings.openGnomePanel("network")
                Keys.onReturnPressed: SystemSettings.openGnomePanel("network")
                Keys.onSpacePressed: SystemSettings.openGnomePanel("network")
            }
        }

        ActionRow {
            objectName: "health-fedora-handoff:color"
            label: "Color profiles"
            detail: "Assigning an ICC profile here has no visible effect in this session: the colord daemon that loads it onto a display isn't running under Hyprland"
            action: "Open color"
            onTriggered: SystemSettings.openGnomePanel("color")
        }

        ActionRow {
            objectName: "health-fedora-handoff:wellbeing"
            label: "Digital wellbeing"
            detail: "Screen time and break reminders"
            action: "Open wellbeing"
            divider: false
            onTriggered: SystemSettings.openGnomePanel("wellbeing")
        }
    }
}
