# coding=UTF-8

import os

from PyQt5.QtWidgets import QDialog
from PyQt5 import uic

from qgis.core import QgsProject, QgsMapLayer

from .config import PlotConfig
from .qgeologis.units import AVAILABLE_UNITS

DEFAULT_PLOT_SIZE = 150


class ConfigCreateDialog(QDialog):
    def __init__(self, parent, timeseries=False):
        """ ConfigCreateDialog is used to add a new log configuration

        :param timeseries: true if times series log
        :param timeseries: bool"""
        super().__init__(parent)

        uic.loadUi(os.path.join(os.path.dirname(__file__), "config_create_dialog.ui"), self)
        self.timeseries = timeseries
        if timeseries:
            types = [
                self.tr("Instantaneous temporal measures"),
                self.tr("Cumulative temporal measures"),
            ]
        else:
            types = [
                self.tr("Instantaneous log measures"),
                self.tr("Cumulative log measures"),
                self.tr("Continuous log measures"),
                self.tr("Stratigraphic measures"),
            ]

        self._uom_type_instantaneous_cb.currentTextChanged.connect(self.__on_unit_type_changed)
        self._uom_type_cumulative_cb.currentTextChanged.connect(self.__on_unit_type_changed)
        self._uom_type_continuous_cb.currentTextChanged.connect(self.__on_unit_type_changed)

        self._type.addItems(types)
        self._type.currentIndexChanged.connect(self.__on_type_changed)
        self.__on_type_changed(0)

        self._source.currentIndexChanged.connect(self._on_source_changed)
        for layer in QgsProject.instance().mapLayers().values():
            if layer.type() == QgsMapLayer.VectorLayer:
                self._source.addItem(layer.name(), layer)

        style_dir = os.path.join(os.path.dirname(__file__), "qgeologis", "styles")
        self._style_file.addItems([f for f in os.listdir(style_dir) if f[-4:] == ".xml"])

    def available_units(self):
        return {
            self.tr("-"): "-",
            self.tr("Debit"): "m3/s",
            self.tr("Volume"): "m³",
            self.tr("Length"): "m",
            self.tr("Weight"): "g",
            self.tr("Torque"): "N.m",
            self.tr("Pressure"): "Pa",
            self.tr("Temperature"): "°C",
            self.tr("Radioactivity"): "Bq/kg",
            self.tr("Speed"): "m/s",
            self.tr("pH"): "pH",
            self.tr("Conductivity"): "S/m",
        }

    def __on_type_changed(self, index):
        """ Triggered on log type combobox change

        :param index: log type combobox index
        :type index: int
        """
        self._type_widgets.setCurrentIndex(index)
        for column_field in [
            self._uom_type_instantaneous_cb,
            self._uom_type_cumulative_cb,
            self._uom_type_continuous_cb,
        ]:
            column_field.clear()
            column_field.addItems(self.available_units().keys())
            column_field.setCurrentText("-")

    def __on_unit_type_changed(self, text):
        if text != "":
            for column_field in [
                self._uom_instantaneous_cb,
                self._uom_cumulative_cb,
                self._uom_continuous_cb,
            ]:
                column_field.clear()
                column_field.addItems(AVAILABLE_UNITS[self.available_units()[text]])
                if text == "-":
                    column_field.setEditable(True)
                else:
                    column_field.setEditable(False)
                column_field.setCurrentText(self.available_units()[text])

    def _on_source_changed(self, index):
        """ Triggered on type change, fill form with layer field

        :param index: page index
        :type index: int
        """
        layer = self._source.itemData(index)

        for column_field in [
            self._feature_ref_column,
            self._depth_from_column,
            self._depth_to_column,
            self._start_measure_column,
            self._interval_column,
            self._value_continuous_column,
            self._event_column,
            self._value_instantaneous_column,
            self._start_cumulative_column,
            self._end_cumulative_column,
            self._value_cumulative_column,
            self._cat_cumulative_column,
        ]:
            column_field.clear()
            column_field.addItems(layer.fields().names())

        for column_field in [
            self._cat_instantaneous_column,
            self._cat_cumulative_column,
            self._uncertainty_instantaneous_column,
            self._uncertainty_cumulative_column,
            self._uncertainty_continuous_column,
        ]:
            column_field.clear()
            column_field.addItem("None")
            column_field.addItems(layer.fields().names())

        for column_field in [
            self._formation_code_column,
            self._rock_code_column,
            self._formation_description_column,
            self._rock_description_column,
        ]:
            column_field.clear()
            column_field.addItems([""] + layer.fields().names())

        for column_field in [
            self._uom_type_instantaneous_cb,
            self._uom_type_cumulative_cb,
            self._uom_type_continuous_cb,
        ]:
            column_field.clear()
            column_field.addItems(self.available_units().keys())
            column_field.setCurrentText("-")

    def config(self):
        """ Return configuration from dialog

        :return: configuration
        :rtype: dict
        """
        config = None
        # instantaneous measures
        if self._type.currentIndex() == 0:
            config = {
                "event_column": self._event_column.currentText(),
                "value_column": self._value_instantaneous_column.currentText(),
                "uom": self._uom_instantaneous_cb.currentText(),
                "displayed_uom": self._uom_instantaneous_cb.currentText(),
                "type": "instantaneous",
                "uncertainty_column": self._uncertainty_instantaneous_column.currentText()
                if self._uncertainty_instantaneous_column.currentText() != "None"
                else None,
                "scale_type": "log" if self._log_instantaneous.isChecked() else "linear",
                "min": self._instantaneous_min.text()
                if self._instantaneous_min.isEnabled()
                else None,
                "max": self._instantaneous_max.text()
                if self._instantaneous_max.isEnabled()
                else None,
                "display": "1",
                "displayed_cat": [],
                "plot_size": DEFAULT_PLOT_SIZE,
                "stacked": {},
            }
            if self._cat_instantaneous_column.currentText() != "None":
                config["display"] = "0"
                config["feature_filter_type"] = "unique_data_from_values"
                config["feature_filter_column"] = self._cat_instantaneous_column.currentText()
            else:
                config["feature_filter_type"] = "None"

        # cumulative measures
        elif self._type.currentIndex() == 1:
            config = {
                "uom": self._uom_cumulative_cb.currentText(),
                "displayed_uom": self._uom_cumulative_cb.currentText(),
                "type": "cumulative",
                "min_event_column": self._start_cumulative_column.currentText(),
                "max_event_column": self._end_cumulative_column.currentText(),
                "value_column": self._value_cumulative_column.currentText(),
                "uncertainty_column": self._uncertainty_cumulative_column.currentText()
                if self._uncertainty_cumulative_column.currentText() != "None"
                else None,
                "scale_type": "log" if self._log_cumulative.isChecked() else "linear",
                "min": self._cumulative_min.text() if self._cumulative_min.isEnabled() else None,
                "max": self._cumulative_max.text() if self._cumulative_max.isEnabled() else None,
                "display": "1",
                "displayed_cat": [],
                "plot_size": DEFAULT_PLOT_SIZE,
                "stacked": {},
            }
            if self._cat_cumulative_column.currentText() != "None":
                config["display"] = "0"
                config["feature_filter_type"] = "unique_data_from_values"
                config["feature_filter_column"] = self._cat_cumulative_column.currentText()
            else:
                config["feature_filter_type"] = "None"

        # continuous measure (only for logs)
        elif self._type.currentIndex() == 2:
            config = {
                "start_measure_column": self._start_measure_column.currentText(),
                "interval_column": self._interval_column.currentText(),
                "values_column": self._value_continuous_column.currentText(),
                "feature_filter_type": "None",
                "uom": self._uom_continuous_cb.currentText(),
                "displayed_uom": self._uom_continuous_cb.currentText(),
                "type": "continuous",
                "scale_type": "log" if self._log_continuous.isChecked() else "linear",
                "uncertainty_column": self._uncertainty_continuous_column.currentText()
                if self._uncertainty_continuous_column.currentText() != "None"
                else None,
                "min": self._continuous_min.text() if self._continuous_min.isEnabled() else None,
                "max": self._continuous_max.text() if self._continuous_max.isEnabled() else None,
                "display": "1",
                "displayed_cat": [],
                "plot_size": DEFAULT_PLOT_SIZE,
                "stacked": {},
            }

        # Stratigraphy (only for logs)
        if self._type.currentIndex() == 3:
            config = {
                "type": "stratigraphic",
                "depth_from_column": self._depth_from_column.currentText(),
                "depth_to_column": self._depth_to_column.currentText(),
                "formation_code_column": self._formation_code_column.currentText() or None,
                "rock_code_column": self._rock_code_column.currentText() or None,
                "formation_description_column": self._formation_description_column.currentText()
                or None,
                "rock_description_column": self._rock_description_column.currentText() or None,
                "feature_filter_type": "None",
                "style": self._style_file.currentText(),
                "display": "1",
                "plot_size": DEFAULT_PLOT_SIZE,
                "stacked": {},
            }

        config["source"] = self._source.itemData(self._source.currentIndex()).id()
        config["feature_ref_column"] = self._feature_ref_column.currentText()
        config["name"] = self._name.text()

        if self.timeseries:
            section = "timeseries"
        else:
            section = ["log_measures", "log_measures", "log_measures", "stratigraphy_config"][
                self._type.currentIndex()
            ]
        return (section, PlotConfig(config))
