#pragma once

#include "../base/types.h"
#include <memory>
#include <functional>
#include <vector>
#include <string>
#include <shared_mutex>
#include <mutex>

namespace av {
namespace codec {

/**
 * 编解码器状态
 */
enum class CodecState {
    IDLE,       // 空闲
    OPENED,     // 已打开
    RUNNING,    // 运行中
    FLUSHING,   // 刷新中
    CLOSED,     // 已关闭
    ERROR       // 错误
};

/**
 * 编解码器类型
 */
enum class CodecType {
    ENCODER,    // 编码器
    DECODER     // 解码器
};

/**
 * 抽象编解码器基类
 * 提供编解码器的通用接口和状态管理
 */
class AbstractCodec {
public:
    AbstractCodec(MediaType mediaType, CodecType codecType);
    virtual ~AbstractCodec();

    // 禁止拷贝
    AbstractCodec(const AbstractCodec&) = delete;
    AbstractCodec& operator=(const AbstractCodec&) = delete;

    /**
     * 打开编解码器
     * @param params 编解码参数
     * @return 成功返回ErrorCode::SUCCESS
     */
    virtual ErrorCode open(const CodecParams& params) = 0;

    /**
     * 关闭编解码器
     */
    virtual void close() = 0;

    /**
     * 刷新编解码器缓冲区
     * @return 成功返回ErrorCode::SUCCESS
     */
    virtual ErrorCode flush() = 0;

    /**
     * 重置编解码器
     * @return 成功返回ErrorCode::SUCCESS
     */
    virtual ErrorCode reset();

    // 状态查询（线程安全）
    CodecState getState() const { 
        std::shared_lock<std::shared_mutex> lock(stateMutex_);
        return state_; 
    }
    MediaType getMediaType() const { return mediaType_; }
    CodecType getCodecType() const { return codecType_; }
    bool isOpened() const { 
        std::shared_lock<std::shared_mutex> lock(stateMutex_);
        return state_ == CodecState::OPENED || state_ == CodecState::RUNNING; 
    }
    bool isRunning() const { 
        std::shared_lock<std::shared_mutex> lock(stateMutex_);
        return state_ == CodecState::RUNNING; 
    }
    bool hasError() const { 
        std::shared_lock<std::shared_mutex> lock(stateMutex_);
        return state_ == CodecState::ERROR; 
    }

    // 参数获取
    const CodecParams& getParams() const { return params_; }

    // 统计信息
    struct Statistics {
        uint64_t processedFrames = 0;   // 处理的帧数
        uint64_t droppedFrames = 0;     // 丢弃的帧数
        uint64_t errorCount = 0;        // 错误次数
        double avgProcessTime = 0.0;    // 平均处理时间(ms)
        uint64_t totalBytes = 0;        // 总字节数
    };
    
    Statistics getStatistics() const { 
        std::lock_guard<std::mutex> lock(statsMutex_);
        return stats_; 
    }
    void resetStatistics();

    // 回调函数设置
    using ErrorCallback = std::function<void(ErrorCode error, const std::string& message)>;
    void setErrorCallback(ErrorCallback callback) { errorCallback_ = std::move(callback); }
    
    // 错误码转换工具
    static ErrorCode convertFFmpegError(int ffmpegError);
    static std::string getErrorDescription(ErrorCode error);

protected:
    // RAII资源管理包装器
    template<typename T, typename Deleter>
    class ResourceGuard {
    private:
        T* resource_;
        Deleter deleter_;
        bool released_;
        
    public:
        explicit ResourceGuard(T* resource, Deleter deleter) 
            : resource_(resource), deleter_(deleter), released_(false) {}
            
        ~ResourceGuard() {
            if (!released_ && resource_) {
                deleter_(resource_);
            }
        }
        
        // 禁止拷贝
        ResourceGuard(const ResourceGuard&) = delete;
        ResourceGuard& operator=(const ResourceGuard&) = delete;
        
        // 允许移动
        ResourceGuard(ResourceGuard&& other) noexcept
            : resource_(other.resource_), deleter_(std::move(other.deleter_)), released_(other.released_) {
            other.released_ = true;
        }
        
        ResourceGuard& operator=(ResourceGuard&& other) noexcept {
            if (this != &other) {
                if (!released_ && resource_) {
                    deleter_(resource_);
                }
                resource_ = other.resource_;
                deleter_ = std::move(other.deleter_);
                released_ = other.released_;
                other.released_ = true;
            }
            return *this;
        }
        
        T* get() const { return resource_; }
        T* release() { released_ = true; return resource_; }
        void reset(T* newResource = nullptr) {
            if (!released_ && resource_) {
                deleter_(resource_);
            }
            resource_ = newResource;
            released_ = false;
        }
        
        explicit operator bool() const { return resource_ != nullptr && !released_; }
    };
    
    // 状态管理助手，确保状态一致性
    class StateGuard {
    private:
        AbstractCodec* codec_;
        CodecState originalState_;
        CodecState targetState_;
        bool committed_;
        
