// Entry point for the desktop emulator
#include "low_level_display_sfml.h"
#include "../display/low_level_render.h"
#include "../display/low_level_gui.h"
#include "game_launcher.h"
#include "../games/demo_game.h"
#include "../games/tic_tac_toe.h"
#include "../games/monopoly/monopoly_game.h"
#include "input_manager.h"
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <iostream>
#include <vector>
#include <cstring>

constexpr int WIDTH = 400;
constexpr int HEIGHT = 300;


int main() {
    // Allocate 1-bit framebuffer (rounded up)
    size_t buffer_size = (WIDTH * HEIGHT + 7) / 8;
    std::vector<uint8_t> framebuffer(buffer_size, 0);

    // Set up display, renderer, and GUI
    LowLevelDisplaySFML display(WIDTH, HEIGHT);
    if (!display.init()) {
        std::cerr << "Failed to initialize SFML display" << std::endl;
        return 1;
    }
    LowLevelRenderer renderer(framebuffer.data(), WIDTH, HEIGHT);
    LowLevelGUI gui(&renderer, font_5x5_obj);
    InputManager input_manager; // Emulator stub

    // Create GameLauncher
    GameLauncher launcher(WIDTH, HEIGHT, &renderer, &gui, &input_manager);
    launcher.register_game("Tic-Tac-Toe", "Classic 2-player game",
        [](uint16_t w, uint16_t h, LowLevelRenderer* r, LowLevelGUI* g, InputManager* im) -> Game* {
            return new TicTacToeGame(w, h, r, g, im);
        });
    launcher.register_game("Monopoly", "Classic property trading game",
        [](uint16_t w, uint16_t h, LowLevelRenderer* r, LowLevelGUI* g, InputManager* im) -> Game* {
            return new MonopolyGame(w, h, r, g, im);
        });
    launcher.register_game("Demo Game", "Simple test game",
        [](uint16_t w, uint16_t h, LowLevelRenderer* r, LowLevelGUI* g, InputManager* im) -> Game* {
            return new DemoGame(w, h, r, g, im);
        });

    Game* current_game = nullptr;
    bool running = true;
    bool needs_redraw = true;

    while (display.isOpen() && running) {
        // Handle SFML events and translate to InputEvent
        InputEvent event = {INPUT_NONE, 0, 0, 0, 0, 0, false};
        sf::Event sfEvent;
        while (display.pollEvent(sfEvent)) {
            if (sfEvent.type == sf::Event::Closed) {
                display.close();
                running = false;
            } else if (sfEvent.type == sf::Event::MouseButtonPressed) {
                event.type = INPUT_TOUCH_DOWN;
                event.x = sfEvent.mouseButton.x;
                event.y = sfEvent.mouseButton.y;
                event.valid = true;

                // Check for virtual buttons
                InputType virtual_type;
                if (input_manager.check_virtual_buttons(event.x, event.y, virtual_type)) {
                    event.type = virtual_type;
                }
            } else if (sfEvent.type == sf::Event::KeyPressed) {
                if (sfEvent.key.code == sf::Keyboard::Space) {
                    event.type = INPUT_BUTTON_0;
                    event.valid = true;
                } else if (sfEvent.key.code == sf::Keyboard::Enter) {
                    event.type = INPUT_BUTTON_1;
                    event.valid = true;
                } else if (sfEvent.key.code == sf::Keyboard::Escape) {
                    // Simulate long-press exit
                    if (launcher.is_game_selected()) {
                        launcher.reset();
                        needs_redraw = true;
                    }
                }
            }
        }

        if (event.valid) {
            if (launcher.is_game_selected()) {
                current_game = launcher.get_selected_game();
                needs_redraw = current_game->update(event) || needs_redraw;
                if (current_game->wants_to_exit()) {
                    launcher.reset();
                    needs_redraw = true;
                }
            } else {
                bool game_selected = launcher.update(event);
                if (game_selected) {
                    needs_redraw = true;
                }
            }
        }

        if (needs_redraw) {
            renderer.clear_buffer();
            if (launcher.is_game_selected()) {
                current_game = launcher.get_selected_game();
                current_game->draw();
            } else {
                launcher.draw();
            }
            display.draw_buffer(framebuffer.data());
            display.refresh();
            needs_redraw = false;
        }
    }
    return 0;
}
