# local
from .controls import ControlsWidget
from .media_library import MediaLibrary
from .now_playing import NowPlayingWidget
from only_otters.facts import get_fact_by_tags
from only_otters.facts.audio import text_to_audio
from only_otters.images import buttons as imgButtons

# std
from pathlib import Path

# qt
from PyQt5 import QtWidgets, QtMultimedia, QtGui, QtCore


class MusicPlayer(QtWidgets.QWidget):
    """Represents a MusicPlayer object, for playing/pausing/loading music."""

    # Every {} songs, an ad will be played automatically
    total_songs_between_adverts: int = 1

    fact_refresh_rate = 8

    def __init__(self):
        super().__init__()
        self.player = QtMultimedia.QMediaPlayer()
        self.playlist = QtMultimedia.QMediaPlaylist()
        self.player.setPlaylist(self.playlist)
        self.player.playlist().currentMediaChanged.connect(self.disable_advert_controls)
        self.advert_in_progress = False

        self.advert_counter = self.total_songs_between_adverts - 1

        self.init_ui()

    def init_ui(self):
        """Create the UI."""
        self.main_layout = QtWidgets.QVBoxLayout(self)
        self.main_layout.setContentsMargins(0, 0, 0, 0)
        self.main_layout.setSpacing(0)
        self.setStyleSheet('QLabel { color: white; }')

        self.vertical_spacer = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Fixed,
                                                     QtWidgets.QSizePolicy.Expanding)

        self.now_playing_widget = NowPlayingWidget(self.player)

        images_path = Path('only_otters/images')
        self.foreground_image = QtGui.QPixmap(str(images_path / 'foreground.png'))
        self.foreground_label = QtWidgets.QLabel(self)
        self.foreground_label.setPixmap(self.foreground_image)

        self.contents_widget = QtWidgets.QFrame()
        self.contents_widget.setStyleSheet('background: qlineargradient(spread:pad, '
                                           'x1:0.495, y1:0, x2:0.5, y2:1,'
                                           'stop:0 rgba(155, 118, 83, 255),'
                                           'stop:1 rgba(122, 93, 65, 255))')
        self.contents_widget.setSizePolicy(QtWidgets.QSizePolicy.Preferred,
                                           QtWidgets.QSizePolicy.Expanding)
        self.contents_layout = QtWidgets.QHBoxLayout()
        self.contents_layout.setContentsMargins(50, 60, 50, 50)
        self.contents_layout.setSpacing(30)
        self.main_content_layout = QtWidgets.QVBoxLayout()
        self.main_content_layout.setAlignment(QtCore.Qt.AlignLeft)
        self.sidebar_layout = QtWidgets.QVBoxLayout()
        self.sidebar_layout.setSpacing(0)

        self.media_library = MediaLibrary()
        self.media_library.song_triggered.connect(self.play_song)

        self.main_content_layout.addWidget(self.media_library)
        self.main_content_layout.addItem(self.vertical_spacer)

        self.fact_title_frame = QtWidgets.QFrame()
        self.fact_title_frame.setStyleSheet('background: #57bd4f;'
                                            'border-top-left-radius: 6px;'
                                            'border-top-right-radius: 6px;'
                                            'color: white;')
        self.fact_title_layout = QtWidgets.QHBoxLayout()
        title_font = QtGui.QFont('Raleway', 16)
        title_font.setBold(True)
        self.fact_title_label = QtWidgets.QLabel('Climate Change Facts')
        self.fact_title_label.setFont(title_font)
        self.fact_title_layout.addWidget(self.fact_title_label)
        self.fact_title_frame.setLayout(self.fact_title_layout)

        self.fact_widget = get_fact_by_tags('ui').as_widget(self)
        self.fact_widget.setMinimumSize(300, 200)

        self.next_fact_button = QtWidgets.QPushButton("Next Fact", self)
        self.next_fact_button.clicked.connect(self.refresh_fact)
        self.next_fact_button.setStyleSheet('background: #78543b;'
                                            'padding: 7px;'
                                            'border-bottom-left-radius: 6px;'
                                            'border-bottom-right-radius: 6px;'
                                            'color: white;')

        self.refresh_fact_timer = QtCore.QTimer(self)
        self.refresh_fact_timer.timeout.connect(self.refresh_fact)
        self.refresh_fact_timer.start(self.fact_refresh_rate * 1000)

        self.sidebar_layout.addWidget(self.fact_title_frame)
        self.sidebar_layout.addWidget(self.fact_widget)
        self.sidebar_layout.addWidget(self.next_fact_button)
        self.sidebar_layout.addItem(self.vertical_spacer)

        self.contents_layout.addLayout(self.main_content_layout)
        self.contents_layout.addLayout(self.sidebar_layout)
        self.contents_widget.setLayout(self.contents_layout)

        self.controls = ControlsWidget(self.player)

        self.main_layout.addWidget(self.now_playing_widget)
        self.main_layout.addWidget(self.contents_widget)
        self.main_layout.addWidget(self.controls)

        self.setLayout(self.main_layout)

    def play_song(self, song: str):
        """Play a song given its file url in the local filesystem."""
        self.player.playlist().clear()
        self.controls.duration_label.setText('Loading...')
        url = QtCore.QUrl.fromLocalFile(song)

        if self.check_advert_intermission():
            self.player.playlist().addMedia(QtMultimedia.QMediaContent(url))
        else:
            self.player.playlist().insertMedia(
                self.player.playlist().nextIndex(),
                QtMultimedia.QMediaContent(url)
            )

            if self.player.playlist().mediaCount() == 1:
                self.controls.toggle_play()
            else:
                self.controls._next_song()
        self.controls.duration_label.setText('0')
        self.controls.play_pause_button.setIcon(QtGui.QIcon(imgButtons.Pause.str))

    def disable_advert_controls(self, media: QtMultimedia.QMediaContent):
        """Disable player controls while an ad is playing."""
        if self.advert_in_progress:
            self.now_playing_widget.audio_visualiser.green_flames()
            self.controls.setEnabled(False)
            self.advert_in_progress = False
        else:
            self.now_playing_widget.audio_visualiser.red_flames()
            self.controls.setEnabled(True)

    def play_ad(self):
        """Play an ad before a song is played."""
        self.advert_in_progress = True

        fact = get_fact_by_tags('text')
        text = "Did you know that ... " + fact.content + '. Thank you for listening to Leafify'

        file = text_to_audio(text)
        self.play_song(file)

        self.now_playing_widget.now_playing_label.setText('Advert Intermission')

    def check_advert_intermission(self):
        """
        Callback for every time the media player's status changes.
        Will play an ad after each song. 'ADVERT' is a on/off
        """
        if not self.advert_counter:
            self.advert_counter = self.total_songs_between_adverts
            self.play_ad()
            return True
        else:
            self.advert_counter -= 1
            return False

    def resizeEvent(self, event):
        """Handles the positioning and sizing of the moon foreground image."""
        scaled = self.foreground_image.scaled(max(self.width(), 1920), 99999999,
                                              QtCore.Qt.KeepAspectRatio)
        self.foreground_label.setPixmap(scaled)

        self.foreground_label.move(0, self.now_playing_widget.y() +
                                   self.now_playing_widget.height() - scaled.height()*0.65)
        self.foreground_label.resize(self.width(), scaled.height())
        self.foreground_label.raise_()

    def refresh_fact(self):
        """Refresh the fact widget."""

        # Delete previous widget
        self.fact_widget.deleteLater()

        # Prepare widget
        self.fact_widget = get_fact_by_tags('ui').as_widget(self)
        self.fact_widget.setMinimumSize(300, 200)

        # Place widget
        self.sidebar_layout.insertWidget(1, self.fact_widget)

        # Reset timer
        self.refresh_fact_timer.start(self.fact_refresh_rate * 1000)