#pragma once

#include <glm/glm.hpp>
#include <string>

struct LiveParams {
    float bpm = 92.0f;
    float timeScale = 1.0f;
    float narrativeDuration = 45.0f;
    float networkStart = 11.0f;
    float freedBounceDuration = 7.0f;
    float tunnelDuration = 13.0f;
    float launchDuration = 10.0f;
    float finaleWhiteDuration = 3.2f;

    glm::vec3 bgColor{0.14f, 0.08f, 0.06f};
    glm::vec3 colorFire{1.0f, 0.32f, 0.06f};
    glm::vec3 colorAmber{0.98f, 0.68f, 0.10f};
    glm::vec3 colorChrome{0.28f, 0.52f, 1.0f};
    glm::vec3 tunnelWarm{0.55f, 0.28f, 0.12f};
    glm::vec3 tunnelHot{0.95f, 0.55f, 0.18f};
    glm::vec3 tunnelCool{0.45f, 0.72f, 1.05f};
    glm::vec3 impactColor{1.05f, 0.72f, 0.38f};
    glm::vec3 linkWarm{1.0f, 0.72f, 0.38f};
    glm::vec3 starWarm{1.0f, 0.88f, 0.72f};

    float linkBrightness = 1.0f;
    float learnRate = 1.0f;
    float musicDriveGain = 1.0f;
    float beatSensitivity = 1.0f;
    float tunnelSpeedGain = 1.0f;
    float launchThrustGain = 1.0f;
    float starSwirlGain = 1.0f;
    float cameraFollowMin = 18.0f;
    float cameraFollowMax = 24.0f;
    float blobScale = 1.35f;
    float tunnelBehindMul = 1.0f;
    float tunnelAheadMul = 1.0f;
    float dendriteLineWidth = 1.0f;
    float fovTunnel = 52.0f;
    float fovLaunch = 62.0f;
    float cubeHalfExtent = 9.5f;

    bool resetDemo = false;
    float jumpPhase = -1.0f;

    static LiveParams defaults();
    void applyKeyValue(const std::string& key, float a, float b = 0.0f, float c = 0.0f, int components = 1);
    std::string serialize() const;
};

extern LiveParams gLive;

bool liveTuneStartServer(std::string& outSocketPath);
void liveTunePoll();
void liveTuneShutdown();
bool liveTuneSpawnPanel(const std::string& socketPath);
void liveTuneApplyBlobScale();
bool liveTuneLoadPresetFile(const std::string& path);
bool liveTuneLoadDefaultPreset(std::string* outLoadedPath = nullptr);
/** MP3 path from the last loaded preset JSON (`mp3` field), resolved relative to preset file. */
std::string liveTunePresetMp3Path();
