from PyQt6.QtWidgets import (
    QWidget, QHBoxLayout, QVBoxLayout, QPushButton, QLabel, QSlider, QGroupBox, QStyle, QProxyStyle,
)
from PyQt6.QtCore import Qt, pyqtSignal
from PyQt6.QtGui import QPixmap, QColor


def _fmt_time(ms: int) -> str:
    total = ms // 1000
    m, s = divmod(total, 60)
    return f"{m}:{s:02d}"


class JumpStyle(QProxyStyle):
    def styleHint(self, hint, opt=None, widget=None, returnData=None):
        if hint == QStyle.StyleHint.SH_Slider_AbsoluteSetButtons:
            return Qt.MouseButton.LeftButton.value
        return super().styleHint(hint, opt, widget, returnData)


class PlayerHeader(QGroupBox):
    prev_requested = pyqtSignal()
    play_pause_requested = pyqtSignal()
    next_requested = pyqtSignal()
    shuffle_requested = pyqtSignal()
    repeat_requested = pyqtSignal()
    position_changed_by_user = pyqtSignal(int)
    volume_changed = pyqtSignal(int)

    def __init__(self, parent=None):
        super().__init__(parent)
        self.setFlat(True)
        self._setup_ui()

    def _setup_ui(self):
        layout = QVBoxLayout(self)
        layout.setContentsMargins(8, 6, 8, 6)

        controls_row = QHBoxLayout()
        controls_row.setSpacing(8)

        self.prev_btn = QPushButton("\u23EE")
        self.prev_btn.setFixedWidth(36)
        self.prev_btn.setToolTip("Previous")
        self.prev_btn.clicked.connect(self.prev_requested)

        self.play_btn = QPushButton("\u25B6")
        self.play_btn.setFixedWidth(44)
        self.play_btn.setToolTip("Play / Pause")
        self.play_btn.clicked.connect(self.play_pause_requested)

        self.next_btn = QPushButton("\u23ED")
        self.next_btn.setFixedWidth(36)
        self.next_btn.setToolTip("Next")
        self.next_btn.clicked.connect(self.next_requested)

        self.shuffle_btn = QPushButton("\u21C4")
        self.shuffle_btn.setFixedWidth(36)
        self.shuffle_btn.setToolTip("Shuffle")
        self.shuffle_btn.clicked.connect(self.shuffle_requested)

        self.repeat_btn = QPushButton("\u21BB")
        self.repeat_btn.setFixedWidth(36)
        self.repeat_btn.setToolTip("Repeat: Off")
        self.repeat_btn.clicked.connect(self.repeat_requested)

        controls_row.addWidget(self.shuffle_btn)
        controls_row.addWidget(self.prev_btn)
        controls_row.addWidget(self.play_btn)
        controls_row.addWidget(self.next_btn)
        controls_row.addWidget(self.repeat_btn)

        self.time_label_start = QLabel("0:00")
        self.time_label_start.setFixedWidth(40)
        self.time_label_start.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)

        self.position_slider = QSlider(Qt.Orientation.Horizontal)
        self.position_slider.setStyle(JumpStyle(self.position_slider.style()))
        self.position_slider.setMinimum(0)
        self.position_slider.setMaximum(1000)
        self.position_slider.setValue(0)
        self.position_slider.sliderPressed.connect(self._on_slider_user_action)
        self.position_slider.sliderMoved.connect(self._on_slider_user_action)
        self.position_slider.sliderReleased.connect(self._on_slider_user_action)

        self.time_label_end = QLabel("0:00")
        self.time_label_end.setFixedWidth(40)
        self.time_label_end.setAlignment(Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter)

        controls_row.addWidget(self.time_label_start)
        controls_row.addWidget(self.position_slider, stretch=1)
        controls_row.addWidget(self.time_label_end)

        vol_icon = QLabel("\U0001F50A")
        self.volume_slider = QSlider(Qt.Orientation.Horizontal)
        self.volume_slider.setFixedWidth(80)
        self.volume_slider.setRange(0, 100)
        self.volume_slider.setValue(80)
        self.volume_slider.valueChanged.connect(self.volume_changed)

        controls_row.addWidget(vol_icon)
        controls_row.addWidget(self.volume_slider)
        layout.addLayout(controls_row)

        now_playing_layout = QHBoxLayout()
        now_playing_layout.setContentsMargins(6, 0, 0, 0)
        self.cover_label = QLabel()
        self.cover_label.setFixedSize(60, 60)
        self.cover_label.setScaledContents(True)
        self.cover_label.setStyleSheet("background: palette(window); border-radius: 6px;")
        now_playing_layout.addWidget(self.cover_label)

        self.now_playing_label = QLabel("Select a track to play")
        self.now_playing_label.setAlignment(Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter)
        self.now_playing_label.setStyleSheet("color: palette(mid); font-size: 12px;")
        now_playing_layout.addWidget(self.now_playing_label, stretch=1)
        layout.addLayout(now_playing_layout)

    def set_shuffle_active(self, active: bool):
        if active:
            self.shuffle_btn.setStyleSheet("color: palette(highlight); font-weight: bold;")
            self.shuffle_btn.setToolTip("Shuffle: On")
        else:
            self.shuffle_btn.setStyleSheet("")
            self.shuffle_btn.setToolTip("Shuffle: Off")

    def set_repeat_mode(self, mode: str):
        if mode == "repeat_all":
            self.repeat_btn.setText("\u21BB")
            self.repeat_btn.setStyleSheet("color: palette(highlight); font-weight: bold;")
            self.repeat_btn.setToolTip("Repeat: All")
        elif mode == "repeat_one":
            self.repeat_btn.setText("\u21BB\u00B9")
            self.repeat_btn.setStyleSheet("color: palette(highlight); font-weight: bold;")
            self.repeat_btn.setToolTip("Repeat: One")
        else:
            self.repeat_btn.setText("\u21BB")
            self.repeat_btn.setStyleSheet("")
            self.repeat_btn.setToolTip("Repeat: Off")

    def _on_slider_user_action(self):
        self.position_changed_by_user.emit(self.position_slider.value())

    def set_cover(self, pixmap: QPixmap = None, tooltip: str = ""):
        if pixmap:
            self.cover_label.setPixmap(pixmap)
        else:
            self.cover_label.clear()
        self.cover_label.setToolTip(tooltip)

    def set_track_info(self, text: str):
        self.now_playing_label.setText(text)
        self.now_playing_label.setStyleSheet(
            "color: palette(text); font-weight: bold;" if text else "color: palette(mid); font-size: 12px;"
        )

    def set_playing(self, playing: bool):
        self.play_btn.setText("\u23F8" if playing else "\u25B6")

    def set_position(self, position_ms: int, duration_ms: int):
        if not self.position_slider.isSliderDown():
            if duration_ms > 0:
                self.position_slider.setValue(int(position_ms / duration_ms * 1000))
            else:
                self.position_slider.setValue(0)
        self.time_label_start.setText(_fmt_time(position_ms))
        self.time_label_end.setText(_fmt_time(duration_ms))

    def set_volume(self, value: int):
        self.volume_slider.setValue(value)

    def reset_info(self):
        self.cover_label.clear()
        self.cover_label.setToolTip("")
        self.now_playing_label.setText("Select a track to play")
        self.now_playing_label.setStyleSheet("color: palette(mid); font-size: 12px;")
        self.time_label_start.setText("0:00")
        self.time_label_end.setText("0:00")
        self.position_slider.setValue(0)
        self.play_btn.setText("\u25B6")
