#pragma once

#ifndef ANIMATION_LAYER_H
#define ANIMATION_LAYER_H

#include <string>
#include <vector>
#include <map>
#include <memory>
#include <functional>
#include <stduuid/uuid.h>

namespace Vivid2D {
    class Model2D;
    namespace Render::Texture {
        class Texture;
    }
}

namespace Vivid2D::util {

    // ==================== 前置声明/内部类声明 ====================
    class AnimationClip; // 假设这是一个独立的类
    class AnimationLayer;

    // 接口和适配器 (C++ 中使用虚基类)
    class AnimationEventListener;

    // 关键帧和插值
    enum class InterpolationType {
        LINEAR, STEP, SMOOTH, EASE_IN, EASE_OUT, EASE_IN_OUT
    };

    class VIVID_2D_MYDLL_API Keyframe {
    public:
        Keyframe(float time, float value, InterpolationType interpolation)
            : m_time(time), m_value(value), m_interpolation(interpolation) {}

        Keyframe copy() const { return Keyframe(m_time, m_value, m_interpolation); }

        float getTime() const { return m_time; }
        float getValue() const { return m_value; }
        InterpolationType getInterpolation() const { return m_interpolation; }
    private:
        float m_time;
        float m_value;
        InterpolationType m_interpolation;
    };

    // 动画轨道类 (AnimationTrack)
    class VIVID_2D_MYDLL_API AnimationTrack {
    public:
        AnimationTrack(std::string parameterId);

        void addKeyframe(float time, float value);
        void addKeyframe(float time, float value, InterpolationType interpolation);
        float sample(float time) const;

        AnimationTrack copy() const;

        // Getters & Setters
        const std::string& getParameterId() const { return m_parameterId; }
        const std::vector<Keyframe>& getKeyframes() const { return m_keyframes; }
        bool isEnabled() const { return m_enabled; }
        void setEnabled(bool enabled) { m_enabled = enabled; }
        InterpolationType getInterpolation() const { return m_interpolation; }
        void setInterpolation(InterpolationType interpolation) { m_interpolation = interpolation; }

    private:
        float interpolate(const Keyframe& kf1, const Keyframe& kf2, float time) const;
        std::string m_parameterId;
        std::vector<Keyframe> m_keyframes;
        bool m_enabled;
        InterpolationType m_interpolation;
    };

    // 动画事件类 (AnimationEvent)
    class VIVID_2D_MYDLL_API AnimationEvent {
    public:
        using Action = std::function<void()>;

        AnimationEvent(std::string name, float time, Action action);

        void trigger();
        void reset();

        // Getters
        const std::string& getName() const { return m_name; }
        float getTime() const { return m_time; }
        bool isTriggered() const { return m_triggered; }

    private:
        std::string m_name;
        float m_time;
        Action m_action;
        bool m_triggered;
    };

    // 动画事件监听器接口 (AnimationEventListener - 虚基类)
    class VIVID_2D_MYDLL_API AnimationEventListener {
    public:
        virtual ~AnimationEventListener() = default;
        virtual void onAnimationStarted(AnimationLayer* layer, AnimationClip* clip) {}
        virtual void onAnimationStopped(AnimationLayer* layer, AnimationClip* clip) {}
        virtual void onAnimationPaused(AnimationLayer* layer, AnimationClip* clip) {}
        virtual void onAnimationResumed(AnimationLayer* layer, AnimationClip* clip) {}
        virtual void onAnimationCompleted(AnimationLayer* layer, AnimationClip* clip) {}
        virtual void onAnimationLooped(AnimationLayer* layer, AnimationClip* clip) {}
        virtual void onEventTriggered(AnimationLayer* layer, AnimationEvent* event) {}
    };

    // ==================== AnimationLayer 类 ====================

    class VIVID_2D_MYDLL_API AnimationLayer {
    public:
        // 混合模式枚举
        enum class BlendMode {
            OVERRIDE, ADDITIVE, MULTIPLICATIVE, AVERAGE
        };

        using UUID = uuids::uuid;
        AnimationLayer(const AnimationLayer& other) = delete;
        AnimationLayer& operator=(const AnimationLayer& other) = delete;
        AnimationLayer(AnimationLayer&& other) noexcept;
        AnimationLayer& operator=(AnimationLayer&& other) noexcept;

        // ==================== 构造器 ====================
        explicit AnimationLayer(std::string name);
        AnimationLayer(std::string name, float weight);

