# -*- coding: utf-8 -*-
# -----------------------------------------------------------------------------
# Copyright 2016 Continuum Analytics, Inc.
#
# May be copied and distributed freely only as part of an Anaconda or
# Miniconda installation.
# -----------------------------------------------------------------------------
"""Custom widgets used for dialog definition and styling."""

# Third party imports
from qtpy.QtCore import Qt
from qtpy.QtWidgets import (QDialog, QDialogButtonBox,
                            QGraphicsDropShadowEffect, QHBoxLayout, QLabel,
                            QTextEdit, QVBoxLayout)

# Local imports
from anaconda_navigator.utils.analytics import GATracker
from anaconda_navigator.utils.py3compat import parse, to_text_string
from anaconda_navigator.utils.styles import BLUR_SIZE, load_style_sheet
from anaconda_navigator.widgets import (ButtonBase, ButtonDanger, ButtonNormal,
                                        ButtonPrimary, FrameBase, LabelBase,
                                        SpacerHorizontal, SpacerVertical)


class FrameDialog(FrameBase):
    """Frame widget used for CSS styling of the body dialogs."""


class FrameDialogBody(FrameBase):
    """Frame widget used for CSS styling of the body dialogs."""


class FrameDialogTitleBar(FrameBase):
    """Frame widget used for CSS styling of the title bar of dialogs."""


class LabelDialogTitleBar(LabelBase):
    """Label used for CSS styling of the title of dialogs."""


class ButtonDialogClose(ButtonBase):
    """Button used for CSS styling ot the close dialog button."""


class DialogBase(QDialog):
    """Base dialog widget."""

    def __init__(self, *args, **kwargs):
        """Base dialog widget."""
        super(DialogBase, self).__init__(*args, **kwargs)

        # Widgets
        self.frame_dialog = FrameDialog(self)
        self.frame_title_bar = FrameDialogTitleBar(self)
        self.frame_body = FrameDialogBody(self)
        self.button_close_dialog = ButtonDialogClose('X')
        self.label_title_bar = LabelDialogTitleBar('Title')
        self.setAttribute(Qt.WA_TranslucentBackground)
        self.setWindowFlags(Qt.MSWindowsFixedSizeDialogHint)
        self.setSizeGripEnabled(False)
        self.style_sheet = None

        # Widget setup
        shadow = QGraphicsDropShadowEffect()
        shadow.setBlurRadius(BLUR_SIZE)
        shadow.setOffset(0, 0)

        self.frame_dialog.setGraphicsEffect(shadow)
        self.setWindowFlags(Qt.Dialog | Qt.FramelessWindowHint)
        self.button_close_dialog.setFocusPolicy(Qt.NoFocus)

        # Signals
        self.button_close_dialog.clicked.connect(self.reject)

        self.update_style_sheet()

    def setWindowTitle(self, title):
        """Qt override."""
        self.label_title_bar.setText(title)

    def setLayout(self, body_layout):
        """Qt override."""
        title_layout = QHBoxLayout()
        title_layout.addWidget(self.label_title_bar)
        title_layout.addStretch(100000000)
        title_layout.addWidget(self.button_close_dialog)
        title_layout.setContentsMargins(0, 0, 0, 0)
        self.frame_title_bar.setLayout(title_layout)
        self.frame_body.setLayout(body_layout)

        layout_dialog = QVBoxLayout()
        layout_dialog.addWidget(self.frame_title_bar)
        layout_dialog.addWidget(self.frame_body)
        layout_dialog.setContentsMargins(0, 0, 0, 0)
        layout_dialog.setSpacing(0)
        self.frame_dialog.setLayout(layout_dialog)

        layout = QVBoxLayout()
        layout.addWidget(self.frame_dialog)
        self._fix_layout(layout)
        self._fix_layout(title_layout)
        super(DialogBase, self).setLayout(layout)
#        self.frame_title_bar.setMidLineWidth(self.frame_body.width())

    def _fix_layout(self, layout):
        if layout:
            layout.setSpacing(0)
            layout.setContentsMargins(0, 0, 0, 0)
#            layout.setSizeConstraint(QLayout.SetFixedSize)

            items = (layout.itemAt(i).widget() for i in range(layout.count()))
            for w in items:
                if w:
                    new_layout = w.layout()
                    self._fix_layout(new_layout)
        return layout

    def update_style_sheet(self, style_sheet=None):
        """Update custom css stylesheet."""
        if style_sheet is None:
            self.style_sheet = load_style_sheet()
        self.setStyleSheet(self.style_sheet)


class ActionsDialog(DialogBase):
    """Accept actions for pacakge manager."""

    def __init__(self, text, parent=None):
        """Accept actions for pacakge manager."""
        super(ActionsDialog, self).__init__(parent=parent)

        self.label = QLabel(text)
        self.button_cancel = ButtonDanger('Cancel')
        self.button_accept = ButtonPrimary('Ok')

        self.setWindowTitle('Proceed with the following actions?')

        # Layout
        layout_buttons = QHBoxLayout()
        layout_buttons.addStretch()
        layout_buttons.addWidget(self.button_cancel)
        layout_buttons.addWidget(SpacerHorizontal())
        layout_buttons.addWidget(self.button_accept)

        layout = QVBoxLayout()
        layout.addWidget(self.label)
        layout.addWidget(SpacerVertical())
        layout.addWidget(SpacerVertical())
        layout.addLayout(layout_buttons)
        self.setLayout(layout)

        self.button_accept.clicked.connect(self.accept)
        self.button_cancel.clicked.connect(self.reject)


