using Android.Content.PM;
using Android.Media;
using AndroidX.Core.App;
using AndroidX.Core.Content;
using XiaoZhiSharp.Services;

namespace DuoDuo.Services
{
    public class AndroidAudioService : IDisposable, IAudioService
    {
        #region 常量定义
        // 音频参数
        private const int SampleRate = 24000;
        private const int SampleRate_WaveIn = 16000;
        private const int Bitrate = 16;
        private const int Channels = 1;
        private const int FrameDuration = 60;
        private const int FrameSize = SampleRate * FrameDuration / 1000; // 帧大小
        // 计算60ms的样本数
        private const int SamplesPerFrame = SampleRate_WaveIn * FrameDuration / 1000;
        // 16位音频每个样本2字节
        private const int BytesPerSample = Bitrate / 8;
        // 60ms帧的字节数
        private const int BytesPerFrame = SamplesPerFrame * BytesPerSample;

        private MediaPlayer? _mediaPlayer;
        private AudioRecord? _audioRecord;
        private AudioTrack? _audioTrack;
        private bool _isPlaying;
        private bool _isRecording;
        
        // VAD相关字段（从Unity版本移植）
        private bool useVAD = true;                // 是否使用VAD
        private float vadThreshold = 0.015f;       // VAD阈值，可根据环境噪音调整
        private int vadSilenceFrames = 20;         // 静音帧数阈值(约0.33秒)
        private int currentSilenceFrames = 0;      // 当前连续静音帧数
        private bool isSpeaking = false;           // 是否检测到说话
        private DateTime lastTtsEndTime = DateTime.Now; // 上次TTS结束的时间
        private float ttsCooldownTime = 0.5f;      // TTS结束后的冷却时间(秒)
        private bool isInCooldown = false;         // 是否处于冷却期
        private CancellationTokenSource? _recordingCts;
        #endregion

        #region 事件
        public event IAudioService.PcmAudioEventHandler? OnPcmAudioEvent;
        #endregion

        #region 属性
        public bool IsPlaying => _isPlaying;
        public bool IsRecording => _isRecording;
        public int VadCounter { get; private set; } = 0; // 用于语音活动检测的计数器
        #endregion

