from PySide6.QtCore import QFile, QBuffer, QByteArray, QIODevice
from PySide6.QtMultimedia import QMediaPlayer, QAudioOutput

from config.config_manager import ConfigManager, VOLUME_KEY

from config.constants import Resources

class AudioController:
    # Encapsule toute la logique audio : lecture, volume, mute.

    def __init__(self, config: ConfigManager, slider, mute_btn):
        self._config   = config
        self._slider   = slider
        self._mute_btn = mute_btn

        # Lecteur
        self._player = QMediaPlayer()
        self._output = QAudioOutput()
        self._player.setAudioOutput(self._output)
        self._player.setLoops(-1)

        # Chargement du MP3 depuis les ressources Qt
        mp3file = QFile(Resources.MP3.value)
        mp3file.open(QFile.ReadOnly)
        mp3data = mp3file.readAll()
        mp3file.close()

        # Mise en buffer du MP3
        self._buffer = QBuffer()
        self._buffer.setData(QByteArray(mp3data))
        self._buffer.open(QIODevice.ReadOnly)
        self._player.setSourceDevice(self._buffer)

        # État initial du lecteur
        volume = config.get_volume()
        self._is_muted        = volume == 0
        self._previous_volume = volume if volume != 0 else config.get_default(VOLUME_KEY)

        self._apply_volume(volume, save=False)
        self._refresh_mute_btn()
        self._player.play()

        # Connexions
        self._slider.valueChanged.connect(self._on_slider_changed)
        self._mute_btn.clicked.connect(self.toggle_mute)

    # ------------------------------------------------------------------
    # Public API
    # ------------------------------------------------------------------

    def toggle_mute(self) -> None:
        if not self._is_muted:
            self._previous_volume = self._slider.value()
            self._apply_volume(0)
            self._is_muted = True
        else:
            self._apply_volume(self._previous_volume)
            self._is_muted = False

    # ------------------------------------------------------------------
    # Private helpers
    # ------------------------------------------------------------------

    def _on_slider_changed(self, value: int) -> None:
        self._is_muted = value == 0
        self._output.setVolume(value / 100.0)
        self._config.set_volume(value)
        self._refresh_mute_btn()

    def _apply_volume(self, value: int, save: bool = True) -> None:
        self._slider.blockSignals(True)
        self._slider.setValue(value)
        self._slider.blockSignals(False)

        self._output.setVolume(value / 100.0)

        if save:
            self._config.set_volume(value)

        self._refresh_mute_btn()

    def _refresh_mute_btn(self) -> None:
        muted = self._slider.value() == 0
        self._mute_btn.setProperty("muted", muted)
        self._mute_btn.style().unpolish(self._mute_btn)
        self._mute_btn.style().polish(self._mute_btn)
