#!/usr/bin/env bash

set -euo pipefail

repo_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../.." && pwd)"
settings="$repo_dir/config/dot/quickshell/modules/settings"
theme="$repo_dir/config/dot/quickshell/config/Theme.qml"
scheme="$repo_dir/config/dot/quickshell/services/ColorScheme.qml"
search="$repo_dir/config/dot/quickshell/services/SettingsSearch.qml"

fail() {
    printf 'accent controls contract: %s\n' "$1" >&2
    exit 1
}

for component in AccentPicker AccentEditor ThemeProfilePicker; do
    [[ -f "$settings/$component.qml" ]] || fail "$component is missing"
    rg -Fq "$component 1.0 $component.qml" "$settings/qmldir" \
        || fail "$component is not registered in the settings module"
done

for label in \
    'Primary hue' 'Primary saturation' 'Primary value' \
    'Secondary hue' 'Secondary saturation' 'Secondary value'; do
    rg -Fq "$label" "$settings/AccentEditor.qml" \
        || fail "HSV control is missing the visible label $label"
done

rg -Fq 'ValueSlider {' "$settings/AccentEditor.qml" \
    || fail 'advanced accents do not reuse ValueSlider'
rg -Fq 'Accessible.role: Accessible.Slider' "$settings/AccentEditor.qml" \
    || fail 'HSV controls do not expose slider semantics'
rg -Fq 'Accessible.name: root.label' "$settings/AccentEditor.qml" \
    || fail 'HSV controls are not programmatically labelled'
rg -Fq 'Accessible.description:' "$settings/AccentEditor.qml" \
    || fail 'HSV controls do not expose their numeric value as a non-hue signal'
rg -Fq 'activeFocusOnTab: true' "$settings/AccentEditor.qml" \
    || fail 'HSV controls cannot receive keyboard focus'
rg -Fq 'Keys.onPressed:' "$settings/AccentEditor.qml" \
    || fail 'HSV controls cannot be adjusted from the keyboard'
rg -Fq 'activeFocus ? Theme.accentSecondary' "$settings/AccentEditor.qml" \
    || fail 'HSV controls have no visible keyboard focus treatment'

rg -Fq '["hyprpicker", "--format=hex", "--lowercase-hex", "--quiet", "--no-fancy"]' \
    "$settings/AccentEditor.qml" \
    || fail 'screen picking does not use the validated hyprpicker hex invocation'
for target in 'Pick primary from screen' 'Pick secondary from screen'; do
    rg -Fq "$target" "$settings/AccentEditor.qml" \
        || fail "screen picker action is missing $target"
done

# The curated swatches come from the accentName schema rather than from
# Object.keys(Theme.accents): the schema's option order is the palette's order,
# and it is the same source every other enum row reads. What matters here is
# unchanged -- the curated accents are still one click away, ahead of the
# editor.
rg -Fq 'PreferenceSchema.spec("accentName")' "$settings/AccentPicker.qml" \
    || fail 'curated swatches are no longer sourced from the accent schema'
rg -Fq 'model: root.options' "$settings/AccentPicker.qml" \
    || fail 'curated swatches are no longer the fast path'
rg -Fq 'ThemeProfiles.useCuratedAccent(entry.modelData)' "$settings/AccentPicker.qml" \
    || fail 'curated swatches do not select a profile-backed accent'
rg -Fq 'readonly property string current: ThemeProfiles.activeAccentName' "$settings/AccentPicker.qml" \
    || fail 'swatch selection does not follow the active profile'
rg -Fq 'Accessible.name: entry.pair.label + " accent"' "$settings/AccentPicker.qml" \
    || fail 'swatches rely on hue without a programmatic name'
rg -Fq 'activeFocusOnTab: true' "$settings/AccentPicker.qml" \
    || fail 'swatches cannot receive keyboard focus'
