#pragma once

#include <cstdint>
#include <string>
#include <vector>
#include "input/kmbox_net.hpp"
#include "input/human_curve.hpp"

// Các trạng thái của máy trạng thái Tự Động Đăng Nhập Lại
enum class AutoLoginState : uint32_t {
    IDLE = 0,               // Bình thường, bot đang chạy trong game
    DISCONNECTED_WAITING,   // Vừa rớt mạng, chờ một khoảng cooldown để client giải phóng socket
    DISMISS_DIALOG,         // Đóng hộp thoại lỗi "An unexpected disconnection occurred" (Click OK / Enter / Space)
    WAIT_LOGIN_SCREEN,      // Chờ màn hình đăng nhập (Login Screen) hiển thị
    SUBMIT_LOGIN,           // Nhập mật khẩu (nếu có) và nhấn "Log In" / Enter
    WAIT_CHAR_SELECT,       // Chờ tải danh sách nhân vật (Character Selection)
    SELECT_CHARACTER,       // Chọn slot nhân vật và nhấn "Play" / Enter
    WAIT_GAME_LOAD          // Chờ màn hình tải (Loading Screen) kết thúc để vào lại game
};

struct AutoLoginConfig {
    bool enabled = true;
    uint32_t reconnectDelayMs = 5000; // Cooldown sau khi đứt mạng (mặc định 5s)
    uint32_t charSlot = 1;            // Slot nhân vật (1: mặc định / nhân vật cấp cao nhất League hiện tại)
    std::string characterName = "";   // Tên nhân vật (tuỳ chọn CLI --character)
    std::string password = "";        // Mật khẩu cho bản Standalone (để trống nếu dùng Steam/Saved Password)
    std::string leagueName = "Forbidden Rites"; // League mới nhất (Non-Hardcore, Non-SSF)
    uint32_t maxRetries = 10;         // Số lần thử kết nối lại tối đa
};

class AutoLogin {
public:
    explicit AutoLogin(AutoLoginConfig config = {});

    void SetConfig(const AutoLoginConfig& config) { m_config = config; }
    const AutoLoginConfig& GetConfig() const { return m_config; }

    AutoLoginState GetState() const { return m_state; }
    bool IsActive() const { return m_state != AutoLoginState::IDLE; }
    uint32_t GetRetryCount() const { return m_retryCount; }
    const std::string& GetLastDisconnectReason() const { return m_lastDisconnectReason; }

    // Kích hoạt khi LogSensor hoặc Core phát hiện mất kết nối
    void OnDisconnect(const std::string& reason, uint64_t nowMs);

    // Kích hoạt thủ công (nút 'Thử đăng nhập' từ GUI qua IPC)
    void TriggerManualLogin(uint64_t nowMs);

    // Báo hiệu khi màn hình tải kết thúc / vào lại map thành công
    void OnLoadingFinished(const std::string& areaName, uint64_t nowMs);

    // Cập nhật State Machine trong vòng lặp chính của Core
    // Trả về true nếu vừa thực hiện một thao tác input
    bool Tick(KMBoxNet& kmbox, uint64_t nowMs);

    // Đưa về trạng thái IDLE
    void Reset();

    // Hỗ trợ kiểm thử logic chuyển đổi trạng thái
    void SetStateForTest(AutoLoginState state, uint64_t nowMs) {
        m_state = state;
        m_stateStartMs = nowMs;
        m_lastActionMs = nowMs;
    }

private:
    void FocusGameWindow();
    bool GetGameWindowRect(int& outLeft, int& outTop, int& outWidth, int& outHeight);

    void SendClick(int x, int y, KMBoxNet& kmbox);
    void SendKey(uint8_t vk, KMBoxNet& kmbox, uint32_t holdMs = 40);
    void SendText(const std::string& text, KMBoxNet& kmbox);

    AutoLoginConfig m_config;
    AutoLoginState m_state = AutoLoginState::IDLE;

    uint64_t m_stateStartMs = 0;
    uint64_t m_lastActionMs = 0;
    uint32_t m_retryCount = 0;
    std::string m_lastDisconnectReason;
    HumanCurveGenerator m_curveGen;
};
