#pragma once

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

// ==========================================================
// TownQuestEngine - Máy Trạng Thái Tự Động Mở World Map (Phím U)
// & Điều Hướng Làm Quest Chiến Dịch POE2
// ==========================================================

enum class TownQuestState : uint32_t {
    IDLE = 0,
    PRESS_U,            // Gửi phím 'U' (VK_U = 0x55) mở World Map từ Làng
    WAIT_MAP_OPEN,      // Chờ 350ms để giao diện World Map hiển thị
    CLICK_ACT_TAB,      // Click chọn Tab Act (Act 1, 2, 3)
    CLICK_ZONE_NODE,    // Click chọn Node bản đồ phụ bản nhiệm vụ
    CONFIRM_TRAVEL,     // Bấm Enter / nút xác nhận dịch chuyển vào map
    WAIT_ZONE_LOAD      // Chờ sự kiện LoadingFinished hoàn tất
};

struct TownQuestConfig {
    bool enabled = true;
    uint32_t mapOpenDelayMs = 400;      // Thời gian chờ mở UI World Map
    uint32_t tabSwitchDelayMs = 250;    // Thời gian chờ chuyển Tab Act
    uint32_t zoneClickDelayMs = 250;    // Thời gian chờ chọn Zone Node
    uint32_t maxLoadWaitMs = 30000;     // Hết thời gian chờ load map (30s)
};

class TownQuestEngine {
public:
    explicit TownQuestEngine(TownQuestConfig config = {});

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

    TownQuestState GetState() const { return m_state; }
    bool IsActive() const { return m_state != TownQuestState::IDLE; }
    uint32_t GetTargetAct() const { return m_targetAct; }
    uint32_t GetTargetZoneIndex() const { return m_targetZoneIndex; }

    // Kích hoạt dịch chuyển bản đồ (từ IPC lệnh 96 hoặc tự động)
    void StartTravel(uint32_t act, uint32_t zoneIndex, uint64_t nowMs);

    // Sự kiện khi tải map mới thành công
    void OnLoadingFinished(const std::string& areaName, uint64_t nowMs);

    // Cập nhật State Machine trong chu kỳ chính của Core
    // Cập nhật State Machine trong chu kỳ chính của Core
    bool Tick(KMBoxNet& kmbox, uint64_t nowMs);

    // Đóng giao diện World Map nếu đang mở (gửi phím ESC hoặc U)
    void CloseMapIfOpen(KMBoxNet* kmbox = nullptr);
    void CloseMapIfOpen(KMBoxNet& kmbox) { CloseMapIfOpen(&kmbox); }
    bool IsMapOpen() const { return m_mapOpen || (m_state >= TownQuestState::WAIT_MAP_OPEN && m_state <= TownQuestState::WAIT_ZONE_LOAD); }

    // Đưa về trạng thái IDLE (đóng World Map nếu đang mở)
    void Reset(KMBoxNet* kmbox = nullptr);
    void Reset(KMBoxNet& kmbox) { Reset(&kmbox); }

    // Lấy tên map từ Act và Zone Index
    std::string GetZoneName(uint32_t act, uint32_t zoneIndex) const;
    void SetCurrentAreaName(const std::string& areaName) { m_currentAreaName = areaName; }
    const std::string& GetCurrentAreaName() const { return m_currentAreaName; }

    // Hỗ trợ kiểm thử logic
    void SetStateForTest(TownQuestState state, uint64_t nowMs) {
        m_state = state;
        m_stateStartMs = nowMs;
    }

private:
    bool FocusGameWindow();
    bool GetGameWindowRect(int& outLeft, int& outTop, int& outWidth, int& outHeight);
    void SendClick(int x, int y, KMBoxNet& kmbox);
    void SendDoubleClick(int x, int y, KMBoxNet& kmbox);
    void SendKey(uint8_t vk, KMBoxNet& kmbox, uint32_t holdMs = 40);

    TownQuestConfig m_config;
    TownQuestState m_state = TownQuestState::IDLE;

    uint32_t m_targetAct = 2;
    uint32_t m_targetZoneIndex = 0;
    uint64_t m_stateStartMs = 0;
    uint64_t m_lastActionMs = 0;
    uint32_t m_retryCount = 0;
    std::string m_currentAreaName;
    uint64_t m_lastUKeyMs = 0;
    HumanCurveGenerator m_curveGen;
    bool m_mapOpen = false;
    KMBoxNet* m_kmbox = nullptr;
};
