// Appearance — the page the rest of the settings vocabulary was built for.
//
// Before Stage 3 this page adjusted a clock format and three vitals toggles,
// and its "Theme" card was two rows of text pretending to be controls. It now
// drives the compositor directly: every row here is applied through
// `hyprctl eval` and confirmed by reading the value back before it is stored.
//
// The preview is pinned above the controls rather than sitting inline, because
// the numbers are meaningless on their own -- "outer gaps 24" only means
// something once you have watched the windows move apart by that much, at the
// scale of the display you actually use.

import QtQuick
import qs.config
import qs.services

SettingsPage {
    id: root

    property string expandedPicker: ""

    // Which group of cards is on screen. Theme leads deliberately: light and
    // dark is the control reached most often, and it used to be the third
    // section down, below a wallpaper grid and the whole lock screen.
    property string tab: "theme"

    // Arriving from another page that named a section opens on it. Taken once
    // rather than bound, so the tabs still work normally afterwards.
    Component.onCompleted: {
        const section = ShellState.takeSettingsSection();
        if (section !== "")
            root.tab = section;
    }

    title: "Appearance"
    lede: "Tune the Prism shell and the applications that live inside it. The preview above is your real geometry, to scale."

    header: Component {
        Column {
            spacing: 9

            DesktopPreview {
                width: parent.width
            }

            Text {
                width: parent.width
                horizontalAlignment: Text.AlignHCenter
                text: SystemSettings.lastError !== ""
                    ? SystemSettings.lastError
                    : "Live preview — the focused window wears the prism border"
                color: SystemSettings.lastError !== "" ? Theme.warn : Theme.fgMuted
                font.family: Theme.fontFamily
                font.pixelSize: Theme.fontSizeSmall
                elide: Text.ElideRight
            }
        }
    }

    SettingsTabs {
        tabs: [
            { value: "theme", label: "Theme" },
            { value: "background", label: "Background" },
            { value: "type", label: "Typography" },
            { value: "windows", label: "Windows" },
            { value: "shell", label: "Shell" },
        ]
        current: root.tab
        onSelected: value => root.tab = value
    }

    SettingsCard {
        visible: root.tab === "background"
        title: "Background"
        subtitle: Wallpaper.lastError !== ""
            ? Wallpaper.lastError
            : "Applied to every display, from the folder below."

        TextEntryRow { setting: "wallpaperDir"; placeholder: "Pictures/Wallpapers" }

        WallpaperControls {
            id: wallpaperControls
            width: parent.width
        }

        WallpaperPicker {
            id: wallpapers
            width: parent.width
            mode: wallpaperControls.mode
            selectedOutput: wallpaperControls.selectedOutput
        }

        ActionRow {
            visible: wallpapers.hidden > 0 || wallpapers.expanded
            label: wallpapers.expanded ? "Showing every image" : wallpapers.hidden + " more available"
            detail: "The grid is kept short so the rest of this page stays reachable"
            action: wallpapers.expanded ? "Show fewer" : "Show all"
            onTriggered: wallpapers.expanded = !wallpapers.expanded
        }

        ActionRow {
            label: "Look for new images"
            detail: Wallpaper.scanning
                ? "Scanning…"
                : Wallpaper.available.length + " image" + (Wallpaper.available.length === 1 ? "" : "s") + " found"
            action: "Rescan"
            divider: false
            enabled: !Wallpaper.scanning
            onTriggered: Wallpaper.rescan()
        }
    }

    SettingsCard {
        visible: root.tab === "background"
        title: "Lock screen"
        subtitle: LockScreen.lastError !== ""
            ? LockScreen.lastError
            : "A representative preview of the screen shown before authentication."

        LockScreenPreview {
            width: parent.width
        }

        ChoiceRow { setting: "lockBackgroundMode" }
        SliderRow { setting: "lockBlurLevel"; zeroLabel: "Off" }
        ToggleRow { setting: "lockShowClock" }
        ToggleRow { setting: "lockShowDate" }
        ToggleRow { setting: "lockShowUser" }
        ToggleRow { setting: "lockFadeOnEmpty"; divider: false }
    }

    SettingsCard {
        visible: root.tab === "theme"
        // Not "Color scheme" any more: the card holds the saved themes as well
        // as the scheme, and a theme carries both ends of the accent with it.
        title: "Theme"
        subtitle: ColorScheme.lastError !== ""
            ? ColorScheme.lastError
            : "Start with Moon, Moon Rose, or Day; saved themes capture the scheme and both ends of the Prism accent."

        ThemeProfilePicker {
            width: parent.width
        }

        // Drawn as the gradient each accent produces rather than a flat dot,
        // because the gradient is what is being chosen.
        AccentPicker {
            width: parent.width
        }

        AccentEditor {
            width: parent.width
        }
    }

    SettingsCard {
        visible: root.tab === "type"
        title: "Shell typography"
        subtitle: Fonts.lastError !== ""
            ? Fonts.lastError
            : "Every piece of text in the shell. Samples are drawn in the font they name."

        SliderRow { setting: "interfaceFontSize" }

        TextRow {
            label: "Interface font"
            detail: Fonts.interfaceMissing
                ? "Not installed on this machine — fontconfig is substituting something else"
                : "Used for all shell text"
            value: Fonts.interfaceFont
        }

        FontPicker {
            width: parent.width
            families: Fonts.interfaceFonts
            current: Fonts.interfaceFont
            emptyText: Fonts.scanning ? "Reading installed fonts…" : "No interface fonts found"
            onPicked: family => Fonts.setInterface(family)
        }

        TextRow {
            label: "Icon font"
            detail: Fonts.iconMissing
                ? "Not installed — the shell's glyphs will not draw correctly"
                : "Draws the shell's glyphs, so only Nerd Fonts are offered"
            value: Fonts.iconFont
        }

        FontPicker {
            width: parent.width
            families: Fonts.iconFonts
            current: Fonts.iconFont
            emptyText: "No Nerd Fonts installed"
            onPicked: family => Fonts.setIcon(family)
        }
    }

    SettingsCard {
        visible: root.tab === "type"
        title: "Application typography"
        subtitle: DesktopStyle.lastError !== ""
            ? DesktopStyle.lastError
            : "Fonts used by applications that follow the desktop defaults. Open one family at a time to keep the page calm."

        ActionRow {
            label: "Application font"
            detail: DesktopStyle.applicationFont
            action: root.expandedPicker === "application-font" ? "Close" : "Choose"
            onTriggered: root.expandedPicker = root.expandedPicker === "application-font" ? "" : "application-font"
        }

        FontPicker {
            visible: root.expandedPicker === "application-font"
            width: parent.width
            families: Fonts.interfaceFonts
            current: DesktopStyle.applicationFont
            emptyText: Fonts.scanning ? "Reading installed fonts…" : "No application fonts found"
            onPicked: family => {
                if (DesktopStyle.setApplicationFont(family))
                    root.expandedPicker = "";
            }
        }

        SliderRow { setting: "applicationFontSize" }

        ActionRow {
            label: "Document font"
            detail: DesktopStyle.documentFont
            action: root.expandedPicker === "document-font" ? "Close" : "Choose"
            onTriggered: root.expandedPicker = root.expandedPicker === "document-font" ? "" : "document-font"
        }

        FontPicker {
            visible: root.expandedPicker === "document-font"
            width: parent.width
            families: Fonts.interfaceFonts
            current: DesktopStyle.documentFont
            emptyText: Fonts.scanning ? "Reading installed fonts…" : "No document fonts found"
            onPicked: family => {
                if (DesktopStyle.setDocumentFont(family))
                    root.expandedPicker = "";
            }
        }

        SliderRow { setting: "documentFontSize" }

        ActionRow {
            label: "Monospace font"
            detail: DesktopStyle.monospaceFont
            action: root.expandedPicker === "monospace-font" ? "Close" : "Choose"
            onTriggered: root.expandedPicker = root.expandedPicker === "monospace-font" ? "" : "monospace-font"
        }

        FontPicker {
            visible: root.expandedPicker === "monospace-font"
            width: parent.width
            families: Fonts.monospaceFonts
            current: DesktopStyle.monospaceFont
            emptyText: Fonts.scanning ? "Reading installed fonts…" : "No monospace fonts found"
            onPicked: family => {
                if (DesktopStyle.setMonospaceFont(family))
                    root.expandedPicker = "";
            }
        }

        SliderRow { setting: "monospaceFontSize" }
        ChoiceRow { setting: "fontHinting" }
        ChoiceRow { setting: "fontAntialiasing"; divider: false }
    }

    SettingsCard {
        visible: root.tab === "type"
        title: "Icons & pointer"
        subtitle: DesktopStyle.lastError !== ""
            ? DesktopStyle.lastError
            : "Installed themes only. The pointer updates in applications and Hyprland together."

        ActionRow {
            label: "Application icons"
            detail: DesktopStyle.iconTheme
            action: root.expandedPicker === "icon-theme" ? "Close" : "Choose"
            enabled: DesktopStyle.catalogLoaded
            onTriggered: root.expandedPicker = root.expandedPicker === "icon-theme" ? "" : "icon-theme"
        }

        SearchPicker {
            visible: root.expandedPicker === "icon-theme"
            width: parent.width
            items: DesktopStyle.iconThemes
            current: DesktopStyle.iconTheme
            placeholder: "Search icon themes"
            emptyText: DesktopStyle.scanning ? "Reading installed icon themes…" : "No icon themes found"
            onPicked: value => {
                if (DesktopStyle.setIconTheme(value))
                    root.expandedPicker = "";
            }
        }

        ActionRow {
            label: "Pointer theme"
            detail: DesktopStyle.cursorTheme
            action: root.expandedPicker === "cursor-theme" ? "Close" : "Choose"
            enabled: DesktopStyle.catalogLoaded
            divider: false
            onTriggered: root.expandedPicker = root.expandedPicker === "cursor-theme" ? "" : "cursor-theme"
        }

        SearchPicker {
            visible: root.expandedPicker === "cursor-theme"
            width: parent.width
            items: DesktopStyle.cursorThemes
            current: DesktopStyle.cursorTheme
            placeholder: "Search pointer themes"
            emptyText: DesktopStyle.scanning ? "Reading installed pointer themes…" : "No pointer themes found"
            onPicked: value => {
                if (DesktopStyle.setCursorTheme(value))
                    root.expandedPicker = "";
            }
        }
    }

    SettingsCard {
        visible: root.tab === "windows"
        title: "Titlebars"
        subtitle: "For applications that draw GNOME-compatible titlebars. Hyprland itself does not add titlebar buttons to tiled windows."

        ChoiceRow { setting: "titlebarButtonSide" }
        ToggleRow { setting: "titlebarMaximizeButton" }
        ChoiceRow { setting: "titlebarDoubleClick"; divider: false }
    }

    SettingsCard {
        visible: root.tab === "windows"
        title: "Windows"
        subtitle: "Spacing and shape of tiled windows. Each change is applied to the compositor and confirmed before it is saved."

        SliderRow { setting: "windowRounding" }
        SliderRow { setting: "gapsIn" }
        SliderRow { setting: "gapsOut" }
        SliderRow { setting: "borderSize"; zeroLabel: "None" }
        SliderRow { setting: "roundingPower" }
        SliderRow { setting: "inactiveOpacity" }
        SliderRow { setting: "activeOpacity" }
        SliderRow { setting: "fullscreenOpacity"; divider: false }
    }

    SettingsCard {
        visible: root.tab === "theme"
        title: "Effects"
        subtitle: "Each of these costs frame time. Turning one off is a legitimate way to buy it back while gaming."

        ToggleRow { setting: "blurEnabled" }
        SliderRow { setting: "blurSize" }
        SliderRow { setting: "blurPasses" }
        ToggleRow { setting: "shadowEnabled" }
        SliderRow { setting: "shadowRange"; zeroLabel: "None" }
        SliderRow { setting: "shadowRenderPower" }
        ToggleRow { setting: "shadowSharp" }
        ToggleRow { setting: "glowEnabled" }
        SliderRow { setting: "glowRange"; zeroLabel: "None" }
        ToggleRow { setting: "animationsEnabled"; divider: false }
    }

    SettingsCard {
        visible: root.tab === "shell"
        title: "Clock"

        ToggleRow { setting: "use24Hour" }
        ToggleRow { setting: "showSeconds" }
        ToggleRow { setting: "showWeekday"; divider: false }
    }

    SettingsCard {
        visible: root.tab === "shell"
        title: "System vitals"
        subtitle: "Choose what appears beside the workspace indicator."

        ToggleRow { setting: "showCpu" }
        ToggleRow { setting: "showMemory" }
        ToggleRow { setting: "showGpu"; divider: true }
        // Refresh interval was on the Home page, which split one concept across
        // two pages -- what the vitals show here, how often they update there.
        SliderRow { setting: "vitalsIntervalMs"; divider: GraphicsDevices.devices.length > 1 || GraphicsDevices.selectionMissing }

        // Only worth asking when there is a choice to make.
        ChoiceGrid {
            visible: GraphicsDevices.devices.length > 1 || GraphicsDevices.selectionMissing
            width: parent.width
            label: "Graphics device"
            detail: GraphicsDevices.selectionMissing
                ? "The stored device is not present on this machine, so the graphics readout is hidden. Choose one below."
                : "Which GPU the graphics readout measures."
            options: GraphicsDevices.devices.map(device => ({
                value: device.path,
                label: GraphicsDevices.shortName(device.name)
            }))
            current: GraphicsDevices.selectedPath
            divider: false
            onPicked: value => GraphicsDevices.select(value)
        }
    }

}
