// LineEffect.h - Line clearing visual and audio effects
#pragma once
#include <SDL3/SDL.h>
#include <vector>
#include <random>
#include <array>

#include "../core/Game.h"

class LineEffect {
public:
    struct Particle {
        enum class Style { Shard, Ember };
        float x, y;
        float vx, vy;
        float size;
        float alpha;
        float life;
        float lifeSpan;
        int blockType;
        SDL_Color color;
        Style style;

        Particle(float px, float py, Style particleStyle, SDL_Color tint);
        void update(float dt);
        void render(SDL_Renderer* renderer, SDL_Texture* blocksTex);
        bool isAlive() const { return life < lifeSpan && alpha > 0.01f; }
    };

    struct Spark {
        float x, y;
        float vx, vy;
        float life;
        float maxLife;
        float thickness;
        SDL_Color color;

        Spark(float px, float py, SDL_Color tint);
        void update(float dt);
        void render(SDL_Renderer* renderer) const;
        bool isAlive() const { return life < maxLife; }
    };

    struct GlowPulse {
        float x, y;
        float baseRadius;
        float maxRadius;
        float life;
        float maxLife;
        SDL_Color color;

        GlowPulse(float px, float py, float baseR, float maxR, SDL_Color tint);
        void update(float dt);
        void render(SDL_Renderer* renderer) const;
        bool isAlive() const { return life < maxLife; }
    };

    enum class AnimationState {
        IDLE,
        FLASH_WHITE,
        EXPLODE_BLOCKS,
        BLOCKS_DROP
    };

    LineEffect();
    ~LineEffect();
    
    bool init(SDL_Renderer* renderer);
    void shutdown();
    
    // Start line clear effect for the specified rows
    void startLineClear(const std::vector<int>& rows, int gridX, int gridY, int blockSize, int gridCols = Game::COLS, int gapPx = 0, int gapAfterCol = 0);
    
    // Update and render the effect
    bool update(float deltaTime); // Returns true if effect is complete
    void render(SDL_Renderer* renderer, SDL_Texture* blocksTex, int gridX, int gridY, int blockSize, int gapPx = 0, int gapAfterCol = 0);
    float getRowDropOffset(int row) const;
    
    // Audio
    void playLineClearSound(int lineCount);
    
    bool isActive() const { return state != AnimationState::IDLE; }

private:
    SDL_Renderer* renderer{nullptr};
    AnimationState state{AnimationState::IDLE};
    float timer{0.0f};
    std::vector<int> clearingRows;
    std::vector<Particle> particles;
    std::vector<Spark> sparks;
    std::vector<GlowPulse> glowPulses;
    std::mt19937 rng{std::random_device{}()};
    
    // Audio resources
    SDL_AudioStream* audioStream{nullptr};
    std::vector<int16_t> lineClearSample;
    std::vector<int16_t> tetrisSample;
    
    // Animation timing - Flash then immediate explosion effect
    static constexpr float FLASH_DURATION = 0.18f;   // Slightly longer flash for anticipation
    static constexpr float EXPLODE_DURATION = 0.9f;  // Extended fireworks time
    static constexpr float DROP_DURATION = 0.35f;    // Allow lingering sparks before collapse
    
    void createParticles(int row, int gridX, int gridY, int blockSize);
    void spawnShardBurst(float x, float y, SDL_Color tint);
    void spawnSparkBurst(float x, float y, SDL_Color tint);
    void spawnGlowPulse(float x, float y, float blockSize, SDL_Color tint);
    void updateParticles(float dt);
    void updateSparks(float dt);
    void updateGlowPulses(float dt);
    void renderFlash(int gridX, int gridY, int blockSize);
    void renderExplosion(SDL_Texture* blocksTex);
    void renderGlowPulses();
    void renderSparks();
    void renderParticleGlows();
    bool loadAudioSample(const std::string& path, std::vector<int16_t>& sample);
    void initAudio();
    SDL_Color pickFireColor() const;

    std::array<float, Game::ROWS> rowDropTargets{};
    float dropProgress = 0.0f;
    int dropBlockSize = 0;
    int effectGridCols = Game::COLS;
    int effectGapPx = 0;
    int effectGapAfterCol = 0;
};
