#pragma once

#include <string>
#include <functional>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <chrono>
#include <mutex>
#include <cstdint>

struct lua_State;

namespace mosis {

using TimerId = uint64_t;
using TimePoint = std::chrono::steady_clock::time_point;
using Duration = std::chrono::milliseconds;

struct Timer {
    TimerId id;
    std::string app_id;
    TimePoint fire_time;
    Duration interval;      // 0 for setTimeout, >0 for setInterval
    int callback_ref;       // Lua registry reference
    lua_State* L;           // Lua state that owns the callback
    bool cancelled = false;
    bool is_interval = false;
};

class TimerManager {
public:
    TimerManager();
    ~TimerManager();

    // Non-copyable
    TimerManager(const TimerManager&) = delete;
    TimerManager& operator=(const TimerManager&) = delete;

    // Create timers (returns timer ID, 0 on failure)
    TimerId SetTimeout(lua_State* L, const std::string& app_id,
                       int callback_ref, int delay_ms);
    TimerId SetInterval(lua_State* L, const std::string& app_id,
                        int callback_ref, int interval_ms);

    // Cancel timers
    bool ClearTimer(const std::string& app_id, TimerId id);

    // Cancel all timers for an app (call on app stop)
    void ClearAppTimers(const std::string& app_id);

    // Process timers (call from main loop)
    // Returns number of timers fired
    int ProcessTimers();

    // Get timer count for an app
    size_t GetTimerCount(const std::string& app_id) const;

    // Configuration
    static constexpr size_t MAX_TIMERS_PER_APP = 100;
    static constexpr int MIN_INTERVAL_MS = 10;
    static constexpr int MIN_TIMEOUT_MS = 0;

private:
    TimerId m_next_id = 1;

    // All timers (we use a vector and sort/search as needed)
    std::vector<Timer> m_timers;

    // Track timer count per app
    std::unordered_map<std::string, size_t> m_app_timer_counts;

    // Track which timer IDs belong to which app (for fast cancellation)
    std::unordered_map<std::string, std::unordered_set<TimerId>> m_app_timer_ids;

    mutable std::mutex m_mutex;

    void FireTimer(Timer& timer);
    void RemoveTimer(TimerId id);
    void RescheduleInterval(Timer& timer);
};

// Lua API registration
// Registers: setTimeout, clearTimeout, setInterval, clearInterval
void RegisterTimerAPI(lua_State* L, TimerManager* manager, const std::string& app_id);

} // namespace mosis
