#pragma once

#include "codec_abstract_codec.h"
#include "../base/media_common.h"
#include <mutex>
#include <memory>

extern "C" {
#include <libavcodec/avcodec.h>
#include <libavutil/hwcontext.h>
#include <libavutil/opt.h>
#include <libavformat/avformat.h>
}

namespace av {
namespace codec {

/**
 * 视频编码器参数
 */
struct VideoEncoderParams : public CodecParams {
    int bitRate = 2000000;          // 比特率 (bps)
    int width = 1920;               // 宽度
    int height = 1080;              // 高度
    int fps = 30;                   // 帧率
    int gopSize = 30;               // GOP大小
    int maxBFrames = 0;             // B帧数量
    std::string preset = "medium";  // 编码预设
    std::string tune = "";          // 调优参数
    bool lowLatency = false;        // 低延迟模式
    bool hardwareAccel = true;      // 硬件加速
    AVPixelFormat pixelFormat = AV_PIX_FMT_YUV420P; // 像素格式
    
    VideoEncoderParams() {
        type = MediaType::VIDEO;
    }
};

/**
 * 像素格式转换器
 */
class PixelFormatConverter {
    friend class VideoEncoder;
    
public:
    PixelFormatConverter(AVPixelFormat srcFormat, AVPixelFormat dstFormat);
    ~PixelFormatConverter();
    
    bool setSize(int width, int height);
    AVFramePtr convert(const AVFramePtr& srcFrame);
    
private:
    struct SwsContext* swsCtx_;
    AVPixelFormat srcFormat_;
    AVPixelFormat dstFormat_;
    int width_;
    int height_;
    AVFramePtr dstFrame_;
};

/**
 * 视频编码器实现
 */
class VideoEncoder : public AbstractEncoder {
public:
    VideoEncoder();
    ~VideoEncoder() override;

    // AbstractCodec 接口实现
    ErrorCode open(const CodecParams& params) override;
    void close() override;
    ErrorCode flush() override;

    // AbstractEncoder 接口实现
    ErrorCode encode(const AVFramePtr& frame, std::vector<AVPacketPtr>& packets) override;
    ErrorCode finishEncode(std::vector<AVPacketPtr>& packets) override;

    // 视频编码器特有功能
    const VideoEncoderParams& getVideoParams() const { return videoParams_; }
    
    // 获取支持的编码器列表
    static std::vector<std::string> getSupportedEncoders();
    
    // 检查编码器是否支持硬件加速
    static bool isHardwareEncoder(const std::string& codecName);
    
    // 获取推荐的编码器
    static std::string getRecommendedEncoder();
    
    // 硬件编码器名称
    static constexpr const char* HARDWARE_ENCODERS[] = {
        "h264_nvenc",   // NVIDIA
        "h264_qsv",     // Intel Quick Sync
        "h264_amf",     // AMD
        "h264_videotoolbox", // Apple
    };
    
    // 软件编码器名称
    static constexpr const char* SOFTWARE_ENCODERS[] = {
        "libx264",
        "libx265",
    };

protected:
    bool validateParams(const CodecParams& params) override;

private:
    // 初始化编码器
    ErrorCode initEncoder();
    
    // 设置编码器参数
    ErrorCode setupEncoderParams();
    
    // 设置硬件加速
    ErrorCode setupHardwareAcceleration();
    
    // 设置硬件帧上下文
    ErrorCode setupHardwareFrameContext();
    
    // 转换帧格式
    AVFramePtr convertFrame(const AVFramePtr& frame);
    
    // 转换到硬件帧
    AVFramePtr transferToHardware(const AVFramePtr& frame);
    
    // 编码单个帧
    ErrorCode encodeFrame(const AVFramePtr& frame, std::vector<AVPacketPtr>& packets);
    
    // 接收编码后的包
    ErrorCode receivePackets(std::vector<AVPacketPtr>& packets);
    
    // 获取硬件设备类型
    AVHWDeviceType getHardwareDeviceType() const;
    
    // 获取硬件像素格式
    AVPixelFormat getHardwarePixelFormat() const;
    
    // 查找可用的编码器
    static void findUsableEncoders();

private:
    VideoEncoderParams videoParams_;        // 视频编码参数
    
    // 硬件加速相关
    bool isHardwareEncoder_;                // 是否硬件编码器
    AVBufferRef* hwDeviceCtx_;              // 硬件设备上下文
    AVFramePtr hwFrame_;                    // 硬件帧缓冲
    
    // 格式转换
    std::unique_ptr<PixelFormatConverter> converter_;
    AVFramePtr convertedFrame_;             // 转换后的帧
    
    // 线程安全
    std::mutex encodeMutex_;
    
    // 支持的编码器列表
    static std::vector<std::string> supportedEncoders_;
    static std::once_flag encodersInitFlag_;
};

/**
 * 视频编码器工厂
 */
class VideoEncoderFactory {
public:
    /**
     * 创建视频编码器
     */
    static std::unique_ptr<VideoEncoder> create(const std::string& codecName = "");
    
    /**
     * 创建最佳视频编码器（自动选择硬件/软件）
     */
    static std::unique_ptr<VideoEncoder> createBest(bool preferHardware = true);
};

} // namespace codec
} // namespace av