#pragma once

#include <SDL3/SDL.h>
#include <random>
#include <vector>

struct SpaceWarpSettings {
    float baseSpawnRange = 1.45f;        // logical radius for initial star positions
    float warpFactorScale = 122.85f;       // scales perspective factor so stars spread faster or slower
    float spawnMargin = 60.0f;          // how far offscreen a star can travel before respawn
    float minShade = 0.85f;              // lower bound for per-star brightness multiplier
    float maxShade = 1.15f;              // upper bound for per-star brightness multiplier
    float minSpeed = 120.0f;             // slowest warp velocity (higher feels faster motion)
    float maxSpeed = 280.0f;             // fastest warp velocity
    float minDotSize = 2.5f;             // smallest star size in pixels
    float maxDotSize = 4.5f;             // largest star size in pixels
    float minAlpha = 70.0f;             // base opacity even for distant stars
    float alphaDepthBoost = 160.0f;      // extra opacity applied as stars approach the camera
    float minColor = 180.0f;             // clamp for minimum grayscale value
    float maxColor = 205.0f;             // clamp for maximum grayscale value
    float baseShadeScale = 0.75f;        // baseline multiplier applied to the sampled grayscale shade
    float depthColorScale = 0.55f;       // how much depth affects the grayscale brightness
    bool drawTrails = true;             // when true, also render streak lines for hyper-speed look
    float trailAlphaScale = 0.75f;       // relative opacity for streak lines vs dots
    float maxTrailLength = 36.0f;        // clamp length of each streak in pixels
    float cometSpawnIntervalMin = 2.8f;  // minimum seconds between comet spawns
    float cometSpawnIntervalMax = 6.5f;  // maximum seconds between comet spawns
    float cometSpeedMultiplierMin = 2.2f;// min multiplier for comet forward velocity
    float cometSpeedMultiplierMax = 4.5f;// max multiplier for comet forward velocity
    float cometMinTrail = 140.0f;        // minimum comet trail length in pixels
    float cometMaxTrail = 280.0f;        // maximum comet trail length in pixels
    float cometMinSize = 3.5f;           // minimum comet head size
    float cometMaxSize = 6.5f;           // maximum comet head size
};

struct SpaceWarpFlightMotion {
    float forwardScale = 1.0f;    // multiplier applied to each star's forward velocity (negative = backwards)
    float lateralSpeed = 0.0f;    // normalized horizontal drift speed (left/right)
    float verticalSpeed = 0.0f;   // normalized vertical drift speed (up/down)
};

enum class SpaceWarpFlightMode {
    Forward = 0,
    BankLeft,
    BankRight,
    Reverse,
    Custom
};

class SpaceWarp {
public:
    SpaceWarp();
    void init(int width, int height, int starCount = 320);
    void resize(int width, int height);
    void update(float deltaSeconds);
    void draw(SDL_Renderer* renderer, float alphaScale = 1.0f);
    void setSettings(const SpaceWarpSettings& newSettings);
    const SpaceWarpSettings& getSettings() const { return settings; }
    void setFlightMode(SpaceWarpFlightMode mode);
    SpaceWarpFlightMode getFlightMode() const { return flightMode; }
    void setFlightMotion(const SpaceWarpFlightMotion& motion); // overrides mode with Custom
    const SpaceWarpFlightMotion& getFlightMotion() const { return motion; }
    void setAutoPilotEnabled(bool enabled);
    bool isAutoPilotEnabled() const { return autoPilotEnabled; }

private:
    struct WarpStar {
        float x = 0.0f;
        float y = 0.0f;
        float z = 0.0f;
        float speed = 0.0f;
        float prevScreenX = 0.0f;
        float prevScreenY = 0.0f;
        float screenX = 0.0f;
        float screenY = 0.0f;
        float shade = 1.0f;
        Uint8 baseShade = 220;
    };

    struct WarpComet {
        float x = 0.0f;
        float y = 0.0f;
        float z = 0.0f;
        float speed = 0.0f;
        float life = 0.0f;
        float maxLife = 0.0f;
        float prevScreenX = 0.0f;
        float prevScreenY = 0.0f;
        float screenX = 0.0f;
        float screenY = 0.0f;
        float trailLength = 160.0f;
        float size = 4.0f;
        SDL_Color color{255, 255, 255, 255};
    };

    void respawn(WarpStar& star, bool randomDepth = true);
    bool project(const WarpStar& star, float& outX, float& outY) const;
    bool projectPoint(float x, float y, float z, float& outX, float& outY) const;
    float randomRange(float min, float max);
    void spawnComet();

    std::vector<WarpStar> stars;
    std::vector<WarpComet> comets;
    std::mt19937 rng;

    int width = 0;
    int height = 0;
    float centerX = 0.0f;
    float centerY = 0.0f;
    float warpFactor = 520.0f;

    SpaceWarpSettings settings{};
    SpaceWarpFlightMotion motion{};
    SpaceWarpFlightMode flightMode = SpaceWarpFlightMode::Forward;
    bool autoPilotEnabled = false;
    float autoTimer = 0.0f;
    float autoMinInterval = 3.5f;
    float autoMaxInterval = 7.5f;
    SpaceWarpFlightMotion motionTarget{};
    float cometSpawnTimer = 0.0f;

    float minDepth = 2.0f;
    float maxDepth = 320.0f;

    void scheduleNewAutoTarget();
};
