import webbrowser
from logging import getLogger

from PySide6.QtCore import Signal, Slot
from PySide6.QtGui import QShowEvent
from PySide6.QtWidgets import QWidget

from rare import __codename__, __version__
from rare.ui.components.tabs.settings.about import Ui_About
from rare.utils.qrequests import QRequests

logger = getLogger('About')


def versiontuple(v) -> tuple[int, ...]:
    try:
        return tuple(map(int, (v.split('.'))))
    except Exception as e:
        logger.error('Error while parsing version %s', v)
        logger.error(e)
        return 99, 99, 99, 999


class About(QWidget):
    update_available = Signal()

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

        self.ui = Ui_About()
        self.ui.setupUi(self)

        self.ui.version.setText(f'{__version__}  {__codename__}')

        self.ui.update_label.setEnabled(False)
        self.ui.update_field.setEnabled(False)
        self.ui.open_browser.setVisible(False)
        self.ui.open_browser.setEnabled(False)

        self.releases_url = 'https://api.github.com/repos/RareDevs/Rare/releases/latest'

        self.manager = QRequests(parent=self)
        self.manager.get(self.releases_url, self._on_update_check_finished)

        self.ui.open_browser.clicked.connect(self._on_browser_clicked)

        self._update_available = False

    def showEvent(self, a0: QShowEvent) -> None:
        if a0.spontaneous():
            return super().showEvent(a0)
        self.manager.get(self.releases_url, self._on_update_check_finished)
        return super().showEvent(a0)

    @Slot()
    def _on_browser_clicked(self):
        webbrowser.open('https://github.com/RareDevs/Rare/releases/latest')

    @Slot(dict)
    def _on_update_check_finished(self, data: dict):
        if latest_tag := data.get('tag_name'):
            self._update_available = versiontuple(latest_tag) > versiontuple(__version__)
        else:
            self._update_available = False

        if self._update_available:
            logger.info(f'Update available: {__version__} -> {latest_tag}')
            self.ui.update_field.setText(f'{__version__} -> {latest_tag}')
            self.update_available.emit()
        else:
            self.ui.update_field.setText(self.tr('You have the latest version'))
        self.ui.update_label.setEnabled(self._update_available)
        self.ui.update_field.setEnabled(self._update_available)
        self.ui.open_browser.setVisible(self._update_available)
        self.ui.open_browser.setEnabled(self._update_available)
