// SPDX-FileCopyrightText: 2026 Marco Allegretti
// SPDX-License-Identifier: EUPL-1.2

#include "setupstate.h"
#include "devicecontext.h"

#include <KConfigGroup>
#include <KSharedConfig>

#include <QCoreApplication>
#include <QJSEngine>
#include <QProcess>
#include <QQmlEngine>

const QString CONFIG_FILE = QStringLiteral("plasmamobilerc");
const QString GENERAL_CONFIG_GROUP = QStringLiteral("General");
const QString INITIAL_START_CONFIG_GROUP = QStringLiteral("InitialStart");

SetupState::SetupState(QObject *parent)
    : QObject(parent)
{
    useRecommendedSettings();
}

SetupState *SetupState::self()
{
    static auto *instance = new SetupState(qApp);
    return instance;
}

SetupState *SetupState::create(QQmlEngine *qmlEngine, QJSEngine *jsEngine)
{
    Q_UNUSED(qmlEngine)
    Q_UNUSED(jsEngine)
    return self();
}

QString SetupState::deviceClass() const
{
    return m_deviceClass;
}

void SetupState::setDeviceClass(const QString &deviceClass)
{
    if (m_deviceClass == deviceClass) {
        return;
    }
    m_deviceClass = deviceClass;
    Q_EMIT deviceClassChanged();
}

QString SetupState::experienceProfile() const
{
    return m_experienceProfile;
}

void SetupState::setExperienceProfile(const QString &experienceProfile)
{
    if (m_experienceProfile == experienceProfile) {
        return;
    }
    m_experienceProfile = experienceProfile;
    Q_EMIT experienceProfileChanged();
}

QString SetupState::primaryInput() const
{
    return m_primaryInput;
}

void SetupState::setPrimaryInput(const QString &primaryInput)
{
    if (m_primaryInput == primaryInput) {
        return;
    }
    m_primaryInput = primaryInput;
    Q_EMIT primaryInputChanged();
}

bool SetupState::convergenceModeEnabled() const
{
    return m_convergenceModeEnabled;
}

void SetupState::setConvergenceModeEnabled(bool enabled)
{
    if (m_convergenceModeEnabled == enabled) {
        return;
    }
    m_convergenceModeEnabled = enabled;
    emitShellSettingsChanged();
}

bool SetupState::gamingModeEnabled() const
{
    return m_gamingModeEnabled;
}

void SetupState::setGamingModeEnabled(bool enabled)
{
    if (m_gamingModeEnabled == enabled) {
        return;
    }
    m_gamingModeEnabled = enabled;
    emitShellSettingsChanged();
}

bool SetupState::navigationPanelEnabled() const
{
    return m_navigationPanelEnabled;
}

void SetupState::setNavigationPanelEnabled(bool enabled)
{
    if (m_navigationPanelEnabled == enabled) {
        return;
    }
    m_navigationPanelEnabled = enabled;
    emitShellSettingsChanged();
}

bool SetupState::dynamicTilingEnabled() const
{
    return m_dynamicTilingEnabled;
}

void SetupState::setDynamicTilingEnabled(bool enabled)
{
    if (m_dynamicTilingEnabled == enabled) {
        return;
    }
    m_dynamicTilingEnabled = enabled;
    emitShellSettingsChanged();
}

bool SetupState::snapLayoutsEnabled() const
{
    return m_snapLayoutsEnabled;
}

void SetupState::setSnapLayoutsEnabled(bool enabled)
{
    if (m_snapLayoutsEnabled == enabled) {
        return;
    }
    m_snapLayoutsEnabled = enabled;
    emitShellSettingsChanged();
}

bool SetupState::autoHidePanelsEnabled() const
{
    return m_autoHidePanelsEnabled;
}

void SetupState::setAutoHidePanelsEnabled(bool enabled)
{
    if (m_autoHidePanelsEnabled == enabled) {
        return;
    }
    m_autoHidePanelsEnabled = enabled;
    emitShellSettingsChanged();
}

