import qtawesome
from silx.gui import qt

from .dataURL_group_box import DataURLGroupBox
from .process_name_line_edit import ProcessNameLineEdit


class _BaseExecutionGroupBox(qt.QGroupBox):
    sigExecuteRequested = qt.Signal()

    def __init__(
        self,
        title="Execution Control",
        buttonText="Execute",
        parent=None,
    ):
        super().__init__(title, parent)
        self.executeBtn = qt.QPushButton(buttonText)
        self.executeBtn.setAutoDefault(False)
        self.executeBtn.clicked.connect(self.sigExecuteRequested)
        self.overwrite = qt.QCheckBox("Overwrite Output URL")

    def isOverwriteChecked(self) -> bool:
        return self.overwrite.isChecked()

    def setOverwrite(self, v: bool):
        self.overwrite.setChecked(v)


class ExecutionControlGroupBox(_BaseExecutionGroupBox):
    sigUrlChanged = qt.Signal()

    def __init__(
        self,
        title="Execution Control",
        buttonText="Execute",
        parent=None,
    ):
        super().__init__(
            title=title,
            buttonText=buttonText,
            parent=parent,
        )
        layout = qt.QVBoxLayout(self)

        self.urlWidget = DataURLGroupBox(title="Peaks Group Data URL:")
        self.urlWidget.editingFinished.connect(self.sigUrlChanged)
        layout.addWidget(self.urlWidget)

        formLayout = qt.QFormLayout()
        layout.addLayout(formLayout)
        layout.addWidget(self.overwrite)
        layout.addWidget(self.executeBtn)
        layout.addStretch()

    def getInputURL(self) -> str:
        return self.urlWidget.text()

    def setInputURL(self, url: str):
        self.urlWidget.setText(url)

    @property
    def inputUrlWidget(self):
        return self.urlWidget

    def validate(self):
        url = self.getInputURL()
        if not url:
            message = "The Input Data URL is empty. Please provide a path."
        elif not self.inputUrlWidget.validDataURL():
            message = f"The path or group '{url}' does not exist."
        else:
            message = None

        if message:
            raise ValueError(f"Invalid URL, {message}")


class ExecutionControlGroupBoxWithProcessName(ExecutionControlGroupBox):
    def __init__(
        self,
        title="Execution Control",
        buttonText="Execute",
        parent=None,
    ):
        super().__init__(
            title=title,
            buttonText=buttonText,
            parent=parent,
        )
        self._processNameEdit = ProcessNameLineEdit()
        layout = self.layout()
        layout.removeWidget(self.overwrite)
        layout.removeWidget(self.executeBtn)
        layout.addWidget(self.urlWidget)
        layout.addWidget(self._processNameEdit)
        layout.addWidget(self.overwrite)
        layout.addWidget(self.executeBtn)

    def getProcessName(self) -> str:
        return self._processNameEdit.getText()

    def setProcessName(self, name: str):
        self._processNameEdit.setText(name)

    def validate(self):
        super().validate()
        if self._processNameEdit.getText() == "":
            raise ValueError("Provide a process group name")


class ProgressBarExecutionGroup(_BaseExecutionGroupBox):
    def __init__(
        self, title="Execution Control", buttonText="Refine Grains", parent=None
    ):
        super().__init__(
            title=title,
            buttonText=buttonText,
            parent=parent,
        )

        layout = qt.QVBoxLayout(self)
        layout.addWidget(self.overwrite)
        self._progressBar = qt.QProgressBar()
        self._progressBar.setRange(0, 100)
        self._progressBar.setValue(0)
        self._progressBar.setTextVisible(True)
        layout.addWidget(self._progressBar)

        self.showResultBtn = qt.QPushButton(qtawesome.icon("fa6.eye"), "")
        self.showResultBtn.setFlat(True)
        self.showResultBtn.setToolTip("Show 3D segmented result")
        self.showResultBtn.setFixedSize(30, 30)
        self.showResultBtn.setDisabled(True)
        btnLayout = qt.QHBoxLayout()
        btnLayout.addWidget(self.executeBtn, stretch=1)
        btnLayout.addWidget(self.showResultBtn)
        layout.addLayout(btnLayout)

    def setProgress(self, value: int):
        self._progressBar.setValue(value)


class ExecutionGroup(_BaseExecutionGroupBox):
    def __init__(
        self, title="Execution Control", buttonText="Refine Grains", parent=None
    ):
        super().__init__(title=title, buttonText=buttonText, parent=parent)
        layout = qt.QVBoxLayout(self)
        layout.addWidget(self.overwrite)
        layout.addWidget(self.executeBtn)
        layout.addStretch()
