import traceback

from silx.gui import qt


class ErrorMessageBox(qt.QMessageBox):
    def __init__(self, error, title=None, parent=None):
        super().__init__(parent)
        if title is None:
            title = "Application Error"
        self.setWindowTitle(title)
        self.setIcon(qt.QMessageBox.Critical)
        self.setTextFormat(qt.Qt.RichText)
        message, detailed_text = self._parse_error(error)

        self.setText(message)
        if detailed_text:
            self.setDetailedText(detailed_text)

    @classmethod
    def showError(cls, parent, title, error):
        msg_box = cls(error, title, parent)
        return msg_box.exec_()

    def _parse_error(self, error):
        detailed_text = None
        if hasattr(error, "errors") and callable(getattr(error, "errors")):
            message = "<b>Invalid Parameters:</b><br>Please check the following inputs:<br><ul>"
            for err in error.errors():
                field = " -> ".join(str(loc) for loc in err.get("loc", ["unknown"]))
                message += (
                    f"<li><b>{field}:</b> {err.get('msg', 'Validation error')}</li>"
                )
            message += "</ul>"

        elif isinstance(error, ValueError):
            clean_msg = str(error).capitalize()
            message = (
                f"<b>Invalid Value Provided:</b><br>"
                f"<p style='color: #2c3e50;'>{clean_msg}</p>"
                f"<br><small>Please verify that all numerical ranges and "
                f"selections on the left panel are valid.</small>"
            )
        elif isinstance(error, TypeError):
            message = (
                f"<b>Data Type Error:</b><br>"
                f"<p style='color: #2c3e50;'>{str(error)}</p>"
                f"<br><small>Please enter the variable in "
                f"the respective format of parameters.</small>"
            )
        elif isinstance(error, KeyError):
            message = (
                f"<b>Data Key Error:</b><br>"
                f"<p style='color: #2c3e50;'>{str(error)}</p>"
                f"<br><small>Please verify all the  "
                f"parameters selections on the left panel are valid.</small>"
            )
        elif isinstance(error, FileNotFoundError):
            message = (
                f"<b>Data Access Error:</b><br>"
                f"The system could not locate the file or the specific Nexus path:<br>"
                f"<p style='color: #2c3e50;'>{str(error)}</p>"
                f"<br><small>Please verify that all file paths and "
                f"parameters selections on the left panel are valid.</small>"
            )
        elif isinstance(error, FileExistsError):
            message = "<b>File Already Exists:</b><br>Cannot overwrite the existing file. Please change the output path or enable overwrite."

        elif isinstance(error, PermissionError):
            message = "<b>Permission Denied:</b><br>You do not have write access to this directory or the file is open in another program."

        else:
            message = f"<b>An unexpected error occurred:</b><p>{type(error).__name__}: {str(error)}</p>"
            detailed_text = "".join(
                traceback.format_exception(type(error), error, error.__traceback__)
            )

        return message, detailed_text
