// Headless theme editor, for accent-controls-contract.
//
// The two halves of the editor that write colour: the four wells
// (ThemeEditorWells + ColorWell), which are the fast path and own hex
// validation and the eyedropper, and the six HSV rows (AccentEditor), which
// are the fine-tune behind a disclosure.
//
// AccentEditor commits on a debounce rather than per move, so `adjust` returns
// what is *pending*, not what is stored -- the caller waits and reads `status`
// again. That is the behaviour under test as much as the colour itself: a
// slider that wrote on every move spent a whole drag in apply-and-verify round
// trips and left the desktop repainting behind the pointer.

import Quickshell
import Quickshell.Io
import QtQuick

import qs.config
import qs.modules.settings
import qs.services

ShellRoot {
    Item {
        width: 680
        height: wells.implicitHeight + editor.implicitHeight

        ThemeEditorWells {
            id: wells
            width: parent.width
        }

        AccentEditor {
            id: editor
            y: wells.implicitHeight
            width: parent.width
        }
    }

    IpcHandler {
        target: "accent-controls-test"

        function status(): string {
            return JSON.stringify({
                id: ThemeProfiles.activeProfile.id,
                name: ThemeProfiles.activeProfile.name,
                scheme: ThemeProfiles.activeProfile.scheme,
                accent: String(ThemeProfiles.activeProfile.accent),
                secondary: String(ThemeProfiles.activeProfile.secondary),
                shipped: ThemeProfiles.activeProfile.shipped === true,
                accentName: String(DesktopPreferences.get("accentName")),
                bg: String(ThemeProfiles.activePalette.bg),
                fg: String(ThemeProfiles.activePalette.fg),
                fgDim: String(ThemeProfiles.activePalette.fgDim),
                pending: editor.pending !== null,
                wellError: wells.lastError
            });
        }

        // Moves one HSV slider. The commit is debounced, so the answer is the
        // pair the sliders are showing, not the stored one.
        function adjust(target: string, channel: string, ratio: real): string {
            editor.changeChannel(target, channel, ratio);
            return JSON.stringify({
                shown: { accent: editor.shownAccent, secondary: editor.shownSecondary },
                pending: editor.pending !== null,
                stored: {
                    accent: String(ThemeProfiles.activeProfile.accent),
                    secondary: String(ThemeProfiles.activeProfile.secondary)
                }
            });
        }

        // The one path every well takes -- typed hex, colour wheel and
        // eyedropper all end here, so validation cannot differ between them.
        function well(which: string, hex: string): string {
            wells.apply(which, hex);
            return status();
        }
    }
}
