"""
FFmpeg audio operations.

This module provides implementation for audio-related operations.
"""

import os
from typing import Dict, Any, Union
from pathlib import Path
import logging

logger = logging.getLogger(__name__)

class FFmpegAudio:
    """FFmpeg audio operations implementation."""

    def mute(self, video: Dict[str, Any]) -> Dict[str, Any]:
        """
        Remove audio track from video.

        Args:
            video: Video dictionary

        Returns:
            New video dictionary
        """
        self._ensure_temp_dir()
        temp_file = os.path.join(self._temp_dir, f"mute_{os.path.basename(video['path'])}")

        args = ["-i", video["path"]]
        if video.get("start", 0) > 0:
            args = ["-ss", str(video["start"])] + args
        if video.get("end") is not None:
            duration = video["end"] - video.get("start", 0)
            args += ["-t", str(duration)]

        args += [
            "-c:v", "copy",
            "-an",
            "-y",
            temp_file
        ]

        self._run_ffmpeg(args)
        info = self._run_ffprobe(["-i", temp_file])

        return {
            "path": temp_file,
            "info": info,
            "is_temp": True,
            "start": 0,
            "end": None
        }

    def volume(self, video: Dict[str, Any], level: float) -> Dict[str, Any]:
        """
        Set audio volume level.

        Args:
            video: Video dictionary
            level: Volume level (1.0 = original, 0.5 = 50%, 2.0 = 200%)

        Returns:
            New video dictionary
        """
        self._ensure_temp_dir()
        temp_file = os.path.join(self._temp_dir, f"volume_{level}_{os.path.basename(video['path'])}")

        # Use volume filter - volume in dB = 20 * log10(level)
        volume_filter = f"volume={level}"

        args = ["-i", video["path"]]
        if video.get("start", 0) > 0:
            args = ["-ss", str(video["start"])] + args
        if video.get("end") is not None:
            duration = video["end"] - video.get("start", 0)
            args += ["-t", str(duration)]

        args += [
            "-af", volume_filter,
            "-c:v", "copy",
            "-y",
            temp_file
        ]

        self._run_ffmpeg(args)
        info = self._run_ffprobe(["-i", temp_file])

        return {
            "path": temp_file,
            "info": info,
            "is_temp": True,
            "start": 0,
            "end": None
        }

    def add_audio(self, video: Dict[str, Any], audio_path: Union[str, Path],
                  start: float = 0, volume: float = 1.0) -> Dict[str, Any]:
        """
        Add audio track to video.

        Args:
            video: Video dictionary
            audio_path: Path to audio file
            start: Start time for the audio (seconds)
            volume: Volume level (1.0 = original)

        Returns:
            New video dictionary
        """
        self._ensure_temp_dir()
        temp_file = os.path.join(self._temp_dir, f"add_audio_{os.path.basename(video['path'])}")

        # Build filter complex for mixing audio
        # If video has audio, mix with new audio; otherwise just add new audio
        args = ["-i", video["path"], "-i", str(audio_path)]

        if video.get("start", 0) > 0:
            args = ["-ss", str(video["start"])] + args
        if video.get("end") is not None:
            duration = video["end"] - video.get("start", 0)
            args += ["-t", str(duration)]

        # Check if original video has audio
        has_audio = video.get("info", {}).get("has_audio", False)

        if has_audio:
            # Mix both audio tracks
            args += [
                "-filter_complex", f"[1:a]volume={volume}[a1];[0:a][a1]amix=inputs=2:duration=first",
                "-c:v", "copy",
                "-y",
                temp_file
            ]
        else:
            # Just add the new audio
            if volume != 1.0:
                args += [
                    "-af", f"volume={volume}",
                ]
            args += [
                "-map", "0:v",
                "-map", "1:a",
                "-c:v", "copy",
                "-y",
                temp_file
            ]

        self._run_ffmpeg(args)
        info = self._run_ffprobe(["-i", temp_file])

        return {
            "path": temp_file,
            "info": info,
            "is_temp": True,
            "start": 0,
            "end": None
        }
