"""Audio tools — convert, trim, merge, normalize, and more.

Audio tools return base64-encoded audio data.
"""

from __future__ import annotations

import base64
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from mcp.server.fastmcp import FastMCP


def _b64(data: bytes) -> str:
    return base64.b64encode(data).decode("ascii")


def _raw(b64: str) -> bytes:
    return base64.b64decode(b64)


def register(mcp: FastMCP) -> None:
    from peasy_audio import engine

    @mcp.tool()
    def audio_info(file_path: str) -> dict[str, object]:
        """Get audio file information.

        file_path: Path to audio file.
        Returns: Dict with duration_ms, channels, frame_rate, size_bytes.
        """
        r = engine.info(file_path)
        return {
            "duration_ms": r.duration_ms,
            "duration_seconds": r.duration_seconds,
            "channels": r.channels,
            "frame_rate": r.frame_rate,
            "size_bytes": r.size_bytes,
        }

    @mcp.tool()
    def audio_convert(
        file_path: str, target_format: str = "mp3", bitrate: str = "192k"
    ) -> dict[str, object]:
        """Convert audio to a different format.

        file_path: Path to input audio.
        target_format: Target format (mp3, wav, ogg, flac, aac).
        bitrate: Output bitrate.
        Returns: Dict with base64 data, format, duration_ms, size_bytes.
        """
        r = engine.convert(file_path, target_format=target_format, bitrate=bitrate)  # type: ignore[arg-type]
        return {
            "data_b64": _b64(r.data),
            "format": r.format,
            "duration_ms": r.duration_ms,
            "size_bytes": r.size_bytes,
        }

    @mcp.tool()
    def audio_trim(file_path: str, start_ms: int = 0, end_ms: int = 0) -> dict[str, object]:
        """Trim audio to a time range.

        start_ms: Start time in milliseconds.
        end_ms: End time in milliseconds (0 = end of file).
        Returns: Dict with base64 data, format, duration_ms, size_bytes.
        """
        r = engine.trim(file_path, start_ms=start_ms, end_ms=end_ms)
        return {
            "data_b64": _b64(r.data),
            "format": r.format,
            "duration_ms": r.duration_ms,
            "size_bytes": r.size_bytes,
        }

    @mcp.tool()
    def audio_merge(file_paths: list[str], output_format: str = "mp3") -> dict[str, object]:
        """Merge multiple audio files into one.

        file_paths: List of paths to audio files.
        output_format: Output format.
        Returns: Dict with base64 data, format, duration_ms, size_bytes.
        """
        r = engine.merge(*file_paths, output_format=output_format)
        return {
            "data_b64": _b64(r.data),
            "format": r.format,
            "duration_ms": r.duration_ms,
            "size_bytes": r.size_bytes,
        }

    @mcp.tool()
    def audio_normalize(file_path: str) -> dict[str, object]:
        """Normalize audio volume to a standard level.

        Returns: Dict with base64 data, format, duration_ms, size_bytes.
        """
        r = engine.normalize(file_path)
        return {
            "data_b64": _b64(r.data),
            "format": r.format,
            "duration_ms": r.duration_ms,
            "size_bytes": r.size_bytes,
        }

    @mcp.tool()
    def audio_speed(file_path: str, factor: float = 1.5) -> dict[str, object]:
        """Change audio playback speed.

        factor: Speed multiplier (0.5 = half speed, 2.0 = double speed).
        Returns: Dict with base64 data, format, duration_ms, size_bytes.
        """
        r = engine.speed(file_path, factor=factor)
        return {
            "data_b64": _b64(r.data),
            "format": r.format,
            "duration_ms": r.duration_ms,
            "size_bytes": r.size_bytes,
        }

    @mcp.tool()
    def audio_reverse(file_path: str) -> dict[str, object]:
        """Reverse audio playback.

        Returns: Dict with base64 data, format, duration_ms, size_bytes.
        """
        r = engine.reverse_audio(file_path)
        return {
            "data_b64": _b64(r.data),
            "format": r.format,
            "duration_ms": r.duration_ms,
            "size_bytes": r.size_bytes,
        }

    @mcp.tool()
    def audio_volume(file_path: str, db: float = 3.0) -> dict[str, object]:
        """Change audio volume.

        db: Volume change in decibels (positive = louder, negative = quieter).
        Returns: Dict with base64 data, format, duration_ms, size_bytes.
        """
        r = engine.change_volume(file_path, db=db)
        return {
            "data_b64": _b64(r.data),
            "format": r.format,
            "duration_ms": r.duration_ms,
            "size_bytes": r.size_bytes,
        }
