#include "audio_recorder.h"

#include "capturer/audio/audio_qt_capturer.h"
#include "capturer/audio/wasapi_loopback_capturer.h"
#include "qdebug.h"
#include <algorithm>
#include <mutex>

AudioRecorder::AudioRecorder() {}

AudioRecorder::~AudioRecorder()
{
    Close();
}

bool AudioRecorder::Open(const std::vector<AudioCapturer::Type>& deviceTypes,
                         Encoder<MediaType::AUDIO>::Param& param,
                         const uint32_t sampleRate,
                         const uint32_t channels,
                         const uint32_t bitsPerSample,
                         const AVSampleFormat format)
{
    qDebug() << "AudioRecorder::Open called, deviceTypes size:" << deviceTypes.size();
    Close();
    Info mixInfo;
    mixInfo.mixer = &_mixer;
    mixInfo.isRecord = &_isRecord;
    mixInfo.streamIndex = &_streamIndex;

    // 清空并重新创建音频捕获器
    m_audioCapturers.clear();
    for (int index = 0; index < deviceTypes.size(); ++index) {
        mixInfo.mixIndex = index;
        _infos.push_back(mixInfo);
        if (deviceTypes[index] == AudioCapturer::Type::Speaker) {
            m_audioCapturers.push_back(new WASAPILoopbackCapturer());
        } else {
            m_audioCapturers.push_back(new WASAPILoopbackCapturer());
        }
    }

    // 初始化每个音频捕获器
    for (int index = 0; index < deviceTypes.size(); ++index) {
        if (!m_audioCapturers[index]->Init(deviceTypes[index])) {
            qDebug() << "Failed to initialize audio capturer" << index;
            return false;
        }
        
        // 添加音频格式验证
        const AudioFormat& format = m_audioCapturers[index]->GetFormat();
        qDebug() << "Audio Capturer" << index << "Format:" << "SampleRate:" << format.sampleRate
                 << "Channels:" << format.channels << "BitsPerSample:" << format.bitsPerSample
                 << "BlockAlign:" << format.blockAlign
                 << "AvgBytesPerSec:" << format.avgBytesPerSec;

        // 验证格式是否与预期一致
        if (format.sampleRate != sampleRate) {
            qDebug() << "Warning: Sample rate mismatch. Expected:" << sampleRate
                     << "Got:" << format.sampleRate;
        }
        if (format.channels != channels) {
            qDebug() << "Warning: Channel count mismatch. Expected:" << channels
                     << "Got:" << format.channels;
        }
        
        if (!_mixer.AddAudioInput(index,
                                          format.sampleRate,
                                          format.channels,
                                          format.bitsPerSample,
                                          _GetAVSampleFormat(format.bitsPerSample))) {
            qDebug() << "AddAudioInput failed for index" << index;
            return false;
        }
    }

    if (!_mixer.AddAudioOutput(sampleRate, channels, bitsPerSample, format)) {
        qDebug() << "AddAudioOutput failed";
        return false;
    }
    _param = param;
    if (!_mixer.SetOutFrameSize(1024)) {
        qDebug() << "SetOutFrameSize failed";
        return false;
    }

    // 启动所有成功初始化的音频捕获器
    for (auto capturer : m_audioCapturers) {
        capturer->Start();
    }
    return true;
}

void AudioRecorder::Close()
{
    StopRecord();

    // 停止并释放所有音频捕获器
    for (auto capturer : m_audioCapturers) {
        if (capturer) {
            capturer->Stop();
            delete capturer;
        }
    }
    m_audioCapturers.clear();

    _mixer.Close();
    _infos.clear();
}

void AudioRecorder::SetVolumeScale(float scale, int mixIndex)
{
    auto info = _mixer.GetInputInfo(mixIndex);
    if (info != nullptr) {
        info->scale = scale;
    }
}

bool AudioRecorder::LoadMuxer(AvMuxer& muxer)
{
    std::lock_guard<std::mutex> lock(_muxersMtx);
    
    // 检查是否已经加载过这个muxer
    for (const auto& info : _muxers) {
        if (info.muxer == &muxer) {
            return true; // 已经加载过，直接返回成功
        }
    }
    
    int streamIndex = muxer.AddAudioStream(_param);
    if (streamIndex == -1) {
        qDebug() << "AddAudioStream failed";
        return false;
    }
    
    _muxers.emplace_back(&muxer, streamIndex);
    
    // 为了兼容性，保留原有的_infos逻辑（如果需要的话）
    for (auto&& info : _infos) {
        if (info.muxer == nullptr) {
            info.muxer = &muxer;
            break;
        }
    }
    
    return true;
}

bool AudioRecorder::UnloadMuxer(AvMuxer& muxer)
{
    std::lock_guard<std::mutex> lock(_muxersMtx);
    
    auto it = std::find_if(_muxers.begin(), _muxers.end(),
                          [&muxer](const MuxerInfo& info) {
                              return info.muxer == &muxer;
                          });
    
    if (it != _muxers.end()) {
        _muxers.erase(it);
        
        // 清理_infos中对应的muxer引用
        for (auto&& info : _infos) {
            if (info.muxer == &muxer) {
                info.muxer = nullptr;
            }
        }
        
        return true;
    }
    
    return false; // 没有找到对应的muxer
}

bool AudioRecorder::StartRecord()
{
    _isRecord = true;
    m_audioTimer.Start(AUDIO_PULL_INTERVAL_MS, [this] {
        this->PullAndProcessAudio();
    });
    return true;
}

void AudioRecorder::StopRecord()
{
    _isRecord = false;
    m_audioTimer.Stop();
}

// 新增：主动拉取音频数据的接口
void AudioRecorder::PullAndProcessAudio()
{
    for (int index = 0; index < m_audioCapturers.size(); ++index) {
        // 每次多次拉取小块数据，提升音频帧写入频率
        while (true) {
            char buf[1024];
            int bytes = m_audioCapturers[index]->readAudioData(buf, sizeof(buf));
            // static int debugCounter = 0;
            // if (++debugCounter % 100 == 0) { // 每100次打印一次，避免日志过多
            //     qDebug() << "Capturer" << index << "read" << bytes << "bytes";
            // }
            if (bytes <= 0) {
                break;
            }

            // 添加调试信息，显示数据大小

            auto frame = _mixer.Convert(index, (uint8_t*) buf, bytes);
            if (frame && _isRecord) {
                int frameSize = _mixer.GetOutFrameSize();
                if (_mixer.GetOutFrameSize() != frameSize) {
                    _mixer.SetOutFrameSize(frameSize);
                    continue;
                }
                
                // 向所有已加载的muxer写入音频数据
                {
                    std::lock_guard<std::mutex> muxerLock(_muxersMtx);
                    for (const auto& muxerInfo : _muxers) {
                        muxerInfo.muxer->Write(frame, muxerInfo.streamIndex);
                    }
                }
            }
        }
    }
}

std::string AudioRecorder::GetEncoderNameForMuxer(AvMuxer& muxer)
{
    std::lock_guard<std::mutex> lock(_muxersMtx);
    auto it = std::find_if(_muxers.begin(), _muxers.end(), [&](const MuxerInfo& info){
        return info.muxer == &muxer;
    });
    if (it == _muxers.end()) return {};
    AVCodecContext* ctx = muxer.GetCodecCtx(it->streamIndex);
    if (!ctx || !ctx->codec || !ctx->codec->name) return {};
    return std::string(ctx->codec->name);
}
