#pragma once
#include "../Framework/UIFramework.h"
#include <atomic>
#include <mutex>
#include <string>

class Menu {
public:
    static Menu* Get();

    void Render();
    void AddLog(const std::string& log) { Logs += log + "\n"; }
    void ClearLogs() { Logs.clear(); }
    const std::string& GetLogs() const { return Logs; }

    // Auto-login state (set by Menu.cpp startup check)
    void SetAutoLoginDone(bool success) { m_autoLoginSuccess = success; m_autoLoginChecked = true; }
    bool IsAutoLoginDone() const { return m_autoLoginChecked; }
    bool IsAutoLoginSuccess() const { return m_autoLoginSuccess; }

private:
    Menu() = default;
    ~Menu() = default;

    std::string Logs;
    std::atomic<bool> m_autoLoginChecked{false};
    std::atomic<bool> m_autoLoginSuccess{false};
};


namespace menu {
    class Connect
    {
    public:
        static Connect* Get();

        void DrawConnectMenu();
        bool IsConnected() const { return m_connected; }

        // Allow Login to reset connect state on logout
        void Reset() { m_connected = false; m_statusChecked = false; m_statusPending = false; }

    private:
        Connect() = default;
        ~Connect() = default;

        bool m_connected = false;
        double m_startTime = 0.0;
        bool m_connecting = false;

        // Network status check
        std::atomic<bool> m_statusPending{false};
        std::atomic<bool> m_statusChecked{false};
        std::string m_statusError;
        std::mutex m_mutex;
    };

    class Login
    {
    public:
        static Login* Get();

        void DrawLoginMenu();
        bool Get_loggedIn() const { return m_loggedIn; }
        std::string Get_UserName() const { return UserName.text; }

        // Allow Load/Logout to reset
        void Reset() { m_loggedIn = false; m_refreshToken.clear(); m_token.clear(); }
        std::string GetRefreshToken() const { return m_refreshToken; }

        // For auto-login: set login state without going through UI
        void SetAutoLoggedIn(const std::string& refreshToken, const std::string& accessToken, const std::string& username) {
            m_loggedIn = true;
            m_refreshToken = refreshToken;
            m_token = accessToken;
            m_displayName = username;
        }
        std::string GetDisplayName() const { return m_displayName.empty() ? UserName.text : m_displayName; }

    private:
        Login() { PassWord.password = true; };
        ~Login() = default;

        void TryLogin();
        void ResetLoginForm();

        TextboxState UserName = { "" };
        TextboxState PassWord = { "" };

        RLVector2 TextBox_UserName = { 180, 28 };
        RLVector2 TextBox_PassWord = { 180, 28 };
        bool m_loggedIn = false;
        std::string m_errorMessage;
        int m_loginAttempts = 0;
        double m_lastFailedTime = 0.0;
        bool m_blocked = false;

        std::string m_prevUserText;
        std::string m_prevPassText;
        double m_errorSetTime = 0.0;
        std::string m_prevErrorMessage;

        // Cloud login async state
        std::atomic<bool> m_loginPending{false};
        std::string m_serverError;
        std::string m_serverErrorCode;
        std::string m_token;          // JWT access token (memory only)
        std::string m_refreshToken;   // for DPAPI persistence
        std::string m_displayName;    // username for auto-login display
        std::mutex m_mutex;
        double m_loginStartTime = 0.0;
    };

    class Load
    {
    public:
        static Load* Get();

        void DrawLoadMenu();
        bool Get_injecting() const { return m_injecting; }

        // Reset on logout
        void Reset() { m_injecting = false; m_welcomeShown = false; }

    private:
        Load() = default;
        ~Load() = default;

        void bgDraw() const;
        bool Load_lock = false;
        bool is_cstoggle = true;
        bool m_welcomeShown = false;
        bool m_injecting = false;
        double m_startTime = 0.0;
        bool m_connecting = false;

        RLRectangle Rect = { 10, 17, 289, 133 };
    };

    class Injector
    {
    public:
        static Injector* Get();

        void DrawInjectorMenu();

        bool GetInjectionStatus() const { return m_injectionDone; }
    private:
        Injector() = default;
        ~Injector() = default;

        bool m_connected = false;
        int m_errorCode = 0;
        double m_startTime = 0.0;
        bool m_connecting = false;
        bool m_injectionDone = false;
    };
}