class MessageBox(DialogBase):
    """Base message box dialog."""

    QUESTION_BOX = 100
    INFORMATION_BOX = 101
    ERROR_BOX = 102

    def __init__(self, type_, error='', title='', text=''):
        """Base message box dialog."""
        super(MessageBox, self).__init__()
        self.label_text = QLabel(to_text_string(text))
        self.textbox_error = QTextEdit()
        self.button_ok = ButtonPrimary('Ok')
        self.button_yes = ButtonPrimary('Yes')
        self.button_no = ButtonDanger('No')
        self.button_copy = ButtonNormal('Copy text')
        self.bbox = QDialogButtonBox(Qt.Horizontal)

        self.textbox_error.setReadOnly(True)
        self.textbox_error.setFrameStyle(QTextEdit.Plain)
        self.textbox_error.setFrameShape(QTextEdit.NoFrame)
        self.setMinimumWidth(260)
        self.textbox_error.verticalScrollBar().show()
        self.setWindowTitle(to_text_string(title))

        error = to_text_string(error).split('\n')
        error = '<br>'.join(error)
        self.textbox_error.setText(error)

        # Layouts
        layout = QVBoxLayout()
        layout.addWidget(self.label_text)
        layout.addWidget(SpacerVertical())
        layout.addWidget(self.textbox_error)
        layout.addWidget(SpacerVertical())
        layout.addWidget(self.button_copy)
        layout.addWidget(SpacerVertical())
        layout.addWidget(SpacerVertical())
        layout.addWidget(self.bbox)
        self.layout = layout
        self.setLayout(layout)

        # Signals
        self.button_copy.clicked.connect(self.copy_text)
        self.button_ok.clicked.connect(self.accept)
        self.button_yes.clicked.connect(self.accept)
        self.button_no.clicked.connect(self.reject)

        # Setup
        if type_ == self.ERROR_BOX:
            self.bbox.addButton(self.button_ok, QDialogButtonBox.AcceptRole)
            self.button_yes.setVisible(False)
            self.button_no.setVisible(False)
        elif type_ == self.INFORMATION_BOX:
            self.bbox.addButton(self.button_ok, QDialogButtonBox.AcceptRole)
            self.button_yes.setVisible(False)
            self.button_no.setVisible(False)
            self.textbox_error.setVisible(False)
            self.button_copy.setVisible(False)
        elif type_ == self.QUESTION_BOX:
            self.bbox.addButton(self.button_yes, QDialogButtonBox.AcceptRole)
            self.bbox.addButton(self.button_no, QDialogButtonBox.RejectRole)
            self.textbox_error.setVisible(False)
            self.button_ok.setVisible(False)
            self.button_copy.setVisible(False)

    def copy_text(self):
        """Copy all the content of the displayed error message."""
        self.textbox_error.selectAll()
        self.textbox_error.copy()


class MessageBoxQuestion(MessageBox):
    """Question message box."""

    def __init__(self, text='', title=''):
        """Question message box."""
        super(MessageBoxQuestion, self).__init__(text=text, title=title,
                                                 type_=self.QUESTION_BOX)


class MessageBoxInformation(MessageBox):
    """Information message box."""

    def __init__(self, text='', error='', title=''):
        """Information message box."""
        super(MessageBoxInformation, self).__init__(text=text, title=title,
                                                    type_=self.INFORMATION_BOX)


class MessageBoxError(MessageBox):
    """Error message box dialog with ability to send error reprots."""

    def __init__(self, text='', error='', title=''):
        """Error message box dialog with ability to send error reprots."""
        super(MessageBoxError, self).__init__(text=text, title=title,
                                              error=error,
                                              type_=self.ERROR_BOX)
        self.text = text
        self.error = error
        self.button_send = ButtonNormal('Report Issue', parent=self)
        self.bbox.addButton(self.button_send, QDialogButtonBox.ActionRole)
        self.button_send.clicked.connect(self.send)

    def send(self):
        """Send error report to github and create an issue with a template."""
        import webbrowser
        base = "https://github.com/ContinuumIO/anaconda-issues/issues/new?{0}"
        query = parse.urlencode({
            'title': "Navigator Error",
            'labels': "Navigator",
            'body': "{}\n\n{}\n\n{}".format(self.text,
                                            self.error, GATracker().info)})
        url = base.format(query)
        webbrowser.open_new_tab(url)


# --- Local testing
# -----------------------------------------------------------------------------
def test():  # pragma : no cover
    """Run local tests."""
    from anaconda_navigator.utils.qthelpers import qapplication

    app = qapplication(test_time=3)
    widget_information = MessageBoxInformation(text='SomeRandomText')
    widget_information.show()
    widget_information.update_style_sheet()

    widget_error = MessageBoxError(text='SomeRandomText', error='Some error')
    widget_error.show()
    widget_error.update_style_sheet()
    app.exec_()


if __name__ == '__main__':  # pragma : no cover
    test()
