import os
import time
import tempfile
import streamlit as st
from config import PYGAME_AVAILABLE, MOVIEPY_AVAILABLE

if PYGAME_AVAILABLE:
    import pygame

if MOVIEPY_AVAILABLE:
    from moviepy import VideoFileClip

class AudioPlayer:
    """A class to handle audio extraction and playback for the video."""

    def __init__(self):
        self.is_playing = False
        self.audio_file = None
        self.start_time = None
        self.pygame_initialized = False

        if PYGAME_AVAILABLE:
            try:
                # Initialize pygame mixer with a specific frequency to avoid common issues
                pygame.mixer.pre_init(frequency=44100, size=-16, channels=2, buffer=512)
                pygame.mixer.init()
                self.pygame_initialized = True
            except Exception as e:
                st.warning(f"Audio mixer initialization failed: {e}")

    def extract_audio_from_video(self, video_path):
        """Extracts audio from a video file using MoviePy."""
        if not MOVIEPY_AVAILABLE or not self.pygame_initialized:
            return None

        try:
            temp_audio = tempfile.mktemp(suffix='.wav')
            video_clip = VideoFileClip(video_path)
            if video_clip.audio is not None:
                video_clip.audio.write_audiofile(temp_audio, logger=None)
                video_clip.close()
                return temp_audio
            else:
                video_clip.close()
                return None
        except Exception as e:
            st.warning(f"Could not extract audio: {e}")
            return None

    def load_audio(self, video_path):
        """Loads an audio file for playback."""
        if not self.pygame_initialized:
            return False

        try:
            audio_file = self.extract_audio_from_video(video_path)
            if audio_file and os.path.exists(audio_file):
                self.audio_file = audio_file
                return True
            return False
        except Exception as e:
            st.error(f"Failed to load audio: {e}")
            return False

    def play(self):
        """Plays the loaded audio file."""
        if not self.pygame_initialized or not self.audio_file or self.is_playing:
            return False
        try:
            pygame.mixer.music.load(self.audio_file)
            pygame.mixer.music.play()
            self.is_playing = True
            self.start_time = time.time()
            return True
        except Exception as e:
            st.warning(f"Audio playback failed: {e}")
            return False

    def stop(self):
        """Stops the audio playback."""
        if self.pygame_initialized and self.is_playing:
            try:
                pygame.mixer.music.stop()
                self.is_playing = False
                return True
            except Exception as e:
                return False
        return False

    def restart(self):
        """Restarts the audio from the beginning."""
        if self.pygame_initialized and self.audio_file:
            self.stop()
            return self.play()
        return False

    def cleanup(self):
        """Cleans up audio resources."""
        self.stop()
        if self.audio_file and os.path.exists(self.audio_file):
            try:
                os.unlink(self.audio_file)
                self.audio_file = None
            except Exception:
                pass
