#include <iostream>
#include <cstring>
#include <string>
#include "engine.hpp"
#include "defines.hpp"
#include "resource_manager.hpp"

// getExecutableDirectory() ya está definido en defines.h como inline

void printHelp() {
    std::cout << "ViBe3 Physics - Simulador de físicas avanzadas\n";
    std::cout << "\nUso: vibe3_physics [opciones]\n\n";
    std::cout << "Opciones:\n";
    std::cout << "  -w, --width <px>     Ancho de resolución (default: 320)\n";
    std::cout << "  -h, --height <px>    Alto de resolución (default: 240)\n";
    std::cout << "  -z, --zoom <n>       Zoom de ventana (default: 3)\n";
    std::cout << "  -f, --fullscreen     Modo pantalla completa (F3 - letterbox)\n";
    std::cout << "  -F, --real-fullscreen Modo pantalla completa real (F4 - nativo)\n";
    std::cout << "  -k, --kiosk          Modo kiosko (F4 fijo, sin ESC, sin zoom)\n";
    std::cout << "  -m, --mode <mode>    Modo inicial: sandbox, demo, demo-lite, logo (default: sandbox)\n";
    std::cout << "  --custom-balls <n>   Activa escenario custom (tecla 9) con N pelotas\n";
    std::cout << "  --skip-benchmark     Salta el benchmark y usa el máximo de bolas (50000)\n";
    std::cout << "  --max-balls <n>      Limita el máximo de bolas en modos DEMO/DEMO_LITE\n";
    std::cout << "  --postfx [efecto]    Arrancar con PostFX activo (default: complet): vinyeta, scanlines, cromatica, complet\n";
    std::cout << "  --vignette <float>   Sobreescribir vignette_strength (activa PostFX si no hay --postfx)\n";
    std::cout << "  --chroma <float>     Sobreescribir chroma_strength   (activa PostFX si no hay --postfx)\n";
    std::cout << "  --help               Mostrar esta ayuda\n\n";
    std::cout << "Ejemplos:\n";
    std::cout << "  vibe3_physics                    # 320x240 zoom 3 (ventana 960x720)\n";
    std::cout << "  vibe3_physics -w 1920 -h 1080    # 1920x1080 zoom 1 (auto)\n";
    std::cout << "  vibe3_physics -w 640 -h 480 -z 2 # 640x480 zoom 2 (ventana 1280x960)\n";
    std::cout << "  vibe3_physics -f                 # Fullscreen letterbox (F3)\n";
    std::cout << "  vibe3_physics -F                 # Fullscreen real (F4 - resolución nativa)\n";
    std::cout << "  vibe3_physics -k                 # Modo kiosko (pantalla completa real, bloqueado)\n";
    std::cout << "  vibe3_physics --mode demo        # Arrancar en modo DEMO (auto-play)\n";
    std::cout << "  vibe3_physics -m demo-lite       # Arrancar en modo DEMO_LITE (solo física)\n";
    std::cout << "  vibe3_physics -F --mode logo     # Fullscreen + modo LOGO (easter egg)\n\n";
    std::cout << "Nota: Si resolución > pantalla, se usa default. Zoom se ajusta automáticamente.\n";
}