    public:
        StateGuard(AbstractCodec* codec, CodecState targetState)
            : codec_(codec), targetState_(targetState), committed_(false) {
            if (codec_) {
                originalState_ = codec_->getState();
                codec_->setState(targetState_);
            }
        }
        
        ~StateGuard() {
            if (!committed_ && codec_) {
                codec_->setState(originalState_);
            }
        }
        
        void commit() { committed_ = true; }
        
        // 禁止拷贝和移动
        StateGuard(const StateGuard&) = delete;
        StateGuard& operator=(const StateGuard&) = delete;
        StateGuard(StateGuard&&) = delete;
        StateGuard& operator=(StateGuard&&) = delete;
    };
    
    /**
     * 设置编解码器状态
     */
    void setState(CodecState state);

    /**
     * 报告错误
     */
    void reportError(ErrorCode error, const std::string& message = "");

    /**
     * 更新统计信息
     */
    void updateStats(bool success, double processTime, uint64_t bytes = 0);

    /**
     * 验证参数有效性
     */
    virtual bool validateParams(const CodecParams& params) = 0;

protected:
    MediaType mediaType_;           // 媒体类型
    CodecType codecType_;           // 编解码器类型
    CodecState state_;              // 当前状态
    CodecParams params_;            // 编解码参数
    Statistics stats_;              // 统计信息
    ErrorCallback errorCallback_;   // 错误回调
    
    // FFmpeg相关
    AVCodecContextPtr codecCtx_;    // 编解码上下文
    const AVCodec* codec_;          // 编解码器
    
    // 线程安全机制
    mutable std::shared_mutex stateMutex_;    // 状态读写锁
    mutable std::mutex statsMutex_;           // 统计信息锁
    mutable std::mutex resourceMutex_;        // 资源操作锁
};

/**
 * 抽象编码器基类
 */
class AbstractEncoder : public AbstractCodec {
public:
    AbstractEncoder(MediaType mediaType) : AbstractCodec(mediaType, CodecType::ENCODER) {}
    virtual ~AbstractEncoder() = default;

    /**
     * 编码一帧数据
     * @param frame 输入帧
     * @param packets 输出包列表
     * @return 成功返回ErrorCode::SUCCESS
     */
    virtual ErrorCode encode(const AVFramePtr& frame, std::vector<AVPacketPtr>& packets) = 0;

    /**
     * 结束编码（刷新缓冲区）
     * @param packets 输出包列表
     * @return 成功返回ErrorCode::SUCCESS
     */
    virtual ErrorCode finishEncode(std::vector<AVPacketPtr>& packets) = 0;

    // 编码器特有的回调
    using FrameCallback = std::function<void(const AVFramePtr& frame)>;
    using PacketCallback = std::function<void(const AVPacketPtr& packet)>;
    
    void setFrameCallback(FrameCallback callback) { frameCallback_ = std::move(callback); }
    void setPacketCallback(PacketCallback callback) { packetCallback_ = std::move(callback); }

protected:
    FrameCallback frameCallback_;   // 帧回调
    PacketCallback packetCallback_; // 包回调
};

/**
 * 抽象解码器基类
 */
class AbstractDecoder : public AbstractCodec {
public:
    AbstractDecoder(MediaType mediaType) : AbstractCodec(mediaType, CodecType::DECODER) {}
    virtual ~AbstractDecoder() = default;

    /**
     * 解码一个包
     * @param packet 输入包
     * @param frames 输出帧列表
     * @return 成功返回ErrorCode::SUCCESS
     */
    virtual ErrorCode decode(const AVPacketPtr& packet, std::vector<AVFramePtr>& frames) = 0;

    /**
     * 结束解码（刷新缓冲区）
     * @param frames 输出帧列表
     * @return 成功返回ErrorCode::SUCCESS
     */
    virtual ErrorCode finishDecode(std::vector<AVFramePtr>& frames) = 0;

    // 解码器特有的回调
    using PacketCallback = std::function<void(const AVPacketPtr& packet)>;
    using FrameCallback = std::function<void(const AVFramePtr& frame)>;
    
    void setPacketCallback(PacketCallback callback) { packetCallback_ = std::move(callback); }
    void setFrameCallback(FrameCallback callback) { frameCallback_ = std::move(callback); }

protected:
    PacketCallback packetCallback_; // 包回调
    FrameCallback frameCallback_;   // 帧回调
};

/**
 * 编解码器工厂类
 */
class CodecFactory {
public:
    /**
     * 创建编码器
     */
    static std::unique_ptr<AbstractEncoder> createEncoder(MediaType mediaType, const std::string& codecName);

    /**
     * 创建解码器
     */
    static std::unique_ptr<AbstractDecoder> createDecoder(MediaType mediaType, const std::string& codecName);

    /**
     * 获取支持的编码器列表
     */
    static std::vector<std::string> getSupportedEncoders(MediaType mediaType);

    /**
     * 获取支持的解码器列表
     */
    static std::vector<std::string> getSupportedDecoders(MediaType mediaType);

    /**
     * 检查编解码器是否支持
     */
    static bool isCodecSupported(const std::string& codecName, CodecType type, MediaType mediaType);
};

} // namespace codec
} // namespace av