void SetupState::useRecommendedSettings()
{
    auto *context = DeviceContext::self();
    setDeviceClass(context->recommendedDeviceClass());

    if (context->recommendedExperienceProfile() == QLatin1String("gaming")) {
        setPrimaryInput(QStringLiteral("gamepad"));
    } else if (context->hasTouch() && !context->hasKeyboard() && !context->hasMouse()) {
        setPrimaryInput(QStringLiteral("touch"));
    } else {
        setPrimaryInput(QStringLiteral("keyboardMouse"));
    }

    applyExperienceDefaults(context->recommendedExperienceProfile());
}

void SetupState::applyDeviceDefaults(const QString &deviceClass, const QString &primaryInput)
{
    setDeviceClass(deviceClass);
    setPrimaryInput(primaryInput);

    if (deviceClass == QLatin1String("handheld") || deviceClass == QLatin1String("mini-pc")) {
        applyExperienceDefaults(QStringLiteral("gaming"));
    } else if (deviceClass == QLatin1String("laptop") || deviceClass == QLatin1String("desktop")) {
        applyExperienceDefaults(QStringLiteral("desktop"));
    } else if (deviceClass == QLatin1String("dual-screen") || deviceClass == QLatin1String("foldable")) {
        applyExperienceDefaults(QStringLiteral("hybrid"));
    } else {
        applyExperienceDefaults(QStringLiteral("mobile"));
    }
}

void SetupState::applyExperienceDefaults(const QString &experienceProfile)
{
    setExperienceProfile(experienceProfile);

    if (experienceProfile == QLatin1String("gaming")) {
        setConvergenceModeEnabled(false);
        setGamingModeEnabled(true);
        setNavigationPanelEnabled(false);
        setDynamicTilingEnabled(false);
        setSnapLayoutsEnabled(false);
        setAutoHidePanelsEnabled(true);
    } else if (experienceProfile == QLatin1String("desktop")) {
        setConvergenceModeEnabled(true);
        setGamingModeEnabled(false);
        setNavigationPanelEnabled(false);
        setDynamicTilingEnabled(true);
        setSnapLayoutsEnabled(true);
        setAutoHidePanelsEnabled(false);
    } else if (experienceProfile == QLatin1String("hybrid")) {
        setConvergenceModeEnabled(true);
        setGamingModeEnabled(false);
        setNavigationPanelEnabled(false);
        setDynamicTilingEnabled(true);
        setSnapLayoutsEnabled(true);
        setAutoHidePanelsEnabled(true);
    } else {
        setConvergenceModeEnabled(false);
        setGamingModeEnabled(false);
        setNavigationPanelEnabled(false);
        setDynamicTilingEnabled(false);
        setSnapLayoutsEnabled(false);
        setAutoHidePanelsEnabled(false);
    }
}

void SetupState::apply(bool applyToRunningSession)
{
    auto config = KSharedConfig::openConfig(CONFIG_FILE);
    KConfigGroup general(config, GENERAL_CONFIG_GROUP);
    general.writeEntry("setupDeviceClass", m_deviceClass, KConfigGroup::Notify);
    general.writeEntry("setupExperienceProfile", m_experienceProfile, KConfigGroup::Notify);
    general.writeEntry("setupPrimaryInput", m_primaryInput, KConfigGroup::Notify);
    general.writeEntry("convergenceModeEnabled", m_convergenceModeEnabled, KConfigGroup::Notify);
    general.writeEntry("gamingModeEnabled", m_gamingModeEnabled, KConfigGroup::Notify);
    general.writeEntry("navigationPanelEnabled", m_navigationPanelEnabled, KConfigGroup::Notify);
    general.writeEntry("dynamicTilingEnabled", m_dynamicTilingEnabled, KConfigGroup::Notify);
    general.writeEntry("snapLayoutsEnabled", m_snapLayoutsEnabled, KConfigGroup::Notify);
    general.writeEntry("autoHidePanelsEnabled", m_autoHidePanelsEnabled, KConfigGroup::Notify);

    KConfigGroup initialStart(config, INITIAL_START_CONFIG_GROUP);
    initialStart.writeEntry("wizardRun", true, KConfigGroup::Notify);
    config->sync();

    if (applyToRunningSession) {
        QProcess::startDetached(QStringLiteral("plasma-mobile-envmanager"), {QStringLiteral("--apply-settings")});
    }
}

void SetupState::emitShellSettingsChanged()
{
    Q_EMIT shellSettingsChanged();
}
