# -*- coding: utf-8 -*-

# pylint: disable=too-few-public-methods

"""Common widgets and their bases."""

__all__ = ['IconButton']

import typing
from qtpy import QtWidgets, QtCore
from anaconda_navigator.static import images
from anaconda_navigator import widgets

if typing.TYPE_CHECKING:
    import typing_extensions


class IconButton(QtWidgets.QPushButton):
    """Common control for icon-only buttons."""


class WarningIcon(QtWidgets.QLabel):
    """
    Icon with exclamation sign.

    Used by :class:`~WarningLabel` and its derivatives.
    """


class ErrorIcon(QtWidgets.QLabel):
    """
    Icon with exclamation sign in circle.
    """


class InfoIcon(QtWidgets.QLabel):
    """
    Icon with exclamation sign in circle.
    """


class LabelWithIcon(QtWidgets.QFrame):
    """
    Combined label with icon at the beginning.

    Icon is shown only when the main text is not empty.
    """

    sig_button_clicked = QtCore.Signal()

    def __init__(  # pylint: disable=too-many-arguments
            self,
            icon: typing.Optional[widgets.QLabel] = None,
            text: str = '',
            tooltip: str = '',
            button: str = '',
            alignment: typing.Any = QtCore.Qt.AlignTop,
    ) -> None:
        """Initialize new :class:`~WarningLabel` instance."""
        super().__init__()

        self.__icon: 'typing_extensions.Final[widgets.QLabel]' = icon
        self.__icon.setVisible(bool(text))

        self.__content: 'typing_extensions.Final[widgets.LabelBase]' = widgets.LabelBase()
        self.__content.setText(text)
        self.__content.setToolTip(tooltip)
        self.__content.setWordWrap(True)

        self.__button: 'typing_extensions.Final[widgets.LabelBase]' = widgets.LabelBase()
        self.__button.setText(button)
        self.__button.sig_clicked.connect(self.sig_button_clicked)

        self.__layout: 'typing_extensions.Final[QtWidgets.QHBoxLayout]' = QtWidgets.QHBoxLayout()
        self.__layout.addWidget(self.__icon, 0, alignment)
        self.__layout.addWidget(self.__content, 1, alignment)
        if button:
            self.__layout.addWidget(self.__button, 0, alignment)
        self.__layout.setContentsMargins(0, 0, 0, 0)
        self.__layout.setSpacing(4)

        self.setLayout(self.__layout)

    @property
    def text(self) -> str:  # noqa: D401
        """Content of the main label."""
        return self.__content.text()

    @text.setter
    def text(self, value: str) -> None:
        """Update `text` value."""
        self.__content.setText(value)
        self.__icon.setVisible(bool(value))


class WarningLabel(LabelWithIcon):
    """
    Combined label with warning icon at the beginning.

    Icon is shown only when the main text is not empty.
    """

    def __init__(
            self,
            text: str = '',
            tooltip: str = '',
            button: str = '',
            alignment: typing.Any = QtCore.Qt.AlignTop,
    ) -> None:
        """Initialize new :class:`~WarningLabel` instance."""
        super().__init__(icon=WarningIcon(), text=text, tooltip=tooltip, button=button, alignment=alignment)


class WarningBlock(WarningLabel):
    """Same as :class:`~WarningLabel`, but with colored background."""

    def __init__(
            self,
            text: str = '',
            tooltip: str = '',
            button: str = '',
            alignment: typing.Any = QtCore.Qt.AlignTop,
    ) -> None:
        """Initialize new :class:`~WarningBlock` instance."""
        super().__init__(text=text, tooltip=tooltip, button=button, alignment=alignment)


class ErrorLabel(LabelWithIcon):
    """
    Combined label with error icon at the beginning.

    Icon is shown only when the main text is not empty.
    """

    def __init__(
            self,
            text: str = '',
            tooltip: str = '',
            button: str = '',
            alignment: typing.Any = QtCore.Qt.AlignTop,
    ) -> None:
        """Initialize new :class:`~ErrorLabel` instance."""
        super().__init__(icon=ErrorIcon(), text=text, tooltip=tooltip, button=button, alignment=alignment)


class ErrorBlock(ErrorLabel):
    """Same as :class:`~ErrorLabel`, but with colored background."""

    def __init__(
            self,
            text: str = '',
            tooltip: str = '',
            button: str = '',
            alignment: typing.Any = QtCore.Qt.AlignTop,
    ) -> None:
        """Initialize new :class:`~ErrorBlock` instance."""
        super().__init__(text=text, tooltip=tooltip, button=button, alignment=alignment)


class InfoLabel(LabelWithIcon):
    """
    Combined label with info icon at the beginning.

    Icon is shown only when the main text is not empty.
    """

    def __init__(
            self,
            text: str = '',
            tooltip: str = '',
            button: str = '',
            alignment: typing.Any = QtCore.Qt.AlignTop,
    ) -> None:
        """Initialize new :class:`~InfoLabel` instance."""
        super().__init__(icon=InfoIcon(), text=text, tooltip=tooltip, button=button, alignment=alignment)


class InfoBlock(InfoLabel):
    """Same as :class:`~InfoLabel`, but with colored background."""

    def __init__(
            self,
            text: str = '',
            tooltip: str = '',
            button: str = '',
            alignment: typing.Any = QtCore.Qt.AlignTop,
    ) -> None:
        """Initialize new :class:`~InfoBlock` instance."""
        super().__init__(text=text, tooltip=tooltip, button=button, alignment=alignment)


class TeamEditionServerAlert(QtWidgets.QWidget):
    """Show combined labels with icon about connectivity problems to TE Server."""

    def __init__(self) -> None:
        super().__init__()
        self.error_label: 'typing_extensions.Final[ErrorBlock]' = ErrorBlock(
            text=(
                '<b>Anaconda Anaconda Server server cannot be reached.</b> '
                'Some actions may not work as expected until connection is restored.'
            ),
            alignment=QtCore.Qt.AlignVCenter,
        )
        self.info_label: 'typing_extensions.Final[InfoBlock]' = InfoBlock(
            text='<b>Connection to Anaconda Anaconda Server server restored.</b>',
            button=f'<img src="{images.BLOCK_CLOSE_ICON_PATH}" height="16" width="16">',
            alignment=QtCore.Qt.AlignVCenter,
        )
        self.__timer: 'typing_extensions.Final[QtCore.QTimer]' = QtCore.QTimer()

        layout: 'typing_extensions.Final[QtWidgets.QVBoxLayout]' = QtWidgets.QVBoxLayout()
        layout.addWidget(self.error_label)
        layout.addWidget(self.info_label)

        self.info_label.sig_button_clicked.connect(self.hide_all)

        self.setLayout(layout)
        self.hide_all()

    def show_info(self, limit: typing.Optional[int] = 5000) -> None:
        """Show info label for `limit` seconds"""
        if not self.error_label.isVisible():
            self.error_label.hide()
            return

        self.show()
        self.error_label.hide()
        self.info_label.show()
        if limit:
            self.__timer.singleShot(limit, self.hide_all)

    def show_error(self) -> None:
        """Show error label"""
        self.show()
        self.error_label.show()
        self.info_label.hide()

    def hide_all(self) -> None:
        """Hide all labels."""
        self.hide()
        self.error_label.hide()
        self.info_label.hide()