        // ==================== 轨道管理 ====================
        std::unique_ptr<AnimationTrack> addTrack(const std::string& parameterId);
        AnimationTrack* getTrack(const std::string& parameterId) const;
        bool removeTrack(const std::string& parameterId);
        bool hasTrack(const std::string& parameterId) const;

        // ==================== 剪辑管理 ====================
        void addClip(AnimationClip* clip); // 使用裸指针或 shared_ptr, 假定 Model2D 管理 Clips
        bool removeClip(AnimationClip* clip);
        void playClip(const std::string& clipName);
        void playClip(AnimationClip* clip);
        void stop();
        void pause();
        void resume();

        // ==================== 更新系统 ====================
        void update(float deltaTime, Model2D* model);

        // ==================== 事件系统 ====================
        void addEvent(const std::string& eventName, float time, AnimationEvent::Action action);
        void resetEvents();
        void addEventListener(AnimationEventListener* listener); // 裸指针，不拥有所有权
        bool removeEventListener(AnimationEventListener* listener);

        // ==================== 参数覆盖 ====================
        void setParameterOverride(const std::string& parameterId, float value);
        void clearParameterOverride(const std::string& parameterId);
        void clearAllOverrides();

        // ==================== 工具方法 ====================
        float getProgress() const;
        void setProgress(float progress);
        void seek(float time);
        AnimationLayer copy() const;

        // ==================== Getter/Setter ====================
        const std::string& getName() const { return m_name; }
        const UUID& getUuid() const { return m_uuid; }
        float getWeight() const { return m_weight; }
        void setWeight(float weight);
        bool isEnabled() const { return m_enabled; }
        void setEnabled(bool enabled) { m_enabled = enabled; }
        BlendMode getBlendMode() const { return m_blendMode; }
        void setBlendMode(BlendMode blendMode) { m_blendMode = blendMode; }
        int getPriority() const { return m_priority; }
        void setPriority(int priority) { m_priority = priority; }
        const std::map<std::string, std::unique_ptr<AnimationTrack>>& getTracks() const { return m_tracks; }
        const std::vector<AnimationClip*>& getClips() const { return m_clips; }
        AnimationClip* getCurrentClip() const { return m_currentClip; }
        float getPlaybackSpeed() const { return m_playbackSpeed; }
        void setPlaybackSpeed(float playbackSpeed);
        bool isLooping() const { return m_looping; }
        void setLooping(bool looping) { m_looping = looping; }
        float getCurrentTime() const { return m_currentTime; }
        bool isPlaying() const { return m_playing; }
        bool isPaused() const { return m_paused; }
        const std::map<std::string, float>& getParameterOverrides() const { return m_parameterOverrides; }

    private:
        // ==================== 私有成员变量 ====================
        std::string m_name;
        UUID m_uuid;
        float m_weight;
        bool m_enabled;
        BlendMode m_blendMode;
        int m_priority;

        std::map<std::string, std::unique_ptr<AnimationTrack>> m_tracks;
        std::vector<AnimationClip*> m_clips; // 假设 AnimationClip 是共享的，使用裸指针
        AnimationClip* m_currentClip = nullptr;
        float m_playbackSpeed;
        bool m_looping;

        float m_currentTime;
        bool m_playing;
        bool m_paused;
        std::map<std::string, float> m_parameterOverrides;

        std::vector<AnimationEventListener*> m_eventListeners;
        std::map<std::string, std::vector<std::unique_ptr<AnimationEvent>>> m_events;

        // ==================== 私有辅助方法 ====================
        void checkEvents();
        void applyAnimation(Vivid2D::Model2D* model);
        void applyClipAnimation(Vivid2D::Model2D* model);
        void applyTrackAnimation(Vivid2D::Model2D* model);
        float applyBlending(Vivid2D::Model2D* model, const std::string& paramId, float newValue);

        // 混合函数
        float blendOverride(float current, float target);
        float blendAdditive(float current, float target);
        float blendMultiplicative(float current, float target);
        float blendAverage(float current, float target);

        // 事件通知
        void notifyAnimationStarted(AnimationClip* clip);
        void notifyAnimationStopped(AnimationClip* clip);
        void notifyAnimationPaused(AnimationClip* clip);
        void notifyAnimationResumed(AnimationClip* clip);
        void notifyAnimationCompleted(AnimationClip* clip);
        void notifyAnimationLooped(AnimationClip* clip);
        void notifyEventTriggered(AnimationEvent* event);
    };

} // namespace Vivid2D::util

#endif // ANIMATION_LAYER_H