rg -Fq 'Keys.onReturnPressed:' "$settings/AccentPicker.qml" \
    || fail 'swatches cannot be selected from the keyboard'

rg -Fq 'model: ThemeProfiles.profiles' "$settings/ThemeProfilePicker.qml" \
    || fail 'profile picker does not show shipped and saved profiles'
rg -Fq 'ThemeProfiles.selectProfile(' "$settings/ThemeProfilePicker.qml" \
    || fail 'profile switching is not wired'
rg -Fq 'ThemeProfiles.saveProfile(' "$settings/ThemeProfilePicker.qml" \
    || fail 'profile saving is not wired'
rg -Fq 'maximumLength: 40' "$settings/ThemeProfilePicker.qml" \
    || fail 'profile names are not visibly bounded to the model limit'
rg -Fq 'ThemeProfiles.deleteProfile(' "$settings/ThemeProfilePicker.qml" \
    || fail 'custom profile deletion is not wired'
rg -Fq 'activeFocusOnTab:' "$settings/ThemeProfilePicker.qml" \
    || fail 'profile actions cannot receive keyboard focus'
rg -Fq 'Keys.onReturnPressed:' "$settings/ThemeProfilePicker.qml" \
    || fail 'profile actions cannot be triggered from the keyboard'

for component in ThemeProfilePicker AccentPicker AccentEditor; do
    rg -Fq "$component {" "$settings/AppearancePage.qml" \
        || fail "Appearance does not include $component"
done

rg -Fq 'ThemeProfiles.activeProfile' "$theme" \
    || fail 'Theme roles do not react to the selected profile'
rg -Fq 'root.hyprColor(Theme.accent)' "$scheme" \
    || fail 'the focused border start does not follow Theme.accent'
rg -Fq 'root.hyprColor(Theme.accentSecondary)' "$scheme" \
    || fail 'the focused border end does not follow Theme.accentSecondary'

for term in 'Theme profiles' 'Advanced accent' 'Pick colour from screen'; do
    rg -Fq "$term" "$search" || fail "Settings search is missing $term"
done

if rg -n 'NumberAnimation|ColorAnimation|SequentialAnimation|ParallelAnimation|loops:[[:space:]]*Animation\.Infinite' \
        "$settings/AccentEditor.qml" "$settings/AccentPicker.qml" "$settings/ThemeProfilePicker.qml"; then
    fail 'theme controls introduce continuously repainting or decorative animation'
fi

state_home="$(mktemp -d /tmp/panama-accent-controls.XXXXXX)"
harness="$repo_dir/config/dot/quickshell/accent-controls-harness.qml"

qs_for_test() {
    XDG_CONFIG_HOME="$state_home/config" XDG_STATE_HOME="$state_home/state" \
        QS_DISABLE_CRASH_HANDLER=1 qs -p "$harness" "$@"
}

cleanup() {
    qs_for_test kill >/dev/null 2>&1 || true
    rm -rf "$state_home"
}
trap cleanup EXIT

qs_for_test --daemonize >/dev/null
for _ in $(seq 1 40); do
    qs_for_test ipc show 2>/dev/null | rg -q '^target accent-controls-test$' && break
    sleep 0.1
done
qs_for_test ipc show 2>/dev/null | rg -q '^target accent-controls-test$' \
    || fail 'headless AccentEditor harness did not start'

before="$(qs_for_test ipc call accent-controls-test status)"
jq -e '.id == "moon" and .shipped == true' <<<"$before" >/dev/null \
    || fail 'headless editor did not begin on Moon'
after="$(qs_for_test ipc call accent-controls-test adjust primary h 0)"
jq -e '.shipped == false and .accent != "#82aaff" and .secondary == "#b172b0"' \
    <<<"$after" >/dev/null \
    || fail 'an HSV adjustment did not create a custom profile with the unchanged secondary colour'

trap - EXIT
cleanup
printf 'accent controls contract: PASS\n'
