# -*- coding: utf-8 -*-
"""
/***************************************************************************
 PluginExtraInfoDialog
                              -------------------
        begin                : 2021-12-20
        git sha              : $Format:%H$
        copyright            : (C) 2021 by Zuidt
        email                : richard@zuidt.nl
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
"""

import logging
import os

from qgis.PyQt import uic
from qgis.PyQt.QtCore import (
    Qt,
)
from qgis.PyQt.QtWidgets import (
    QDialog,
)

from . import LOGGER_NAME
from .ext.ndff.connector.connector import (
    NdffConnector,
)
from .ndffc_plugin_search_code_dialog import PluginSearchCodeDialog

log = logging.getLogger(LOGGER_NAME)

# This loads your .ui file so that PyQt can populate your plugin with the elements from Qt Designer
FORM_CLASS, _ = uic.loadUiType(
    os.path.join(os.path.dirname(__file__), "ndffc_plugin_extra_info_dialog_base.ui")
)


class PluginExtraInfoDialog(QDialog, FORM_CLASS):
    """
    Extra Info fields are key:value pairs to be set in the extrainfo list of an NdffObservation

    Dialog to let the user set BOTH(!) the key (NDFF code identity) and the value (either a default or the value
    for a field) for ONE ExtraInfo item
    """

    def __init__(self, parent=None):
        """
        Constructor of the dialog
        """
        super(PluginExtraInfoDialog, self).__init__(parent)
        self.setupUi(self)

        self.search_code_dlg = PluginSearchCodeDialog(parent=self)
        self.search_code_dlg.setModal(True)
        self.search_code_dlg.setWindowModality(
            Qt.WindowModality.ApplicationModal
        )  # https://doc.qt.io/qt-5/qt.html#WindowModality-enum
        self.search_code_dlg.finished.connect(self.extra_info_key_uri_search_finished)

        self.combo_layer_fields.fieldChanged.connect(self.layer_field_changed)
        self.btn_search_api.clicked.connect(self.search_key_uri)

        self.connector = None
        self.record = None
        self.field_map_key = None
        self.field_map_value = None

    def show(
        self,
        layer,
        connector: NdffConnector,
        record: dict,
        field_map_key: str = None,
        field_map_value: str = None,
    ) -> None:
        """
        This will set the GUI of the dialog AND show it.
        In this way you can reuse a dialog instance.
        """
        self.connector = connector
        self.record = record
        self.field_map_key = field_map_key
        self.field_map_value = field_map_value
        self.combo_layer_fields.setLayer(layer)
        if field_map_key and field_map_value:
            # we are EDITING a row/set in the ExtraInfo fields
            self.lbl_extra_info_key_uri.setText(
                self.connector.get_field_mapping(field_map_key)
            )
            self.combo_layer_fields.setField(
                self.connector.get_field_mapping(field_map_value)
            )
        else:
            # self.layer_field_changed(self.combo_layer_fields.currentField())
            pass
        self.showNormal()

    def search_key_uri(self):
        """
        Because only NDFF identity uri's are allowed to use as KEY for extra info, we let the user search for
        identities vai eth search code dialog (and init with 'extra_info_identity' so only
        """
        self.search_code_dlg.setup_gui(self.connector, "extra_info_identity", "")
        self.search_code_dlg.open()

    def layer_field_changed(self, data_field: str):
        """
        Setting the dropdown AND the example from data based on a field/attribute from a data record

        So observation_field here is a data attribute
        """
        # show if there is a mapping for field = SET dropdown value AND the corresponding data if a record is available
        log.debug(f"Calling layer_field_changed for data field {data_field}")
        extra_info_value = ""
        if data_field != "" and self.record and self.record[data_field]:
            extra_info_value = self.record[data_field]
        # see #53 value of extra info is potentially VERY large, limit the shown(!) chars too
        self.lbl_extra_info_value.setText(f"{extra_info_value}"[0:100])

    def extra_info_key_uri_search_finished(self):
        """
        Slot to be called after the user accepted the result of searching for a uri/identity at the NDFF for the KEY
        of the extra info item
        """
        key_uri = self.search_code_dlg.le_selected_uri.text()
        # log.debug(f' extra_info_key_uri_finished; key_uri: {key_uri} field')
        self.lbl_extra_info_key_uri.setText(key_uri)
        self.layer_field_changed(self.combo_layer_fields.currentField())

    def accept(self) -> None:
        """
        Qt Api call to accept the dialog

        Upon a successful acceptance of the content, it will add an extra info field mapping the settings
        via the NdffConnector
        """
        if self.lbl_extra_info_key_uri.text() in (
            "",
            "NDFF URI voor een Veld",
            'Selecteer een uri uit de lijst, of gebruik "Annuleer/Cancel"',
        ):
            self.lbl_extra_info_key_uri.setText(
                'Selecteer een uri uit de lijst, of gebruik "Annuleer/Cancel"'
            )
        else:
            # ADDING this as a field mapping
            # checking for uri of key is done in connector:
            if (
                self.field_map_key
                and self.field_map_value
                and self.connector.change_extra_info_field_mapping(
                    self.field_map_key,
                    self.lbl_extra_info_key_uri.text(),
                    self.field_map_value,
                    self.combo_layer_fields.currentField(),
                )
            ):
                # we just successfully EDITED an existing ExtraInfo field pair
                self.done(QDialog.DialogCode.Accepted)
            elif self.connector.add_extra_info_field_mapping(
                self.lbl_extra_info_key_uri.text(),
                self.combo_layer_fields.currentField(),
            ):
                # we just ADDED a new ExtraInfo field pair
                self.done(QDialog.DialogCode.Accepted)
            else:
                # TODO show message ??
                pass
