#pragma once

// This file requires native socket APIs (Windows or POSIX).
// On embedded platforms (STM32, AVR, etc.) this file compiles to nothing.
#ifdef FASTLED_HAS_NETWORKING

#include "fl/stl/asio/ip/tcp.h"
#include "fl/stl/asio/error_code.h"
#include "fl/stl/asio/http/connection.h"
#include "fl/stl/string.h"
#include "fl/stl/span.h"
#include "fl/stl/stdint.h"
#include "fl/stl/noexcept.h"

namespace fl {

// Native HTTP client using POSIX sockets
// Always non-blocking — blocking I/O is never appropriate on embedded
class NativeHttpClient {
public:
    // Constructor (Asio-compatible: accepts endpoint)
    NativeHttpClient(const asio::ip::tcp::endpoint& ep, const ConnectionConfig& config = ConnectionConfig());
    // Legacy constructor (backward compatible)
    NativeHttpClient(const string& host, u16 port, const ConnectionConfig& config = ConnectionConfig());
    ~NativeHttpClient() FL_NOEXCEPT;

    // Disable copy (socket ownership)
    NativeHttpClient(const NativeHttpClient&) FL_NOEXCEPT = delete;
    NativeHttpClient& operator=(const NativeHttpClient&) FL_NOEXCEPT = delete;

    // Connection management
    bool connect();           // Initiate connection
    void disconnect();        // Close connection
    void close();            // Permanent close (no reconnect)
    bool isConnected() const;
    ConnectionState getState() const;

    // Socket I/O
    int send(fl::span<const u8> data);
    int recv(fl::span<u8> buffer);

    // Update loop (handles reconnection, heartbeat)
    void update(u32 currentTimeMs);

    // Heartbeat
    bool shouldSendHeartbeat(u32 currentTimeMs) const;
    void onHeartbeatSent();
    void onHeartbeatReceived();

    // Reconnection state
    u32 getReconnectDelayMs() const;
    u32 getReconnectAttempts() const;

    // Access the endpoint
    const asio::ip::tcp::endpoint& endpoint() const { return mEndpoint; }

    // Access the underlying tcp::socket
    asio::ip::tcp::socket& socket() { return mSocket; }
    const asio::ip::tcp::socket& socket() const { return mSocket; }

private:
    asio::ip::tcp::endpoint mEndpoint;
    asio::ip::tcp::socket mSocket;
    HttpConnection mConnection;

    // Platform-specific connection
    bool platformConnect();
    void platformDisconnect();
    bool isSocketConnected() const;
};

} // namespace fl

#endif // FASTLED_HAS_NETWORKING
