pragma Singleton

import Quickshell
import QtQuick
import qs.config
import "ThemeProfileModel.js" as ThemeProfileModel

Singleton {
    id: root

    readonly property var customProfiles: ThemeProfileModel.validCustomProfiles(
        DesktopPreferences.get("themeProfiles"))
    readonly property var curatedAccents: ThemeProfileModel.curatedAccents()
    readonly property var profiles: ThemeProfileModel.profileCatalog(root.customProfiles)
    readonly property string activeId: DesktopPreferences.get("themeProfileId") || "moon"
    readonly property var activeProfile: ThemeProfileModel.findProfile(
        root.customProfiles, root.activeId) || ThemeProfileModel.shippedProfiles()[0]
    readonly property string activeAccentName: ThemeProfileModel.curatedNameForProfile(
        root.activeProfile)

    property bool reconciling: false

    function commitActive(profile: var): bool {
        if (!profile)
            return false;

        // Scheme first: if another control changed it, the reconciliation hook
        // may briefly select Day/Moon before this final stable profile id lands.
        const schemeAccepted = SystemSettings.commitPreference("colorScheme", profile.scheme);
        const profileAccepted = SystemSettings.commitPreference("themeProfileId", profile.id);
        return schemeAccepted && profileAccepted;
    }

    function selectProfile(id: string): bool {
        return root.commitActive(ThemeProfileModel.findProfile(root.customProfiles, id));
    }

    // Editing a shipped profile creates a saved custom copy. Editing a custom
    // profile updates only that record. ThemeProfileModel enforces both rules,
    // leaving this singleton responsible only for validated preference routing.
    function setAccentPair(accent: string, secondary: string): bool {
        const result = ThemeProfileModel.editProfile(root.customProfiles, root.activeProfile, {
            accent: accent,
            secondary: secondary
        });
        if (!result.profile)
            return false;
        if (!SystemSettings.commitPreference("themeProfiles", result.profiles))
            return false;
        return SystemSettings.commitPreference("themeProfileId", result.profile.id);
    }

    function saveProfile(name: string): bool {
        const result = ThemeProfileModel.createCustomProfile(root.customProfiles, {
            name: name,
            scheme: root.activeProfile.scheme,
            accent: root.activeProfile.accent,
            secondary: root.activeProfile.secondary
        });
        if (!result.profile)
            return false;
        if (!SystemSettings.commitPreference("themeProfiles", result.profiles))
            return false;
        return SystemSettings.commitPreference("themeProfileId", result.profile.id);
    }

    function deleteProfile(id: string): bool {
        const result = ThemeProfileModel.deleteProfile(root.customProfiles, id);
        if (!result.removed)
            return false;
        if (!SystemSettings.commitPreference("themeProfiles", result.profiles))
            return false;
        if (root.activeId === id)
            return root.selectProfile(DesktopPreferences.get("colorScheme") === "light" ? "day" : "moon");
        return true;
    }

    function useCuratedAccent(name: string): bool {
        const scheme = DesktopPreferences.get("colorScheme") === "light" ? "light" : "dark";
        const pair = ThemeProfileModel.curatedPair(name, scheme);
        const shipped = ThemeProfileModel.matchingShippedProfile(
            scheme, pair.accent, pair.secondary);
        const accepted = shipped
            ? root.commitActive(shipped)
            : root.setAccentPair(pair.accent, pair.secondary);
        if (accepted)
            SystemSettings.commitPreference("accentName", name);
        return accepted;
    }

    function reconcileScheme(): void {
        if (root.reconciling)
            return;
        const scheme = DesktopPreferences.get("colorScheme") === "light" ? "light" : "dark";
        if (root.activeProfile.scheme === scheme)
            return;
        root.reconciling = true;
        SystemSettings.commitPreference("themeProfileId", scheme === "light" ? "day" : "moon");
        root.reconciling = false;
    }

    Component.onCompleted: root.reconcileScheme()

    Connections {
        target: DesktopPreferences
        function onRevisionChanged(): void { root.reconcileScheme(); }
    }
}
