use crate::constants::common::*;
use lazy_static::lazy_static;
use rodio::{Decoder, DeviceSinkBuilder, MixerDeviceSink, Player, Source};
use std::fs::File;
use std::io::{Cursor, Read};
use std::path::PathBuf;
use std::sync::Arc;
use std::sync::mpsc;
use std::thread;

// 导出commands子模块
pub mod commands;

#[derive(Debug)]
enum AudioCommand {
    /// ⚡ 使用 Arc 共享音频数据，避免克隆
    PlayPromptTone(Arc<Vec<u8>>),
    Stop,
}

// 预加载的提示音数据 - 使用 Arc 避免克隆
lazy_static! {
    static ref PROMPT_TONE_DATA: Arc<Vec<u8>> = {
        // 读取提示音文件
        let resource_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
            .join(AUDIO_PROMPT_FILE_PATH);
        Arc::new(
            File::open(&resource_path)
                .ok()
                .and_then(|mut file| {
                    let mut data = Vec::new();
                    file.read_to_end(&mut data).ok().map(|_| data)
                })
                .unwrap_or_else(|| {
                    log::error!("无法读取提示音文件 {:?}", resource_path);
                    Vec::new()
                })
        )
    };

    static ref AUDIO_SYSTEM: AudioSystem = AudioSystem::new();
}

struct AudioResources {
    stream: MixerDeviceSink,
}

impl AudioResources {
    fn new() -> Result<Self, Box<dyn std::error::Error>> {
        // 使用 rodio 0.22 API - DeviceSinkBuilder::open_default_sink()
        let stream = DeviceSinkBuilder::open_default_sink()?;

        Ok(Self { stream })
    }
}

struct AudioSystem {
    tx: mpsc::Sender<AudioCommand>,
}

impl AudioSystem {
    fn new() -> Self {
        let (tx, rx) = mpsc::channel();
        thread::spawn(move || Self::audio_worker(rx));
        Self { tx }
    }

    fn audio_worker(rx: mpsc::Receiver<AudioCommand>) {
        let audio_resources = match AudioResources::new() {
            Ok(resources) => resources,
            Err(e) => {
                log::error!("音频系统初始化失败: {}", e);
                return;
            }
        };

        // 通过 mixer 创建 Player - rodio 0.22 API
        let sink = Player::connect_new(audio_resources.stream.mixer());

        while let Ok(cmd) = rx.recv() {
            match cmd {
                AudioCommand::PlayPromptTone(data) => {
                    // 检查音频数据是否为空
                    if data.is_empty() {
                        log::warn!("提示音数据为空");
                        continue;
                    }

                    // 停止当前播放并清空队列
                    sink.stop();
                    sink.clear();

                    // ⚡ 在 worker 线程中克隆数据（只在播放时克隆一次，避免在主线程克隆）
                    let data_vec = (*data).clone();

                    // 解码音频数据
                    match Decoder::new(Cursor::new(data_vec)) {
                        Ok(source) => {
                            // 设置音量并播放
                            let source = source.amplify(AUDIO_VOLUME_AMPLIFICATION);
                            sink.append(source);
                            sink.play();
                        }
                        Err(e) => {
                            log::error!("音频解码失败: {:?}", e);
                        }
                    }
                }
                AudioCommand::Stop => {
                    sink.stop();
                }
            }
        }

        // 线程结束时确保停止播放
        sink.stop();
    }

    fn play_prompt_tone(&self) {
        // ⚡ 直接克隆 Arc 指针，不再拷贝音频数据
        let _ = self.tx.send(AudioCommand::PlayPromptTone(PROMPT_TONE_DATA.clone()));
    }

    #[allow(dead_code)] // 允许未使用的方法，保留以备将来使用
    fn stop(&self) {
        let _ = self.tx.send(AudioCommand::Stop);
    }
}

/// 播放提示音
pub fn play_prompt_tone_imp() {
    AUDIO_SYSTEM.play_prompt_tone();
}

/// 停止音频播放
pub fn stop_prompt_tone_imp() {
    AUDIO_SYSTEM.stop();
}
