#include "codec_audio_decoder.h"
#include "../base/logger.h"
#include "../base/media_common.h"
#include <algorithm>
#include <sstream>
#include <thread>

extern "C" {
#include <libavcodec/avcodec.h>
#include <libavutil/channel_layout.h>
#include <libavutil/opt.h>
#include <libswresample/swresample.h>
}

namespace av {
namespace codec {

// 静态成员初始化
std::vector<std::string> AudioDecoder::supportedDecoders_;
std::once_flag AudioDecoder::decodersInitFlag_;

AudioDecoder::AudioDecoder() : AbstractDecoder(MediaType::AUDIO) {
    AV_LOGGER_DEBUG("创建音频解码器");
}

AudioDecoder::~AudioDecoder() {
    close();
    AV_LOGGER_DEBUG("音频解码器已销毁");
}

ErrorCode AudioDecoder::initialize(const CodecParams& params) {
    if (params.type != MediaType::AUDIO) {
        AV_LOGGER_ERROR("参数类型不是音频");
        return ErrorCode::INVALID_PARAMS;
    }
    
    audioParams_ = static_cast<const AudioDecoderParams&>(params);
    
    if (!validateParams(params)) {
        return ErrorCode::INVALID_PARAMS;
    }
    
    setState(CodecState::IDLE);
    AV_LOGGER_INFOF("音频解码器初始化成功: {}", audioParams_.codecName);
    
    return ErrorCode::SUCCESS;
}

ErrorCode AudioDecoder::open(const CodecParams& params) {
    std::lock_guard<std::mutex> lock(decodeMutex_);
    
    // 如果提供了参数，先初始化
    if (params.type != MediaType::UNKNOWN) {
        ErrorCode initResult = initialize(params);
        if (initResult != ErrorCode::SUCCESS) {
            return initResult;
        }
    }
    
    if (state_ != CodecState::IDLE) {
        AV_LOGGER_ERROR("解码器状态无效，无法打开");
        return ErrorCode::INVALID_STATE;
    }
    
    ErrorCode result = initDecoder();
    if (result != ErrorCode::SUCCESS) {
        return result;
    }
    
    setState(CodecState::OPENED);
    AV_LOGGER_INFOF("音频解码器已打开: {} ({}Hz, {}ch, {})", 
                   audioParams_.codecName, 
                   codecCtx_->sample_rate,
                   codecCtx_->ch_layout.nb_channels,
                   av_get_sample_fmt_name(codecCtx_->sample_fmt));
    
    return ErrorCode::SUCCESS;
}

void AudioDecoder::close() {
    std::lock_guard<std::mutex> lock(decodeMutex_);
    
    if (state_ == CodecState::IDLE) {
        return;
    }
    
    // 清理重采样器
    cleanupResampler();
    
    codecCtx_.reset();
    codec_ = nullptr;
    needResampling_ = false;
    
    setState(CodecState::IDLE);
    AV_LOGGER_DEBUG("音频解码器已关闭");
}

ErrorCode AudioDecoder::flush() {
    std::lock_guard<std::mutex> lock(decodeMutex_);
    
    if (state_ != CodecState::OPENED && state_ != CodecState::RUNNING) {
        return ErrorCode::INVALID_STATE;
    }
    
    if (codecCtx_) {
        avcodec_flush_buffers(codecCtx_.get());
    }
    
    // 重置重采样器
    if (swrCtx_) {
        swr_close(swrCtx_);
        needResampling_ = false;
    }
    
    setState(CodecState::OPENED);
    AV_LOGGER_DEBUG("音频解码器已重置");
    
    return ErrorCode::SUCCESS;
}

ErrorCode AudioDecoder::reset() {
    return flush();
}

ErrorCode AudioDecoder::decode(const AVPacketPtr& packet, std::vector<AVFramePtr>& frames) {
    // 状态检查（使用基类的线程安全方法）
    if (!isOpened()) {
        return ErrorCode::INVALID_STATE;
    }
    
    // 只在处理过程中锁定，缩小锁的粒度
    std::lock_guard<std::mutex> processLock(decodeMutex_);
    
    // 使用StateGuard确保异常安全的状态管理
    StateGuard stateGuard(this, CodecState::RUNNING);
    
    auto startTime = std::chrono::high_resolution_clock::now();
    
    ErrorCode result = decodeFrame(packet, frames);
    
    // 只有在成功时才提交状态变更
    if (result == ErrorCode::SUCCESS) {
        stateGuard.commit();
    }
    
    auto endTime = std::chrono::high_resolution_clock::now();
    double processTime = std::chrono::duration<double, std::milli>(endTime - startTime).count();
    
    int totalSamples = 0;
    for (const auto& frame : frames) {
        if (frame) {
            totalSamples += frame->nb_samples;
        }
    }
    
    updateStats(result == ErrorCode::SUCCESS, processTime, 
                packet ? packet->size : 0, totalSamples);
    
    if (frameCallback_) {
        for (const auto& frame : frames) {
            frameCallback_(frame);
        }
    }
    
    return result;
}

ErrorCode AudioDecoder::finishDecode(std::vector<AVFramePtr>& frames) {
    return decode(nullptr, frames); // 发送空包来刷新解码器
}

bool AudioDecoder::validateParams(const CodecParams& params) {
    if (params.type != MediaType::AUDIO) {
        AV_LOGGER_ERROR("参数媒体类型不是音频");
        return false;
    }
    
    const auto& audioParams = static_cast<const AudioDecoderParams&>(params);
    
    if (audioParams.codecName.empty()) {
        AV_LOGGER_ERROR("解码器名称为空");
        return false;
    }
    
    if (audioParams.sampleRate <= 0) {
        AV_LOGGER_ERROR("采样率无效");
        return false;
    }
    
    if (audioParams.channels <= 0) {
        AV_LOGGER_ERROR("声道数无效");
        return false;
    }
    
    return true;
}



ErrorCode AudioDecoder::initDecoder() {
    // 查找解码器
    codec_ = avcodec_find_decoder_by_name(audioParams_.codecName.c_str());
    if (!codec_) {
        AV_LOGGER_ERRORF("未找到解码器: {}", audioParams_.codecName);
        return ErrorCode::CODEC_NOT_FOUND;
    }
    
    if (codec_->type != AVMEDIA_TYPE_AUDIO) {
        AV_LOGGER_ERROR("解码器类型不是音频");
        return ErrorCode::INVALID_PARAMS;
    }
    
    // 创建解码上下文
    codecCtx_ = makeAVCodecContext(codec_);
    if (!codecCtx_) {
        AV_LOGGER_ERROR("分配解码上下文失败");
        return ErrorCode::MEMORY_ALLOC_FAILED;
    }
    
    // 设置解码器参数
    ErrorCode result = setupDecoderParams();
    if (result != ErrorCode::SUCCESS) {
        return result;
    }
    
    // 打开解码器前的详细日志
    AV_LOGGER_INFOF("准备打开音频解码器: {}", audioParams_.codecName);
    AV_LOGGER_INFOF("解码器参数: 采样率: {}, 声道: {}, 格式: {}, 线程数: {}", 
                   codecCtx_->sample_rate,
                   codecCtx_->ch_layout.nb_channels,
                   av_get_sample_fmt_name(codecCtx_->sample_fmt),
                   codecCtx_->thread_count);
    
    // 打开解码器
    int ret = avcodec_open2(codecCtx_.get(), codec_, nullptr);
    if (ret < 0) {
        AV_LOGGER_ERRORF("打开音频解码器失败: {} (错误码: {})", 
                        ffmpeg_utils::errorToString(ret), ret);
        
        // 详细错误分析
        if (ret == AVERROR(EINVAL)) {
            AV_LOGGER_ERROR("解码器参数无效 - 可能的原因:");
            AV_LOGGER_ERROR("  1. 不支持的采样格式或参数组合");
            AV_LOGGER_ERROR("  2. 采样率或声道数不支持");
        } else if (ret == AVERROR(ENOMEM)) {
            AV_LOGGER_ERROR("内存不足 - 无法分配解码器资源");
        }
        
        return static_cast<ErrorCode>(ret);
    }
    
    AV_LOGGER_INFOF("音频解码器打开成功: {}", audioParams_.codecName);
    
    return ErrorCode::SUCCESS;
}

ErrorCode AudioDecoder::setupDecoderParams() {
    // 设置线程数
    if (audioParams_.threadCount > 0) {
        codecCtx_->thread_count = audioParams_.threadCount;
    } else {
        codecCtx_->thread_count = std::thread::hardware_concurrency();
    }
    
    // 设置采样率（如果指定）
    if (audioParams_.sampleRate > 0) {
        codecCtx_->sample_rate = audioParams_.sampleRate;
    }
    
    // 设置声道数（如果指定）
    if (audioParams_.channels > 0) {
        av_channel_layout_default(&codecCtx_->ch_layout, audioParams_.channels);
    }
    
    // 设置采样格式（如果指定）
    if (audioParams_.sampleFormat != AV_SAMPLE_FMT_NONE) {
        codecCtx_->sample_fmt = audioParams_.sampleFormat;
    }
    
    // 低延迟设置
    if (audioParams_.lowLatency) {
        codecCtx_->flags |= AV_CODEC_FLAG_LOW_DELAY;
        codecCtx_->flags2 |= AV_CODEC_FLAG2_FAST;
    }
    
    // 针对特定解码器的优化设置
    if (audioParams_.codecName == "aac") {
        // AAC 特定设置
        av_opt_set(codecCtx_->priv_data, "dual_mono_mode", "stereo", 0);
    } else if (audioParams_.codecName == "mp3" || audioParams_.codecName == "mp3float") {
        // MP3 特定设置
        if (audioParams_.lowLatency) {
            av_opt_set_int(codecCtx_->priv_data, "skip_frame", 0, 0);
        }
    } else if (audioParams_.codecName == "opus") {
        // Opus 特定设置
        if (audioParams_.lowLatency) {
            av_opt_set_int(codecCtx_->priv_data, "apply_phase_inv", 0, 0);
        }
    }
    
    return ErrorCode::SUCCESS;
}

ErrorCode AudioDecoder::decodeFrame(const AVPacketPtr& packet, std::vector<AVFramePtr>& frames) {
    // 发送包到解码器
    int ret = avcodec_send_packet(codecCtx_.get(), packet ? packet.get() : nullptr);
    if (ret < 0 && ret != AVERROR_EOF && ret != AVERROR(EAGAIN)) {
        AV_LOGGER_ERRORF("发送包到音频解码器失败: {}", ffmpeg_utils::errorToString(ret));
        return static_cast<ErrorCode>(ret);
    }
    
    // AVERROR(EAGAIN) 表示解码器暂时无法接受更多输入，这是正常情况
    if (ret == AVERROR(EAGAIN)) {
        AV_LOGGER_DEBUGF("解码器暂时无法接受更多输入 (EAGAIN)，继续接收帧");
    }
    
    // 接收解码后的帧
    return receiveFrames(frames);
}

ErrorCode AudioDecoder::receiveFrames(std::vector<AVFramePtr>& frames) {
    while (true) {
        AVFramePtr frame = makeAVFrame();
        if (!frame) {
            return ErrorCode::MEMORY_ALLOC_FAILED;
        }
        
        int ret = avcodec_receive_frame(codecCtx_.get(), frame.get());
        if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
            break; // 需要更多输入或已结束
        }
        
        if (ret < 0) {
            ErrorCode error = AbstractCodec::convertFFmpegError(ret);
            AV_LOGGER_ERRORF("接收音频解码帧失败: {} ({})", 
                           AbstractCodec::getErrorDescription(error), 
                           ffmpeg_utils::errorToString(ret));
            return error;
        }
        
        // 格式转换（如果需要）
        auto convertedFrame = convertFrame(std::move(frame));
        if (convertedFrame) {
            frames.push_back(std::move(convertedFrame));
        }
    }
    
