#pragma once

#include <QJsonObject>
#include <QPoint>
#include <QRect>
#include <QSize>
#include <QString>
#include <optional>

enum class SidePopupEdge {
    Right,
    Left,
};

struct SidePopupPlacement {
    QPoint position;
    SidePopupEdge edge = SidePopupEdge::Right;
};

QString normalizedControllerForCompare(const QString &input, const QString &defaultControlInput);
bool backendStateRequiresReloginPrompt(const QString &backendState);
bool controllerInputChanged(const QString &currentInput,
                            const QString &newInput,
                            const QString &defaultControlInput);
bool controllerSwitchNeedsLogoutPrompt(const QString &currentInput,
                                       const QString &newInput,
                                       const QString &defaultControlInput,
                                       const QString &backendState);
bool advertiseExitEnableNeedsConfirmation(bool enabled);
bool shouldShowAuthenticatedMenus(const QString &backendState);
bool shouldShowLoginAction(const QString &backendState);
bool shouldShowReauthAction(const QString &backendState);
bool shouldShowConnectAction(const QString &backendState);
bool shouldShowDisconnectAction(const QString &backendState);
bool shouldEnableRunningOnlyLauncher(const QString &backendState);
bool shouldShowPeersLauncher(bool showAuthenticatedMenus, bool hasPeerSections);
bool errorSuggestsOperatorGrant(const QString &error);
QString loginAuthURLFromSnapshot(const QJsonObject &snapshot);
QString advertiseExitActionText(bool advertisesExitNode);
QString exitMenuTitleText(const QString &currentExitLabel);
QString exitListTitleText(bool hasExitNodeChoices);
bool isSyntheticNoExitNodeChoice(const QString &stableID, const QString &name);
QString submenuLauncherText(const QString &title);
QString peersLauncherText();
QString accountLauncherText(const QString &accountLabel);
QString selfRootActionText(const QString &selfName, const QString &primaryIP);
bool shouldDeferTrayMenuRefresh(bool rootMenuVisible, bool submenuVisible);
bool shouldCloseSidePopupAfterRootHide(bool rootMenuVisible,
                                       bool sidePopupVisible,
                                       bool suppressRootHideClose);
QPoint rootPopupPosition(const QPoint &anchorGlobalPoint,
                         const QSize &popupSize,
                         const QRect &availableScreenRect);
SidePopupPlacement sidePopupPlacement(const QRect &anchorGlobalRect,
                                      const QSize &popupSize,
                                      const QRect &availableScreenRect,
                                      std::optional<SidePopupEdge> lockedEdge = std::nullopt);
QPoint sidePopupPosition(const QRect &anchorGlobalRect,
                         const QSize &popupSize,
                         const QRect &availableScreenRect);
