#pragma once

#ifndef ANIMATION_CLIP_H
#define ANIMATION_CLIP_H

#include <string>
#include <vector>
#include <map>
#include <memory>
#include <algorithm>
#include <functional>
#include <cmath>
#include <chrono>
#include <stduuid/uuid.h>
#include <set>

#include "AnimationLayer.h"

namespace Vivid2D::util {
    // 事件标记类
    class AnimationEventMarker {
    public:
        using Action = std::function<void()>;

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

        void trigger();
        void reset();
        AnimationEventMarker copy() const;

        // Getter方法
        const std::string& getName() const { return m_name; }
        float getTime() const { return m_time; }
        const Action& getAction() const { return m_action; }
        bool isTriggered() const { return m_triggered; }

        AnimationEventMarker(AnimationEventMarker&&) noexcept = default;
        AnimationEventMarker& operator=(AnimationEventMarker&&) noexcept = default;
    private:
        std::string m_name;
        float m_time;
        Action m_action; // C++ 中使用 std::function<void()> 替代 Runnable
        bool m_triggered;
    };

    // 动画曲线类
    class VIVID_2D_MYDLL_API AnimationCurve {
    public:
        AnimationCurve(std::string parameterId, float defaultValue);

        AnimationCurve(const AnimationCurve& other);
        AnimationCurve& operator=(const AnimationCurve& other);
        AnimationCurve(AnimationCurve&& other) noexcept = default;
        AnimationCurve& operator=(AnimationCurve&& other) noexcept = default;

        Keyframe* addKeyframe(float time, float value);
        Keyframe* addKeyframe(float time, float value, InterpolationType interpolation);
        bool removeKeyframe(float time);
        Keyframe* getKeyframe(float time);

        float sample(float time) const;
        float* getValueRange(); // [min, max]
        AnimationCurve copy() const;

        // Getter方法
        const std::string& getParameterId() const { return m_parameterId; }
        const std::vector<std::unique_ptr<Keyframe>>& getKeyframes() const { return m_keyframes; }
        float getDefaultValue() const { return m_defaultValue; }

    private:
        float interpolate(const Keyframe& kf1, const Keyframe& kf2, float time) const;
        // 辅助插值函数
        static float lerp(float a, float b, float t);
        static float smoothLerp(float a, float b, float t);
        static float easeInLerp(float a, float b, float t);
        static float easeOutLerp(float a, float b, float t);
        static float easeInOutLerp(float a, float b, float t);

        std::string m_parameterId;
        std::vector<std::unique_ptr<Keyframe>> m_keyframes;
        float m_defaultValue;
    };


    // ==================== AnimationClip 类 ====================

    class AnimationClip {
    public:
        using UUID = uuids::uuid;
        using TimeStamp = long long;

        // ==================== 构造器 ====================
        explicit AnimationClip(std::string name);
        AnimationClip(std::string name, float duration, float fps);

        // ==================== 曲线管理 ====================
        AnimationCurve* addCurve(const std::string& parameterId);
        AnimationCurve* addCurve(const std::string& parameterId, float defaultValue);
        AnimationCurve* getCurve(const std::string& parameterId);
        bool removeCurve(const std::string& parameterId);
        bool hasCurve(const std::string& parameterId) const;
        std::set<std::string> getCurveParameterIds() const;

        // ==================== 关键帧管理 ====================
        Keyframe* addKeyframe(const std::string& parameterId, float time, float value);
        Keyframe* addKeyframe(const std::string& parameterId, float time, float value, InterpolationType interpolation);
        bool removeKeyframe(const std::string& parameterId, float time);
        Keyframe* getKeyframe(const std::string& parameterId, float time);
        std::vector<const Keyframe*> getKeyframes(const std::string& parameterId);

        // ==================== 采样系统 ====================
        std::map<std::string, float> sample(float time);
        float sampleParameter(const std::string& parameterId, float time);
        std::map<std::string, float> sampleLooped(float time);

        // ==================== 事件标记管理 ====================
        AnimationEventMarker* addEventMarker(const std::string& name, float time);
        AnimationEventMarker* addEventMarker(const std::string& name, float time, AnimationEventMarker::Action action);
        bool removeEventMarker(const std::string& name);
        std::vector<AnimationEventMarker*> getEventMarkersInRange(float startTime, float endTime);
        void triggerEventMarkers(float time, float tolerance);
        void resetEventMarkers();

        // ==================== 工具方法 ====================
        void merge(const AnimationClip& other);
        AnimationClip copy() const;
        int getFrameCount() const;
        int timeToFrame(float time) const;
        float frameToTime(int frame) const;
        bool isTimeInRange(float time) const;
        std::map<std::string, std::vector<float>> getValueBounds(); // [min, max]

        // ==================== Getter/Setter ====================
        const std::string& getName() const { return m_name; }
        const UUID& getUuid() const { return m_uuid; }
        float getDuration() const { return m_duration; }
        void setDuration(float duration);
        float getFramesPerSecond() const { return m_framesPerSecond; }
        void setFramesPerSecond(float framesPerSecond);
        bool isLooping() const { return m_looping; }
        void setLooping(bool looping) { m_looping = looping; }

        const std::map<std::string, std::unique_ptr<AnimationCurve>>& getCurves() const;
        const std::vector<std::unique_ptr<AnimationEventMarker>>& getEventMarkers() const;
        const std::map<std::string, float>& getDefaultValues() const { return m_defaultValues; }

        const std::string& getAuthor() const { return m_author; }
        void setAuthor(std::string author) { m_author = std::move(author); }
        const std::string& getDescription() const { return m_description; }
        void setDescription(std::string description) { m_description = std::move(description); }
        TimeStamp getCreationTime() const { return m_creationTime; }
        TimeStamp getLastModifiedTime() const { return m_lastModifiedTime; }
        const std::map<std::string, std::string>& getUserData() const { return m_userData; }
        void setUserData(std::map<std::string, std::string> userData);

        // ==================== Object 方法 ====================
        bool operator==(const AnimationClip& other) const { return m_uuid == other.m_uuid; }

    private:
        // ==================== 私有成员变量 ====================
        std::string m_name;
        UUID m_uuid;
        float m_duration;
        float m_framesPerSecond;
        bool m_looping;

        std::map<std::string, std::unique_ptr<AnimationCurve>> m_curves;
        std::vector<std::unique_ptr<AnimationEventMarker>> m_eventMarkers;
        std::map<std::string, float> m_defaultValues;

        std::string m_author;
        std::string m_description;
        TimeStamp m_creationTime;
        TimeStamp m_lastModifiedTime;
        std::map<std::string, std::string> m_userData;

        // ==================== 私有辅助方法 ====================
        AnimationCurve* getOrCreateCurve(const std::string& parameterId);
        void updateDurationIfNeeded(float time);
        void markModified();
        static TimeStamp getCurrentTimeMillis();
    };

} // namespace Vivid2D::util

#endif // ANIMATION_CLIP_H
