#pragma once

#include <memory>
#include <string>
#include <optional>

#include "RecentServers.hpp"
#include "FavouriteServers.hpp"
#include "ServerAddressProvider.hpp"
#include "network/ServerConnection.hpp"

struct ImVec4;

namespace tw::app {

/**
 * The edge out of the lobby: a connection that finished its handshake.
 */
struct LobbyResult {
    std::unique_ptr<tw::net::ServerConnection> connection;
};

/**
 * The lobby screen state. Renders an address input field, recent server list,
 * and manages a connection attempt in flight.
 */
class LobbyState {
    static constexpr size_t ADDRESS_INPUT_SIZE = 64;

    tw::app::RecentServers m_recent;
    tw::app::FavouriteServers m_favourites;

    /**
     * Edited in place by the input field, so it has to outlive the frame that
     * draws it rather than being rebuilt from a string every time.
     */
    char m_address_input[ADDRESS_INPUT_SIZE];

    std::string m_error;
    std::unique_ptr<tw::net::ServerConnection> m_connection;
    std::optional<LobbyResult> m_result;

    void begin_connect(tw::net::Address address);
    void set_address_input(const std::string& address);

    void draw_form();

    /**
     * Renders one address list. The colour is what tells the lists apart on
     * screen, so it belongs to the lobby rather than to the list itself.
     */
    void draw_provider(ServerAddressProvider& provider, const ImVec4& header_colour);

    void draw_favourite_toggle(const std::string& entry);
    void toggle_favourite(const std::string& entry);
    void draw_status();

public:
    /**
     * Constructs the lobby state, optionally starting an auto-connect if a
     * server address is provided.
     */
    explicit LobbyState(std::optional<tw::net::Address> auto_connect);

    /**
     * Updates the lobby: draws the UI, pumps the connection attempt if one
     * is in flight.
     */
    void update(double delta_time);

    /**
     * Returns the transition result if the lobby is done. Moves the result
     * out, leaving none behind.
     */
    std::optional<LobbyResult> take_result();
};

} // namespace tw::app
