from PyQt5.QtWidgets import QWidget, QGridLayout, QLabel, QComboBox, QTableView

from openlog.datamodel.assay.generic_assay import AssayDatabaseDefinition
from openlog.toolbelt.string_map_table_model import StringMapTableModel


class AssayDatabaseDefinitionWidget(QWidget):
    HOLE_COL_DEFAULT = "hole"
    DATASET_COL_DEFAULT = "dataset"
    X_COL_DEFAULT = "x"
    X_END_COL_DEFAULT = "x_end"

    def __init__(self, parent: QWidget = None):
        """
        QWidget to display AssayDatabaseDefinition

        Args:
            parent: QWidget parent
        """
        super().__init__(parent)

        self.layout = QGridLayout()
        self.table_cb = self._add_combobox(self.tr("Table"))
        self.hole_id_cb = self._add_combobox(self.tr("Hole id column"), self.HOLE_COL_DEFAULT)
        self.dataset_cb = self._add_combobox(self.tr("Dataset column"), self.DATASET_COL_DEFAULT)
        self.x_col_cb = self._add_combobox(self.tr("X column"), self.X_COL_DEFAULT)
        self.x_end_col_cb = self._add_combobox(self.tr("X end column"), self.X_END_COL_DEFAULT)
        self.schema_cb = self._add_combobox(self.tr("Schema"))

        row_count = self.layout.rowCount()
        self.assay_column_definition_table = QTableView(self)
        self.assay_column_definition_table.horizontalHeader().setVisible(False)
        self.assay_column_definition_model = StringMapTableModel(self,
                                                                 self.tr("Downhole data column"),
                                                                 self.tr("Database column"))
        self.assay_column_definition_table.setModel(self.assay_column_definition_model)
        self.layout.addWidget(self.assay_column_definition_table, row_count, 0, 1, 2)

        self.setLayout(self.layout)

    def set_assay_database_definition(self, assay_definition: AssayDatabaseDefinition):
        """
        Update widget with assay database definition

        Args:
            assay_definition: AssayDatabaseDefinition
        """
        self.table_cb.setCurrentText(assay_definition.table_name)
        self.hole_id_cb.setCurrentText(assay_definition.hole_id_col)
        self.dataset_cb.setCurrentText(assay_definition.dataset_col)
        self.x_col_cb.setCurrentText(assay_definition.x_col)
        self.x_end_col_cb.setCurrentText(assay_definition.x_end_col)
        self.schema_cb.setCurrentText(assay_definition.schema)

        self.assay_column_definition_model.set_string_map(assay_definition.y_col)

    def get_assay_database_definition(self) -> AssayDatabaseDefinition:
        """
        Returns current assay database definition

        Returns: AssayDatabaseDefinition

        """
        return AssayDatabaseDefinition(table_name=self.table_cb.currentText(),
                                       hole_id_col=self.hole_id_cb.currentText(),
                                       dataset_col=self.dataset_cb.currentText(),
                                       x_col=self.x_col_cb.currentText(),
                                       x_end_col=self.x_end_col_cb.currentText(),
                                       schema=self.schema_cb.currentText(),
                                       y_col=self.assay_column_definition_model.get_string_map())

    def _add_combobox(self, name: str, default_val: str = None) -> QComboBox:
        """
        Add combobox and label to layout and returns created combobox

        Args:
            name: label for combobox
            default_val: default value for combobox

        Returns: created QComboBox

        """
        row_count = self.layout.rowCount()
        self.layout.addWidget(QLabel(name), row_count, 0)
        cb = QComboBox()
        cb.setEditable(True)
        if default_val:
            cb.addItem(default_val)
        self.layout.addWidget(cb, row_count, 1)
        return cb