    return ErrorCode::SUCCESS;
}

AVFramePtr AudioDecoder::convertFrame(AVFramePtr frame) {
    if (!frame) {
        return nullptr;
    }
    
    // 检查是否需要重采样
    bool needConvert = (frame->format != audioParams_.sampleFormat) ||
                      (frame->sample_rate != audioParams_.sampleRate) ||
                      (frame->ch_layout.nb_channels != audioParams_.channels);
    
    if (!needConvert) {
        return std::move(frame); // 格式已经匹配，直接返回
    }
    
    // 设置重采样器
    ErrorCode result = setupResampler(frame.get());
    if (result != ErrorCode::SUCCESS) {
        AV_LOGGER_ERROR("设置重采样器失败");
        return nullptr;
    }
    
    // 创建输出帧
    AVFramePtr outFrame = makeAVFrame();
    if (!outFrame) {
        return nullptr;
    }
    
    outFrame->format = audioParams_.sampleFormat;
    outFrame->sample_rate = audioParams_.sampleRate;
    av_channel_layout_default(&outFrame->ch_layout, audioParams_.channels);
    
    // 计算输出采样数
    int outSamples = swr_get_out_samples(swrCtx_, frame->nb_samples);
    outFrame->nb_samples = outSamples;
    
    // 分配输出缓冲区
    if (av_frame_get_buffer(outFrame.get(), 0) < 0) {
        AV_LOGGER_ERROR("分配音频输出缓冲区失败");
        return nullptr;
    }
    
    // 执行重采样
    int convertedSamples = swr_convert(swrCtx_,
                                      outFrame->data, outSamples,
                                      (const uint8_t**)frame->data, frame->nb_samples);
    
    if (convertedSamples < 0) {
        AV_LOGGER_ERRORF("音频重采样失败: {}", ffmpeg_utils::errorToString(convertedSamples));
        return nullptr;
    }
    
    outFrame->nb_samples = convertedSamples;
    
    // 复制时间戳等信息
    av_frame_copy_props(outFrame.get(), frame.get());
    
    return outFrame;
}

ErrorCode AudioDecoder::setupResampler(const AVFrame* inputFrame) {
    if (!inputFrame) {
        return ErrorCode::INVALID_PARAMS;
    }
    
    // 检查是否需要重新配置重采样器
    bool needReconfigure = !swrCtx_ ||
                          !needResampling_ ||
                          (inputFrame->format != codecCtx_->sample_fmt) ||
                          (inputFrame->sample_rate != codecCtx_->sample_rate) ||
                          (inputFrame->ch_layout.nb_channels != codecCtx_->ch_layout.nb_channels);
    
    if (!needReconfigure) {
        return ErrorCode::SUCCESS;
    }
    
    // 清理旧的重采样器
    cleanupResampler();
    
    // 创建新的重采样器
    swrCtx_ = swr_alloc();
    if (!swrCtx_) {
        AV_LOGGER_ERROR("分配重采样器失败");
        return ErrorCode::MEMORY_ALLOC_FAILED;
    }
    
    // 设置输入参数
    av_opt_set_chlayout(swrCtx_, "in_chlayout", &inputFrame->ch_layout, 0);
    av_opt_set_int(swrCtx_, "in_sample_rate", inputFrame->sample_rate, 0);
    av_opt_set_sample_fmt(swrCtx_, "in_sample_fmt", static_cast<AVSampleFormat>(inputFrame->format), 0);
    
    // 设置输出参数
    AVChannelLayout out_ch_layout;
    av_channel_layout_default(&out_ch_layout, audioParams_.channels);
    av_opt_set_chlayout(swrCtx_, "out_chlayout", &out_ch_layout, 0);
    av_opt_set_int(swrCtx_, "out_sample_rate", audioParams_.sampleRate, 0);
    av_opt_set_sample_fmt(swrCtx_, "out_sample_fmt", audioParams_.sampleFormat, 0);
    
    // 初始化重采样器
    int ret = swr_init(swrCtx_);
    if (ret < 0) {
        AV_LOGGER_ERRORF("初始化重采样器失败: {}", ffmpeg_utils::errorToString(ret));
        cleanupResampler();
        return static_cast<ErrorCode>(ret);
    }
    
    needResampling_ = true;
    
    AV_LOGGER_INFOF("重采样器配置成功: {}Hz,{}ch,{} -> {}Hz,{}ch,{}",
                   inputFrame->sample_rate, inputFrame->ch_layout.nb_channels, 
                   av_get_sample_fmt_name(static_cast<AVSampleFormat>(inputFrame->format)),
                   audioParams_.sampleRate, audioParams_.channels,
                   av_get_sample_fmt_name(audioParams_.sampleFormat));
    
    return ErrorCode::SUCCESS;
}

void AudioDecoder::cleanupResampler() {
    if (swrCtx_) {
        swr_free(&swrCtx_);
        swrCtx_ = nullptr;
    }
    needResampling_ = false;
}

void AudioDecoder::updateStats(bool success, double decodeTime, size_t dataSize, int samples) {
    std::lock_guard<std::mutex> lock(statsMutex_);
    
    if (success) {
        stats_.decodedFrames++;
        stats_.totalSamples += samples;
        stats_.totalBytes += dataSize;
        stats_.totalDecodeTime += decodeTime;
        
        // 如果启用了重采样，更新重采样帧数
        if (isResamplingEnabled()) {
            stats_.resampledFrames++;
        }
        
        // 更新平均解码时间
        if (stats_.decodedFrames == 1) {
            stats_.avgDecodeTime = decodeTime;
        } else {
            stats_.avgDecodeTime = stats_.totalDecodeTime / stats_.decodedFrames;
        }
    } else {
        stats_.errorCount++;
    }
}

AudioDecoder::DecoderStats AudioDecoder::getStats() const {
    std::lock_guard<std::mutex> lock(statsMutex_);
    return stats_;
}

void AudioDecoder::resetStats() {
    std::lock_guard<std::mutex> lock(statsMutex_);
    stats_ = DecoderStats{};
}

std::string AudioDecoder::getDecoderName() const {
    return audioParams_.codecName;
}

bool AudioDecoder::isResamplingEnabled() const {
    return audioParams_.enableResampling && needResampling_;
}

std::vector<std::string> AudioDecoder::getSupportedDecoders() {
    std::call_once(decodersInitFlag_, findUsableDecoders);
    return supportedDecoders_;
}

bool AudioDecoder::isDecoderSupported(const std::string& codecName) {
    auto decoders = getSupportedDecoders();
    return std::find(decoders.begin(), decoders.end(), codecName) != decoders.end();
}

std::string AudioDecoder::getRecommendedDecoder(const std::string& codecName) {
    auto decoders = getSupportedDecoders();
    
    if (!codecName.empty()) {
        // 查找指定编解码格式的解码器
        if (std::find(decoders.begin(), decoders.end(), codecName) != decoders.end()) {
            return codecName;
        }
        
        // 查找相关的解码器
        for (const auto& decoder : decoders) {
            if (decoder.find(codecName) != std::string::npos) {
                return decoder;
            }
        }
    }
    
    // 返回默认推荐的解码器
    const char* preferredDecoders[] = {"aac", "mp3", "opus", "vorbis", "flac"};
    for (const char* preferred : preferredDecoders) {
        if (std::find(decoders.begin(), decoders.end(), preferred) != decoders.end()) {
            return preferred;
        }
    }
    
    return decoders.empty() ? "" : decoders[0];
}

void AudioDecoder::findUsableDecoders() {
    AV_LOGGER_INFO("查找可用的音频解码器...");
    
    // 测试所有音频解码器
    for (const char* decoder : AUDIO_DECODERS) {
        if (decoder && CodecFactory::isCodecSupported(decoder, CodecType::DECODER, MediaType::AUDIO)) {
            supportedDecoders_.emplace_back(decoder);
            AV_LOGGER_INFOF("找到音频解码器: {}", decoder);
        }
    }
    
    AV_LOGGER_INFOF("总共找到 {} 个可用的音频解码器", supportedDecoders_.size());
}

// AudioDecoderFactory 实现
std::unique_ptr<AudioDecoder> AudioDecoder::AudioDecoderFactory::create(const std::string& codecName) {
    auto decoder = std::make_unique<AudioDecoder>();
    
    if (!codecName.empty()) {
        if (!CodecFactory::isCodecSupported(codecName, CodecType::DECODER, MediaType::AUDIO)) {
            AV_LOGGER_ERRORF("不支持的音频解码器: {}", codecName);
            return nullptr;
        }
    }
    
    return decoder;
}

std::unique_ptr<AudioDecoder> AudioDecoder::AudioDecoderFactory::createBest() {
    std::string codecName = AudioDecoder::getRecommendedDecoder();
    
    if (codecName.empty()) {
        AV_LOGGER_ERROR("未找到可用的音频解码器");
        return nullptr;
    }
    
    return create(codecName);
}

} // namespace codec
} // namespace av