"""Media player widget for Meeting Helper GUI."""

from __future__ import annotations

from pathlib import Path

from PySide6.QtCore import Qt, Signal, Slot
from PySide6.QtMultimedia import QAudioOutput, QMediaPlayer
from PySide6.QtWidgets import (
    QComboBox,
    QHBoxLayout,
    QLabel,
    QPushButton,
    QSlider,
    QWidget,
)


def format_time(ms: int) -> str:
    total_seconds = ms // 1000
    hours = total_seconds // 3600
    minutes = (total_seconds % 3600) // 60
    seconds = total_seconds % 60
    if hours > 0:
        return f"{hours}:{minutes:02d}:{seconds:02d}"
    return f"{minutes}:{seconds:02d}"


class MediaPlayerWidget(QWidget):
    """Audio player widget with playback controls."""

    position_changed = Signal(int)
    playback_state_changed = Signal(bool)

    def __init__(self, parent=None):
        super().__init__(parent)
        self._duration_ms = 0
        self._is_seeking = False
        self._setup_player()
        self._setup_ui()
        self._connect_signals()

    def _setup_player(self):
        self._player = QMediaPlayer()
        self._audio_output = QAudioOutput()
        self._player.setAudioOutput(self._audio_output)
        self._audio_output.setVolume(1.0)

    def _setup_ui(self):
        layout = QHBoxLayout(self)
        layout.setContentsMargins(15, 10, 15, 10)
        layout.setSpacing(12)

        self._skip_back_btn = QPushButton("15")
        self._skip_back_btn.setToolTip("Skip back 15 seconds")
        self._skip_back_btn.setFixedSize(36, 36)
        self._skip_back_btn.setStyleSheet("""
            QPushButton { background-color: #3c3c3c; border-radius: 18px; font-size: 11px; font-weight: 600; }
            QPushButton:hover { background-color: #4c4c4c; }
        """)
        layout.addWidget(self._skip_back_btn)

        self._play_btn = QPushButton("\u25b6")
        self._play_btn.setToolTip("Play/Pause")
        self._play_btn.setFixedSize(44, 44)
        self._play_btn.setStyleSheet("""
            QPushButton { background-color: #0e639c; border-radius: 22px; font-size: 16px; }
            QPushButton:hover { background-color: #1177bb; }
        """)
        layout.addWidget(self._play_btn)

        self._skip_forward_btn = QPushButton("15")
        self._skip_forward_btn.setToolTip("Skip forward 15 seconds")
        self._skip_forward_btn.setFixedSize(36, 36)
        self._skip_forward_btn.setStyleSheet("""
            QPushButton { background-color: #3c3c3c; border-radius: 18px; font-size: 11px; font-weight: 600; }
            QPushButton:hover { background-color: #4c4c4c; }
        """)
        layout.addWidget(self._skip_forward_btn)

        self._speed_combo = QComboBox()
        self._speed_combo.addItems(["0.5x", "0.75x", "1x", "1.25x", "1.5x", "2x"])
        self._speed_combo.setCurrentText("1x")
        self._speed_combo.setFixedWidth(70)
        self._speed_combo.setStyleSheet("""
            QComboBox { background-color: #3c3c3c; border: none; border-radius: 4px; padding: 4px 8px; font-size: 12px; }
            QComboBox:hover { background-color: #4c4c4c; }
            QComboBox::drop-down { border: none; width: 20px; }
            QComboBox::down-arrow { image: none; border-left: 4px solid transparent; border-right: 4px solid transparent; border-top: 5px solid #ffffff; margin-right: 5px; }
        """)
        layout.addWidget(self._speed_combo)

        self._current_time_label = QLabel("0:00")
        self._current_time_label.setFixedWidth(50)
        self._current_time_label.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
        self._current_time_label.setStyleSheet("color: #ffffff; font-size: 12px;")
        layout.addWidget(self._current_time_label)

        self._slider = QSlider(Qt.Horizontal)
        self._slider.setMinimum(0)
        self._slider.setMaximum(1000)
        self._slider.setValue(0)
        layout.addWidget(self._slider, 1)

        self._total_time_label = QLabel("0:00")
        self._total_time_label.setFixedWidth(50)
        self._total_time_label.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        self._total_time_label.setStyleSheet("color: #858585; font-size: 12px;")
        layout.addWidget(self._total_time_label)

        self.setFixedHeight(64)
        self.setStyleSheet("MediaPlayerWidget { background-color: #252526; border-top: 1px solid #3c3c3c; }")

    def _connect_signals(self):
        self._player.positionChanged.connect(self._on_position_changed)
        self._player.durationChanged.connect(self._on_duration_changed)
        self._player.playbackStateChanged.connect(self._on_playback_state_changed)
        self._play_btn.clicked.connect(self.toggle)
        self._skip_back_btn.clicked.connect(self._skip_back)
        self._skip_forward_btn.clicked.connect(self._skip_forward)
        self._speed_combo.currentTextChanged.connect(self._on_speed_changed)
        self._slider.sliderPressed.connect(self._on_slider_pressed)
        self._slider.sliderReleased.connect(self._on_slider_released)
        self._slider.sliderMoved.connect(self._on_slider_moved)

    def load(self, path: Path):
        from PySide6.QtCore import QUrl
        self._player.setSource(QUrl.fromLocalFile(str(path)))
        self._player.setPosition(0)

    def toggle(self):
        if self._player.playbackState() == QMediaPlayer.PlayingState:
            self._player.pause()
        else:
            self._player.play()

    @Slot(int)
    def _on_position_changed(self, position: int):
        if not self._is_seeking:
            self._current_time_label.setText(format_time(position))
            if self._duration_ms > 0:
                self._slider.setValue(int((position / self._duration_ms) * 1000))
        self.position_changed.emit(position)

    @Slot(int)
    def _on_duration_changed(self, duration: int):
        self._duration_ms = duration
        self._total_time_label.setText(format_time(duration))

    @Slot(QMediaPlayer.PlaybackState)
    def _on_playback_state_changed(self, state: QMediaPlayer.PlaybackState):
        is_playing = state == QMediaPlayer.PlayingState
        self._play_btn.setText("\u23f8" if is_playing else "\u25b6")
        self.playback_state_changed.emit(is_playing)

    def _on_slider_pressed(self):
        self._is_seeking = True

    def _on_slider_released(self):
        self._is_seeking = False
        if self._duration_ms > 0:
            self._player.setPosition(int((self._slider.value() / 1000) * self._duration_ms))

    def _on_slider_moved(self, value: int):
        if self._duration_ms > 0:
            self._current_time_label.setText(format_time(int((value / 1000) * self._duration_ms)))

    def _skip_back(self):
        self._player.setPosition(max(0, self._player.position() - 15000))

    def _skip_forward(self):
        self._player.setPosition(min(self._duration_ms, self._player.position() + 15000))

    def _on_speed_changed(self, text: str):
        self._player.setPlaybackRate(float(text.replace("x", "")))

    def stop(self):
        self._player.stop()
        self._player.setPosition(0)
