//! Volume monitoring and control module
//!
//! Provides volume status and control via shepherdd.
//! The service handles actual volume control and enforces restrictions.

use shepherd_api::{Command, ResponsePayload, VolumeInfo};
use shepherd_ipc::IpcClient;
use shepherd_util::default_socket_path;
use tokio::runtime::Runtime;

/// Get current volume status from shepherdd
pub fn get_volume_status() -> Option<VolumeInfo> {
    let socket_path = default_socket_path();

    let rt = match Runtime::new() {
        Ok(rt) => rt,
        Err(e) => {
            tracing::error!("Failed to create runtime: {}", e);
            return None;
        }
    };

    rt.block_on(async {
        match IpcClient::connect(&socket_path).await {
            Ok(mut client) => match client.send(Command::GetVolume).await {
                Ok(response) => {
                    if let shepherd_api::ResponseResult::Ok(ResponsePayload::Volume(info)) =
                        response.result
                    {
                        Some(info)
                    } else {
                        None
                    }
                }
                Err(e) => {
                    tracing::error!("Failed to get volume: {}", e);
                    None
                }
            },
            Err(e) => {
                tracing::debug!("Failed to connect to shepherdd for volume: {}", e);
                None
            }
        }
    })
}

/// Toggle mute state via shepherdd
pub fn toggle_mute() -> anyhow::Result<()> {
    let socket_path = default_socket_path();

    let rt = Runtime::new()?;

    rt.block_on(async {
        let mut client = IpcClient::connect(&socket_path).await?;
        let response = client.send(Command::ToggleMute).await?;

        match response.result {
            shepherd_api::ResponseResult::Ok(ResponsePayload::VolumeSet) => Ok(()),
            shepherd_api::ResponseResult::Ok(ResponsePayload::VolumeDenied { reason }) => {
                Err(anyhow::anyhow!("Volume denied: {}", reason))
            }
            shepherd_api::ResponseResult::Err(e) => Err(anyhow::anyhow!("Error: {}", e.message)),
            _ => Err(anyhow::anyhow!("Unexpected response")),
        }
    })
}

/// Set volume to a specific percentage via shepherdd
pub fn set_volume(percent: u8) -> anyhow::Result<()> {
    let socket_path = default_socket_path();

    let rt = Runtime::new()?;

    rt.block_on(async {
        let mut client = IpcClient::connect(&socket_path).await?;
        let response = client.send(Command::SetVolume { percent }).await?;

        match response.result {
            shepherd_api::ResponseResult::Ok(ResponsePayload::VolumeSet) => Ok(()),
            shepherd_api::ResponseResult::Ok(ResponsePayload::VolumeDenied { reason }) => {
                Err(anyhow::anyhow!("Volume denied: {}", reason))
            }
            shepherd_api::ResponseResult::Err(e) => Err(anyhow::anyhow!("Error: {}", e.message)),
            _ => Err(anyhow::anyhow!("Unexpected response")),
        }
    })
}

#[cfg(test)]
mod tests {
    use shepherd_api::VolumeRestrictions;

    #[test]
    fn test_volume_icon_names() {
        // Test that VolumeInfo::icon_name works correctly
        let info = shepherd_api::VolumeInfo {
            percent: 0,
            muted: false,
            available: true,
            backend: Some("test".into()),
            restrictions: VolumeRestrictions::unrestricted(),
        };
        assert_eq!(info.icon_name(), "audio-volume-muted-symbolic");

        let info = shepherd_api::VolumeInfo {
            percent: 50,
            muted: false,
            available: true,
            backend: Some("test".into()),
            restrictions: VolumeRestrictions::unrestricted(),
        };
        assert_eq!(info.icon_name(), "audio-volume-medium-symbolic");

        let info = shepherd_api::VolumeInfo {
            percent: 100,
            muted: true,
            available: true,
            backend: Some("test".into()),
            restrictions: VolumeRestrictions::unrestricted(),
        };
        assert_eq!(info.icon_name(), "audio-volume-muted-symbolic");
    }
}
