"""Audio processing utilities using FFmpeg."""
import ffmpeg
import subprocess
from pathlib import Path
from typing import Optional
import sys

sys.path.insert(0, str(Path(__file__).parent.parent.parent))

from shared.logging_config import setup_logging

logger = setup_logging("audio.processing")


class AudioProcessor:
    """Audio processing using FFmpeg."""
    
    @staticmethod
    def normalize_audio(
        input_file: str,
        output_file: str,
        target_lufs: float = -14.0
    ) -> str:
        """Normalize audio to target LUFS level.
        
        Args:
            input_file: Input audio file path
            output_file: Output audio file path
            target_lufs: Target LUFS level
            
        Returns:
            Path to processed file
        """
        logger.info(f"Normalizing audio: {input_file} to {target_lufs} LUFS")
        
        try:
            # First pass: measure loudness
            probe = ffmpeg.probe(input_file)
            loudness_info = subprocess.run(
                [
                    'ffmpeg', '-i', input_file,
                    '-af', f'loudnorm=I={target_lufs}:print_format=json',
                    '-f', 'null', '-'
                ],
                capture_output=True,
                text=True
            )
            
            # Second pass: apply normalization
            stream = ffmpeg.input(input_file)
            stream = ffmpeg.filter(stream, 'loudnorm', I=target_lufs, TP=-1.5, LRA=11)
            stream = ffmpeg.output(stream, output_file, audio_bitrate='320k')
            ffmpeg.run(stream, overwrite_output=True, quiet=True)
            
            logger.info(f"Audio normalized successfully: {output_file}")
            return output_file
            
        except Exception as e:
            logger.error(f"Normalization failed: {e}")
            raise
    
    @staticmethod
    def convert_format(
        input_file: str,
        output_file: str,
        format: str = "mp3",
        bitrate: str = "320k"
    ) -> str:
        """Convert audio to different format.
        
        Args:
            input_file: Input audio file path
            output_file: Output audio file path
            format: Target format (mp3, aac, wav)
            bitrate: Audio bitrate
            
        Returns:
            Path to converted file
        """
        logger.info(f"Converting {input_file} to {format}")
        
        try:
            stream = ffmpeg.input(input_file)
            stream = ffmpeg.output(stream, output_file, audio_bitrate=bitrate, format=format)
            ffmpeg.run(stream, overwrite_output=True, quiet=True)
            
            logger.info(f"Conversion successful: {output_file}")
            return output_file
            
        except Exception as e:
            logger.error(f"Conversion failed: {e}")
            raise
    
    @staticmethod
    def trim_audio(
        input_file: str,
        output_file: str,
        start_time: float = 0,
        duration: Optional[float] = None
    ) -> str:
        """Trim audio to specific duration.
        
        Args:
            input_file: Input audio file path
            output_file: Output audio file path
            start_time: Start time in seconds
            duration: Duration in seconds (None = to end)
            
        Returns:
            Path to trimmed file
        """
        logger.info(f"Trimming audio from {start_time}s, duration={duration}s")
        
        try:
            stream = ffmpeg.input(input_file, ss=start_time)
            if duration:
                stream = stream.filter('atrim', duration=duration)
            stream = ffmpeg.output(stream, output_file)
            ffmpeg.run(stream, overwrite_output=True, quiet=True)
            
            logger.info(f"Trimming successful: {output_file}")
            return output_file
            
        except Exception as e:
            logger.error(f"Trimming failed: {e}")
            raise
    
    @staticmethod
    def analyze_audio(input_file: str) -> dict:
        """Analyze audio file for metadata.
        
        Args:
            input_file: Audio file path
            
        Returns:
            Dictionary with audio metadata
        """
        logger.info(f"Analyzing audio: {input_file}")
        
        try:
            probe = ffmpeg.probe(input_file)
            audio_stream = next((s for s in probe['streams'] if s['codec_type'] == 'audio'), None)
            
            if not audio_stream:
                raise ValueError("No audio stream found")
            
            metadata = {
                'duration': float(probe['format'].get('duration', 0)),
                'bit_rate': int(probe['format'].get('bit_rate', 0)),
                'sample_rate': int(audio_stream.get('sample_rate', 0)),
                'channels': int(audio_stream.get('channels', 0)),
                'codec': audio_stream.get('codec_name'),
                'file_size': int(probe['format'].get('size', 0))
            }
            
            logger.info(f"Analysis complete: {metadata}")
            return metadata
            
        except Exception as e:
            logger.error(f"Analysis failed: {e}")
            raise
