#pragma once
#include "Json.h"
#include <fstream>
#include <sstream>
#include <iostream>

// Persistent engine settings saved to JSON.
// Automatically loads on construction and saves on demand.
//
// Settings file (default: ~/.zoomengine/settings.json):
// {
//   "window": { "width": 1920, "height": 1080, "fullscreen": false, "vsync": true },
//   "audio":  { "master_volume": 0.8, "sfx_volume": 1.0, "music_volume": 0.7 },
//   "graphics": { "show_fps": true, "fov": 60.0, "draw_distance": 1000.0 },
//   "font":   { "spacing": 0.75, "weight": 2.0 },
//   "input":  { "mouse_sensitivity": 80.0, "gamepad_deadzone": 0.15 }
// }

struct Settings {
    // Window
    int windowWidth     = 1920;
    int windowHeight    = 1080;
    bool fullscreen     = false;
    bool vsync          = true;

    // Audio
    float masterVolume  = 0.8f;
    float sfxVolume     = 1.0f;
    float musicVolume   = 0.7f;

    // Graphics
    bool showFps        = true;
    float fov           = 60.0f;
    float drawDistance   = 1000.0f;

    // Font
    float fontSpacing   = 0.75f;
    float fontWeight    = 2.0f;

    // Input
    float mouseSensitivity  = 80.0f;
    float gamepadDeadzone   = 0.15f;

    std::string filePath;

    Settings() = default;

    // Load from file. Returns true if file existed.
    bool load(const std::string& path = "") {
        filePath = path.empty() ? defaultPath() : path;
        try {
            json::Value root = json::parseFile(filePath);
            if (root.has("window")) {
                auto& w = root["window"];
                windowWidth  = w.get_int("width", windowWidth);
                windowHeight = w.get_int("height", windowHeight);
                fullscreen   = w.get_bool("fullscreen", fullscreen);
                vsync        = w.get_bool("vsync", vsync);
            }
            if (root.has("audio")) {
                auto& a = root["audio"];
                masterVolume = a.get_float("master_volume", masterVolume);
                sfxVolume    = a.get_float("sfx_volume", sfxVolume);
                musicVolume  = a.get_float("music_volume", musicVolume);
            }
            if (root.has("graphics")) {
                auto& g = root["graphics"];
                showFps      = g.get_bool("show_fps", showFps);
                fov          = g.get_float("fov", fov);
                drawDistance  = g.get_float("draw_distance", drawDistance);
            }
            if (root.has("font")) {
                auto& f = root["font"];
                fontSpacing = f.get_float("spacing", fontSpacing);
                fontWeight  = f.get_float("weight", fontWeight);
            }
            if (root.has("input")) {
                auto& i = root["input"];
                mouseSensitivity = i.get_float("mouse_sensitivity", mouseSensitivity);
                gamepadDeadzone  = i.get_float("gamepad_deadzone", gamepadDeadzone);
            }
            std::cout << "Settings loaded from " << filePath << std::endl;
            return true;
        } catch (...) {
            return false;
        }
    }

    // Save current settings to file
    bool save() const {
        if (filePath.empty()) return false;

        // Ensure directory exists
        std::string dir = filePath.substr(0, filePath.find_last_of('/'));
        if (!dir.empty()) {
            std::string cmd = "mkdir -p \"" + dir + "\"";
            system(cmd.c_str());
        }

        std::ofstream f(filePath);
        if (!f.is_open()) {
            std::cerr << "Settings: cannot write to " << filePath << std::endl;
            return false;
        }

        f << "{\n";
        f << "  \"window\": {\n";
        f << "    \"width\": " << windowWidth << ",\n";
        f << "    \"height\": " << windowHeight << ",\n";
        f << "    \"fullscreen\": " << (fullscreen ? "true" : "false") << ",\n";
        f << "    \"vsync\": " << (vsync ? "true" : "false") << "\n";
        f << "  },\n";
        f << "  \"audio\": {\n";
        f << "    \"master_volume\": " << masterVolume << ",\n";
        f << "    \"sfx_volume\": " << sfxVolume << ",\n";
        f << "    \"music_volume\": " << musicVolume << "\n";
        f << "  },\n";
        f << "  \"graphics\": {\n";
        f << "    \"show_fps\": " << (showFps ? "true" : "false") << ",\n";
        f << "    \"fov\": " << fov << ",\n";
        f << "    \"draw_distance\": " << drawDistance << "\n";
        f << "  },\n";
        f << "  \"font\": {\n";
        f << "    \"spacing\": " << fontSpacing << ",\n";
        f << "    \"weight\": " << fontWeight << "\n";
        f << "  },\n";
        f << "  \"input\": {\n";
        f << "    \"mouse_sensitivity\": " << mouseSensitivity << ",\n";
        f << "    \"gamepad_deadzone\": " << gamepadDeadzone << "\n";
        f << "  }\n";
        f << "}\n";

        std::cout << "Settings saved to " << filePath << std::endl;
        return true;
    }

    // Save window dimensions (call on resize)
    void updateWindowSize(int w, int h) {
        windowWidth = w;
        windowHeight = h;
    }

private:
    static std::string defaultPath() {
        const char* home = getenv("HOME");
        if (home) return std::string(home) + "/.zoomengine/settings.json";
        return "settings.json";
    }
};
