import urllib.parse

from datetime import datetime
from slugify import slugify                 # type: ignore
from typing import Dict, Optional
from PyQt5.QtCore import QUrl
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtWidgets import QTabWidget
from config import Config


class InfoTabs(QTabWidget):
    """
    Class to manage info tabs
    """

    def __init__(self, parent=None) -> None:
        super().__init__(parent)

        # Dictionary to record when tabs were last updated (so we can
        # re-use the oldest one later)
        self.last_update: Dict[QWebEngineView, datetime] = {}

    def open_in_songfacts(self, title):
        """Search Songfacts for title"""

        slug = slugify(title, replacements=([["'", ""]]))
        url = f"https://www.songfacts.com/search/songs/{slug}"

        self.open_tab(url, title)

    def open_in_wikipedia(self, title):
        """Search Wikipedia for title"""

        str = urllib.parse.quote_plus(title)
        url = f"https://www.wikipedia.org/w/index.php?search={str}"

        self.open_tab(url, title)

    def open_tab(self, url: str, title: str) -> None:
        """
        Open passed URL. Create new tab if we're below the maximum
        number otherwise reuse oldest content tab.
        """

        short_title = title[:Config.INFO_TAB_TITLE_LENGTH]

        if self.count() < Config.MAX_INFO_TABS:
            # Create a new tab
            widget = QWebEngineView()
            widget.setZoomFactor(Config.WEB_ZOOM_FACTOR)
            tab_index = self.addTab(widget, short_title)

        else:
            # Reuse oldest widget
            widget = min(
                self.last_update, key=self.last_update.get      # type: ignore
            )
            tab_index = self.indexOf(widget)
            self.setTabText(tab_index, short_title)

        widget.setUrl(QUrl(url))
        self.last_update[widget] = datetime.now()

        # Show newly updated tab
        self.setCurrentIndex(tab_index)
