from __future__ import annotations

import os
from typing import Any

from silx.gui import qt

from ewoks3dxrd.models import DetectorCorrectionFiles

from ..common.base_parameter_control import BaseParameterControl
from ..common.file_folder_browse_button import FileFolderBrowseButton


class DetectorControlBox(BaseParameterControl):
    def __init__(self, parent: qt.QWidget | None = None) -> None:
        super().__init__(title="Detector Correction Settings", parent=parent)

        self._spline_group = qt.QGroupBox("Correction via Spline file")
        self._spline_group.setCheckable(True)
        self._spline_group.setChecked(True)

        spline_layout = qt.QFormLayout(self._spline_group)
        self._spline_file = FileFolderBrowseButton(dialogTitle="Select Spline File")
        self._spline_file.setNameFilters(["Spline file (*.spline)", "Any files (*)"])
        spline_layout.addRow("File Path:", self._spline_file)

        self._dxdy_group = qt.QGroupBox("Correction via Dx/Dy Files")
        self._dxdy_group.setCheckable(True)
        self._dxdy_group.setChecked(False)

        dxdy_layout = qt.QFormLayout(self._dxdy_group)
        self._x_file = FileFolderBrowseButton(dialogTitle="Select Dx file")
        self._y_file = FileFolderBrowseButton(dialogTitle="Select Dy file")
        dxdy_layout.addRow("Dx File:", self._x_file)
        dxdy_layout.addRow("Dy File:", self._y_file)

        self._spline_group.toggled.connect(self._disable_dxdy_group)
        self._dxdy_group.toggled.connect(self._disable_spline_group)

        self.settingsLayout.addRow(self._spline_group)
        self.settingsLayout.addRow(self._dxdy_group)

    def _disable_dxdy_group(self, on: bool):
        self._dxdy_group.setChecked(not on)

    def _disable_spline_group(self, on: bool):
        self._spline_group.setChecked(not on)

    def getCorrectionFiles(self) -> DetectorCorrectionFiles:
        if self._spline_group.isChecked():
            correction_files = self._spline_file.getText()
        else:
            correction_files = (self._x_file.getText(), self._y_file.getText())

        if not all(correction_files):
            raise ValueError("Set detector correction file(s).")

        return self._validate_correction_files(correction_files)

    def setCorrectionFiles(self, files: Any):
        correction_files = self._validate_correction_files(files)
        if isinstance(correction_files, str):
            self._spline_group.setChecked(True)
            self._dxdy_group.setChecked(False)
            self._spline_file.setText(correction_files)
        else:
            x_file, y_file = correction_files
            self._dxdy_group.setChecked(True)
            self._spline_group.setChecked(False)
            self._x_file.setText(x_file)
            self._y_file.setText(y_file)

    def _validate_correction_files(self, files: Any) -> DetectorCorrectionFiles:
        if isinstance(files, str):
            if not os.path.exists(files):
                raise FileNotFoundError(f"File does not exist: {files}")

        elif isinstance(files, tuple) and len(files) == 2:
            for f in files:
                if not os.path.exists(f):
                    raise FileNotFoundError(f"File does not exist: {f}")
        else:
            raise ValueError(f"Given correction files are not valid: {files}")

        return files

    def validate(self):
        self.getCorrectionFiles()