        public AndroidAudioService()
        {
            if (!HasAudioPermission())
            {
                RequestAudioPermission();
            }

            try
            {
                // 初始化音频播放组件
                _mediaPlayer = new MediaPlayer();
                // 计算最小缓冲区大小，并确保至少能容纳一帧数据
                int minBufferSize = AudioRecord.GetMinBufferSize(SampleRate_WaveIn, ChannelIn.Mono, Android.Media.Encoding.Pcm16bit);
                int bufferSize = Math.Max(minBufferSize, BytesPerFrame * 2); // 至少能容纳2帧数据

                // 初始化音频录制组件
                _audioRecord = new AudioRecord(AudioSource.Mic, SampleRate_WaveIn, ChannelIn.Mono, Android.Media.Encoding.Pcm16bit, bufferSize);
                // 检查 AudioRecord 是否初始化成功
                if (_audioRecord.State != State.Initialized)
                {
                    Console.WriteLine("AudioRecord 初始化失败");
                    _audioRecord = null;
                }

                // 初始化 AudioTrack
                int audioTrackBufferSize = AudioTrack.GetMinBufferSize(SampleRate, ChannelOut.Mono, Android.Media.Encoding.Pcm16bit);
                _audioTrack = new AudioTrack(Android.Media.Stream.Music, SampleRate, ChannelOut.Mono, Android.Media.Encoding.Pcm16bit, audioTrackBufferSize, AudioTrackMode.Stream);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"初始化音频组件时出错: {ex.Message}");
            }
        }
        private bool HasAudioPermission()
        {
            return ContextCompat.CheckSelfPermission(Android.App.Application.Context, Android.Manifest.Permission.RecordAudio) == Permission.Granted;
        }
        private async Task RequestAudioPermission()
        {
            ActivityCompat.RequestPermissions(Platform.CurrentActivity, new string[] { Android.Manifest.Permission.RecordAudio }, 1);
            await Task.Delay(1000); // 等待用户响应权限请求
        }
        public void StartRecording()
        {
            try
            {
                // 如果处于冷却期，不启动录音
                if (isInCooldown)
                {
                    Console.WriteLine("处于冷却期，暂不启动录音");
                    return;
                }
                
                // 如果已经在录音，先停止
                if (_isRecording)
                {
                    StopRecording();
                }
                
                // 确保 AudioRecord 已经正确初始化
                if (_audioRecord != null && _audioRecord.State == State.Initialized)
                {
                    Console.WriteLine("尝试开始录音");
                    _audioRecord.StartRecording();
                    _isRecording = true;
                    Console.WriteLine("开始录音");
                    VadCounter = 0; // 重置静音计数器
                    currentSilenceFrames = 0;
                    isSpeaking = false;
                    
                    _recordingCts = new CancellationTokenSource();
                    var token = _recordingCts.Token;

                    Task.Run(() =>
                    {
                        byte[] buffer = new byte[BytesPerFrame];
                        while (_isRecording && !token.IsCancellationRequested)
                        {
                            try
                            {
                                int bytesRead = _audioRecord.Read(buffer, 0, buffer.Length);
                                if (bytesRead > 0)
                                {
                                    // 发送音频数据
                                    if (OnPcmAudioEvent != null)
                                    {
                                        OnPcmAudioEvent(buffer);
                                    }

                                    // VAD检测
                                    if (useVAD)
                                    {
                                        bool hasVoice = DetectVoiceActivity(buffer, bytesRead);
                                        
                                        if (hasVoice)
                                    {
                                            currentSilenceFrames = 0;
                                            if (!isSpeaking)
                                            {
                                                // 检查是否在TTS结束后太快检测到声音（可能是回音）
                                                var timeSinceTts = (DateTime.Now - lastTtsEndTime).TotalSeconds;
                                                if (timeSinceTts < ttsCooldownTime * 2)
                                                {
                                                    Console.WriteLine($"VAD: TTS结束后{timeSinceTts:F2}秒内检测到声音，可能是回音，忽略");
                                                    continue;
                                                }
                                                
                                                isSpeaking = true;
                                                Console.WriteLine("VAD: 检测到语音开始");
                                            }
                                        }
                                        else
                                        {
                                            currentSilenceFrames++;
                                            
                                            // 如果之前在说话，且静音超过阈值，认为说话结束
                                            if (isSpeaking && currentSilenceFrames > vadSilenceFrames)
                                            {
                                                isSpeaking = false;
                                                VadCounter = currentSilenceFrames;
                                                Console.WriteLine($"VAD: 检测到语音结束，静音帧数: {currentSilenceFrames}");
                                            }
                                        }
                                    }
                                    else
                                    {
                                        // 使用原有的简单静音检测
                                        if (!IsAudioMute(buffer, bytesRead))
                                        {
                                            VadCounter = 0;
                                        }
                                        else
                                        {
                                            VadCounter++;
                                        }
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine($"录音时出错: {ex.Message}");
                            }
                        }
                    }, token);
                }
                else
                {
                    if (_audioRecord == null)
                    {
                        Console.WriteLine("AudioRecord 未初始化，可能是权限问题或资源冲突");
                        
                        // 尝试重新初始化AudioRecord
                        try
                        {
                            int minBufferSize = AudioRecord.GetMinBufferSize(SampleRate_WaveIn, ChannelIn.Mono, Android.Media.Encoding.Pcm16bit);
                            int bufferSize = Math.Max(minBufferSize, BytesPerFrame * 2); // 至少能容纳2帧数据
                            _audioRecord = new AudioRecord(AudioSource.Mic, SampleRate_WaveIn, ChannelIn.Mono, Android.Media.Encoding.Pcm16bit, bufferSize);
                            
                            if (_audioRecord.State == State.Initialized)
                            {
                                Console.WriteLine("成功重新初始化AudioRecord，重试录音");
                                StartRecording();
                            }
                            else
                            {
                                Console.WriteLine("重新初始化AudioRecord失败");
                            }
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine($"重新初始化AudioRecord出错: {ex.Message}");
                        }
                    }
                    else if (_audioRecord.State != State.Initialized)
                    {
                        Console.WriteLine($"AudioRecord 状态异常: {_audioRecord.State}");
                    }
                    else if (_isRecording)
                    {
                        Console.WriteLine("正在录音中，无法再次开始");
                    }
                    Console.WriteLine("无法开始录音，AudioRecord 未初始化或正在录音中");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"启动录音时出错: {ex.Message}");
                _isRecording = false;
            }
        }
        public void StopRecording()
        {
            try
            {
                if (_audioRecord != null && _isRecording)
                {
                    _audioRecord.Stop();
                    _isRecording = false;
                    VadCounter = 0;
                    currentSilenceFrames = 0;
                    isSpeaking = false;
                    
                    // 取消录音任务
                    _recordingCts?.Cancel();
                    _recordingCts?.Dispose();
                    _recordingCts = null;
                    
                    Console.WriteLine("结束录音");
                }
                else
                {
                    // 即使没有录音在进行，也重置状态
                    _isRecording = false;
                    VadCounter = 0;
                    currentSilenceFrames = 0;
                    isSpeaking = false;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"停止录音时出错: {ex.Message}");
                // 确保状态重置，即使发生异常
                _isRecording = false;
                VadCounter = 0;
                currentSilenceFrames = 0;
                isSpeaking = false;
            }
        }
        private bool IsAudioMute(byte[] buffer, int bytesRecorded)
        {
            double rms = 0;
            int sampleCount = bytesRecorded / 2; // 每个样本 2 字节

            for (int i = 0; i < sampleCount; i++)
            {
                short sample = BitConverter.ToInt16(buffer, i * 2);
                rms += sample * sample;
            }

            rms = Math.Sqrt(rms / sampleCount);
            rms /= short.MaxValue; // 归一化到 0 - 1 范围

            double MuteThreshold = 0.01; // 静音阈值
            return rms < MuteThreshold;
        }
        
        // 添加VAD检测方法（从Unity版本移植）
        private bool DetectVoiceActivity(byte[] buffer, int bytesRecorded)
        {
            // 计算音频能量
            double energy = 0;
            int sampleCount = bytesRecorded / 2; // 16位音频，每个样本2字节
            
            for (int i = 0; i < sampleCount; i++)
            {
                short sample = BitConverter.ToInt16(buffer, i * 2);
                float normalizedSample = sample / (float)short.MaxValue;
                energy += normalizedSample * normalizedSample;
            }
            
            energy /= sampleCount;
            
            // 在TTS播放结束后的一段时间内，提高VAD阈值，减少误触发
            float currentThreshold = vadThreshold;
            var timeSinceTts = (DateTime.Now - lastTtsEndTime).TotalSeconds;
            
            if (timeSinceTts < ttsCooldownTime * 2)
            {
                // 在冷却期后的一段时间内，使用更高的阈值
                currentThreshold = vadThreshold * 1.5f;
                
                // 如果能量值接近阈值但未超过，记录日志但不触发
                if (energy > vadThreshold && energy <= currentThreshold)
                {
                    Console.WriteLine($"VAD: 冷却期内检测到低能量声音，能量值: {energy:F5}，当前阈值: {currentThreshold:F5}");
                }
            }
            
            // 判断能量是否超过阈值
            bool hasVoice = energy > currentThreshold;
            
            // 调试信息
            if (hasVoice)
            {
                Console.WriteLine($"VAD: 检测到声音，能量值: {energy:F5}，当前阈值: {currentThreshold:F5}");
            }
            
            return hasVoice;
        }
        public void StartPlaying()
        {
            try
            {
                if (!_isPlaying && _audioTrack != null)
                {
                    _audioTrack.Play();
                    _isPlaying = true;
                    
                    // 播放开始时，停止录音以避免回音
                    if (_isRecording)
                    {
                        StopRecording();
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"启动播放时出错: {ex.Message}");
            }
        }
        
        public void StopPlaying()
        {
            try
            {
                if (_isPlaying && _audioTrack != null)
                {
                    _audioTrack.Stop();
                    _isPlaying = false;
                    
                    // 记录TTS结束时间，开始冷却期
                    lastTtsEndTime = DateTime.Now;
                    isInCooldown = true;
                    Console.WriteLine($"TTS播放结束，进入冷却期 {ttsCooldownTime} 秒");
                    
                    // 启动冷却期计时器
                    Task.Run(async () =>
                    {
                        await Task.Delay((int)(ttsCooldownTime * 1000));
                        isInCooldown = false;
                        Console.WriteLine("冷却期结束，可以开始新一轮录音");
                    });
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"停止播放时出错: {ex.Message}");
            }
        }
        public void AddOutSamples(byte[] pcmData)
        {
            try
            {
                if (_audioTrack != null)
                {
                    if (!_isPlaying)
                    {
                        StartPlaying();
                    }
                    _audioTrack.Write(pcmData, 0, pcmData.Length);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"添加样本数据时出错: {ex.Message}");
            }
        }
        public void AddOutSamples(float[] pcmData)
        {
            throw new NotImplementedException("不支持 float 类型的 PCM 数据");
        }
        // 添加VAD配置方法
        public void ConfigureVAD(bool enabled, float threshold, int silenceFrames, float cooldownTime)
        {
            useVAD = enabled;
            vadThreshold = threshold;
            vadSilenceFrames = silenceFrames;
            ttsCooldownTime = cooldownTime;
            
            // 重置VAD状态
            currentSilenceFrames = 0;
            isSpeaking = false;
            isInCooldown = false;
            lastTtsEndTime = DateTime.Now.AddSeconds(-10); // 设置为很久以前，确保不在冷却期
            VadCounter = 0;
            
            Console.WriteLine($"VAD配置更新: 启用={enabled}, 阈值={threshold}, 静音帧数={silenceFrames}, 冷却时间={cooldownTime}秒");
            Console.WriteLine("VAD状态已重置");
        }
        
        /// <summary>
        /// 重置TTS状态，用于断线重连恢复
        /// </summary>
        public void ResetTtsState()
        {
            isInCooldown = false;
            lastTtsEndTime = DateTime.Now.AddSeconds(-10);
            Console.WriteLine("TTS状态已重置");
        }
        
        // 获取当前VAD状态
        public bool IsSpeaking => isSpeaking;
        public bool IsInCooldown => isInCooldown;
        public int CurrentSilenceFrames => currentSilenceFrames;
        
        public void Dispose()
        {
            try
            {
                _isPlaying = false;
                _isRecording = false;
                _recordingCts?.Cancel();
                _recordingCts?.Dispose();
                _audioRecord?.Release();
                _audioRecord = null;
                _mediaPlayer?.Release();
                _mediaPlayer = null;
                _audioTrack?.Release();
                _audioTrack = null;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"释放资源时出错: {ex.Message}");
            }
        }
    }
}