int main(int argc, char* argv[]) {
    int width = 0;
    int height = 0;
    int zoom = 0;
    int custom_balls = 0;
    bool fullscreen = false;
    bool real_fullscreen = false;
    bool kiosk_mode = false;
    bool skip_benchmark = false;
    int max_balls_override = 0;
    int initial_postfx = -1;
    float override_vignette = -1.f;
    float override_chroma = -1.f;
    AppMode initial_mode = AppMode::SANDBOX;  // Modo inicial (default: SANDBOX)

    // Parsear argumentos
    for (int i = 1; i < argc; i++) {
        if (strcmp(argv[i], "--help") == 0) {
            printHelp();
            return 0;
        } else if (strcmp(argv[i], "-w") == 0 || strcmp(argv[i], "--width") == 0) {
            if (i + 1 < argc) {
                width = atoi(argv[++i]);
                if (width < 320) {
                    std::cerr << "Error: Ancho mínimo es 320\n";
                    return -1;
                }
            } else {
                std::cerr << "Error: -w/--width requiere un valor\n";
                return -1;
            }
        } else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--height") == 0) {
            if (i + 1 < argc) {
                height = atoi(argv[++i]);
                if (height < 240) {
                    std::cerr << "Error: Alto mínimo es 240\n";
                    return -1;
                }
            } else {
                std::cerr << "Error: -h/--height requiere un valor\n";
                return -1;
            }
        } else if (strcmp(argv[i], "-z") == 0 || strcmp(argv[i], "--zoom") == 0) {
            if (i + 1 < argc) {
                zoom = atoi(argv[++i]);
                if (zoom < 1) {
                    std::cerr << "Error: Zoom mínimo es 1\n";
                    return -1;
                }
            } else {
                std::cerr << "Error: -z/--zoom requiere un valor\n";
                return -1;
            }
        } else if (strcmp(argv[i], "-f") == 0 || strcmp(argv[i], "--fullscreen") == 0) {
            fullscreen = true;
        } else if (strcmp(argv[i], "-F") == 0 || strcmp(argv[i], "--real-fullscreen") == 0) {
            real_fullscreen = true;
        } else if (strcmp(argv[i], "-k") == 0 || strcmp(argv[i], "--kiosk") == 0) {
            kiosk_mode = true;
        } else if (strcmp(argv[i], "-m") == 0 || strcmp(argv[i], "--mode") == 0) {
            if (i + 1 < argc) {
                std::string mode_str = argv[++i];
                if (mode_str == "sandbox") {
                    initial_mode = AppMode::SANDBOX;
                } else if (mode_str == "demo") {
                    initial_mode = AppMode::DEMO;
                } else if (mode_str == "demo-lite") {
                    initial_mode = AppMode::DEMO_LITE;
                } else if (mode_str == "logo") {
                    initial_mode = AppMode::LOGO;
                } else {
                    std::cerr << "Error: Modo '" << mode_str << "' no válido. Usa: sandbox, demo, demo-lite, logo\n";
                    return -1;
                }
            } else {
                std::cerr << "Error: -m/--mode requiere un valor\n";
                return -1;
            }
        } else if (strcmp(argv[i], "--custom-balls") == 0) {
            if (i + 1 < argc) {
                int n = atoi(argv[++i]);
                if (n < 1) {
                    std::cerr << "Error: --custom-balls requiere un valor >= 1\n";
                    return -1;
                }
                custom_balls = n;
            } else {
                std::cerr << "Error: --custom-balls requiere un valor\n";
                return -1;
            }
        } else if (strcmp(argv[i], "--skip-benchmark") == 0) {
            skip_benchmark = true;
        } else if (strcmp(argv[i], "--postfx") == 0) {
            // Si no hay valor o el siguiente arg es otra opción, defaultear a complet
            if (i + 1 < argc && argv[i + 1][0] != '-') {
                std::string fx = argv[++i];
                if (fx == "vinyeta") {
                    initial_postfx = 0;
                } else if (fx == "scanlines") {
                    initial_postfx = 1;
                } else if (fx == "cromatica") {
                    initial_postfx = 2;
                } else if (fx == "complet") {
                    initial_postfx = 3;
                } else {
                    std::cerr << "Error: --postfx '" << fx << "' no válido. Usa: vinyeta, scanlines, cromatica, complet\n";
                    return -1;
                }
            } else {
                initial_postfx = 3;  // default: complet
            }
        } else if (strcmp(argv[i], "--vignette") == 0) {
            if (i + 1 < argc) {
                override_vignette = (float)atof(argv[++i]);
            } else {
                std::cerr << "Error: --vignette requiere un valor\n";
                return -1;
            }
        } else if (strcmp(argv[i], "--chroma") == 0) {
            if (i + 1 < argc) {
                override_chroma = (float)atof(argv[++i]);
            } else {
                std::cerr << "Error: --chroma requiere un valor\n";
                return -1;
            }
        } else if (strcmp(argv[i], "--max-balls") == 0) {
            if (i + 1 < argc) {
                int n = atoi(argv[++i]);
                if (n < 1) {
                    std::cerr << "Error: --max-balls requiere un valor >= 1\n";
                    return -1;
                }
                max_balls_override = n;
            } else {
                std::cerr << "Error: --max-balls requiere un valor\n";
                return -1;
            }
        } else {
            std::cerr << "Error: Opción desconocida '" << argv[i] << "'\n";
            printHelp();
            return -1;
        }
    }

    // Inicializar sistema de recursos empaquetados (intentar cargar resources.pack)
    std::string resources_dir = getResourcesDirectory();
    std::string pack_path = resources_dir + "/resources.pack";
    ResourceManager::init(pack_path);

    Engine engine;

    if (custom_balls > 0)
        engine.setCustomScenario(custom_balls);  // pre-init: asigna campos antes del benchmark

    if (max_balls_override > 0)
        engine.setMaxBallsOverride(max_balls_override);
    else if (skip_benchmark)
        engine.setSkipBenchmark();

    if (initial_postfx >= 0)
        engine.setInitialPostFX(initial_postfx);

    if (override_vignette >= 0.f || override_chroma >= 0.f) {
        if (initial_postfx < 0)
            engine.setInitialPostFX(0);
        engine.setPostFXParamOverrides(override_vignette, override_chroma);
    }

    if (!engine.initialize(width, height, zoom, fullscreen, initial_mode)) {
        std::cout << "¡Error al inicializar el engine!" << std::endl;
        return -1;
    }

    // Si se especificó real fullscreen (F4) o modo kiosko, activar después de inicializar
    if (real_fullscreen || kiosk_mode) {
        engine.toggleRealFullscreen();
    }
    if (kiosk_mode) {
        engine.setKioskMode(true);
    }

    engine.run();
    engine.shutdown();

    return 0;
}