# -*- coding: utf8 -*-

"""Helper components for web links."""

from __future__ import annotations

__all__ = ['open_link', 'NavigatorLink']

import collections.abc
import typing
import urllib.parse

from qtpy import QtCore
from qtpy import QtGui

from anaconda_navigator.utils import telemetry

if typing.TYPE_CHECKING:
    import typing_extensions


def open_link(url: str | QtCore.QUrl, *, origin: str | None = None) -> None:
    """Open a :code:`url` in an external web browser."""
    qt_url: QtCore.QUrl
    if isinstance(url, QtCore.QUrl):
        url, qt_url = url.toString(), url
    else:
        qt_url = QtCore.QUrl(url)

    if url.startswith('navigator://'):
        raise ValueError('Navigator links must be processed separately')

    QtGui.QDesktopServices.openUrl(qt_url)

    details: dict[str, typing.Any] = {'url': url}
    if origin is not None:
        details['origin'] = origin
    telemetry.ANALYTICS.instance.event('redirect', details)


class NavigatorLink(typing.NamedTuple):
    """Details on a :code:`navigator://` link."""

    path: collections.abc.Sequence[str]
    query: collections.abc.Mapping[str, str]

    @classmethod
    def parse(cls, url: str) -> typing_extensions.Self:
        """Parse a :code:`navigator://` link."""
        parts: list[str] = url.split('://', 1)
        if len(parts) > 1:
            if parts[0] != 'navigator':
                raise ValueError('url is not a `navigator://` link')
            parts = parts[1:]

        parts = parts[0].split('?', 1)

        query: dict[str, str] = {}
        if len(parts) >= 2:
            query.update(urllib.parse.parse_qsl(parts[1], keep_blank_values=True))

        return cls(
            path=tuple(map(urllib.parse.unquote, parts[0].split('/'))),
            query=query,
        )
