'''
/***************************************************************************
Name	   :  crops_controller.py
Description:  crops controller class for FEWSTools plugin
copyright  :  (C) 2022-2023 by FEWS
email      :  jhowton@contractor.usgs.gov
Created    :  05/12/2022
Modified   :  Date - Name - Changes Made

 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/
'''

from PyQt5.QtWidgets import QMessageBox, QDialog
from fews_tools.utilities import geoclim_utilities as util
from fews_tools.controllers.new_name_controller import NewNameController

from fews_tools.forms.Ui_CropDefinition import Ui_CropDefinition

from fews_tools.models.crops_model import CropsModel
from fews_tools.controllers.import_crop_controller import ImportCrop


class CropsController(QDialog):
    '''
    Class for crops controller
    '''

    def __init__(self):
        QDialog.__init__(self)
        self.ui = Ui_CropDefinition()
        self.ui.setupUi(self)

        self.crops_info = CropsModel()

        # get a list to hold widget values
        self.widget_val_list = [''] * 14

        # Track if anything has changed to enable save button
        self.ui.defaultCropComboBox.currentIndexChanged['QString'].connect(
            self.save_enabled)
        self.ui.commentLineEdit.textChanged.connect(self.save_enabled)
        self.ui.f1SpinBox.valueChanged.connect(self.save_enabled)
        self.ui.f2SpinBox.valueChanged.connect(self.save_enabled)
        self.ui.f3SpinBox.valueChanged.connect(self.save_enabled)
        self.ui.kc_iniSpinBox.valueChanged.connect(self.save_enabled)
        self.ui.kc_midSpinBox.valueChanged.connect(self.save_enabled)
        self.ui.kc_endSpinBox.valueChanged.connect(self.save_enabled)
        self.ui.maxRootSpinBox.valueChanged.connect(self.save_enabled)
        self.ui.iniRootSpinBox.valueChanged.connect(self.save_enabled)
        self.ui.maxDepletionSpinBox.valueChanged.connect(self.save_enabled)
        self.ui.crop_c1SpinBox.valueChanged.connect(self.save_enabled)
        self.ui.crop_c2SpinBox.valueChanged.connect(self.save_enabled)

        # connect remaining widgets
        self.ui.cropNameComboBox.currentIndexChanged['QString'].connect(
            self.crop_selection_changed)
        self.ui.newCropButton.clicked.connect(self.new_crop)
        self.ui.deleteCropButton.clicked.connect(self.delete_crop)
        self.ui.saveButton.clicked.connect(self.save_crop)
        self.ui.copyCropButton.clicked.connect(self.copy_crop)
        self.ui.importCropButton.clicked.connect(self.import_crop)

        self.__initial_form_load__()

    def __initial_form_load__(self):
        '''
        Fills the form entries initial load
        '''
        util.fill_misc_widget(self.ui.defaultCropComboBox, ['No', 'Yes'])
        util.fill_crop_combo(self.ui.cropNameComboBox)

        # Disable the save button until something changes
        self.ui.saveButton.setEnabled(False)

    def crop_selection_changed(self):
        '''
        Function to update form widgets when crop selection changes.
        '''
        # use the name to set crops object data structure vals
        self.crops_info.query_named_crop(
            self.ui.cropNameComboBox.currentText())
        # get the values for use here
        crop_dic = self.crops_info.get_crop_dictionary()

        # from here must map between dictionary and the widget vals
        self.ui.commentLineEdit.setText(crop_dic['Comments'])
        self.ui.f1SpinBox.setValue(crop_dic['F1'])
        self.ui.f2SpinBox.setValue(crop_dic['F2'])
        self.ui.f3SpinBox.setValue(crop_dic['F3'])
        self.ui.kc_iniSpinBox.setValue(crop_dic['K1'])
        self.ui.kc_midSpinBox.setValue(crop_dic['K2'])
        self.ui.kc_endSpinBox.setValue(crop_dic['K3'])
        self.ui.maxRootSpinBox.setValue(crop_dic['Root'])
        self.ui.iniRootSpinBox.setValue(crop_dic['RootIni'])
        self.ui.maxDepletionSpinBox.setValue(crop_dic['KP'])
        self.ui.crop_c1SpinBox.setValue(crop_dic['C1'])
        self.ui.crop_c2SpinBox.setValue(crop_dic['C2'])

        # Disable save until something is changed.
        self.ui.saveButton.setEnabled(False)

        if crop_dic['DefaultCrop'] == "Yes":
            self.ui.defaultCropComboBox.setCurrentIndex(
                self.ui.defaultCropComboBox.findText("Yes"))
        else:
            self.ui.defaultCropComboBox.setCurrentIndex(
                self.ui.defaultCropComboBox.findText("No"))

    def new_crop(self):
        '''
        Function to create a new crop from a reset form.
        '''
        new_crop_name_dlg = NewNameController('Crop')
        new_crop_name_dlg.exec_()
        new_crop_name = new_crop_name_dlg.get_new_name()

        if new_crop_name:
            err = self.__check_new_name__(new_crop_name)
            if err is False:
                reply = QMessageBox.question(
                    self,
                    'New default crop?',
                    'Do you want to set this as the default crop?',
                    QMessageBox.Yes, QMessageBox.No)

                self.ui.cropNameComboBox.addItem(new_crop_name)
                self.ui.cropNameComboBox.setCurrentIndex(
                    self.ui.cropNameComboBox.count() - 1)
                if reply == QMessageBox.Yes:
                    self.ui.defaultCropComboBox.setCurrentIndex(
                        self.ui.defaultCropComboBox.findText("Yes"))
                else:
                    self.ui.defaultCropComboBox.setCurrentIndex(
                        self.ui.defaultCropComboBox.findText("No"))

                self.ui.commentLineEdit.setText("")
                self.ui.f1SpinBox.setValue(0)
                self.ui.f2SpinBox.setValue(0)
                self.ui.f3SpinBox.setValue(0)
                self.ui.kc_iniSpinBox.setValue(0)
                self.ui.kc_midSpinBox.setValue(0)
                self.ui.kc_endSpinBox.setValue(0)
                self.ui.maxRootSpinBox.setValue(0)
                self.ui.iniRootSpinBox.setValue(0)
                self.ui.maxDepletionSpinBox.setValue(0)
                self.ui.crop_c1SpinBox.setValue(0)
                self.ui.crop_c2SpinBox.setValue(0)

    def copy_crop(self):
        '''
        Function to create a new crop from the current crop.
        '''
        new_crop_name_dlg = NewNameController('Crop')
        new_crop_name_dlg.exec_()
        new_crop_name = new_crop_name_dlg.get_new_name()

        if new_crop_name:
            err = self.__check_new_name__(new_crop_name)
            if err is False:
                reply = QMessageBox.question(
                    self,
                    'New default crop?',
                    'Do you want to set this as the default crop?',
                    QMessageBox.Yes, QMessageBox.No)

                self.ui.cropNameComboBox.addItem(new_crop_name)
                self.ui.cropNameComboBox.setCurrentIndex(
                    self.ui.cropNameComboBox.count() - 1)
                if reply == QMessageBox.Yes:
                    self.ui.defaultCropComboBox.setCurrentIndex(
                        self.ui.defaultCropComboBox.findText("Yes"))
                else:
                    self.ui.defaultCropComboBox.setCurrentIndex(
                        self.ui.defaultCropComboBox.findText("No"))

    def __check_new_name__(self, new_name):
        '''
        Check if name exists return err if yes
        :param new_name(string) - New name
        :return err(boolean) - True if name already exists, else False
        '''
        err = False
        crop_name_list = self.crops_info.get_all_crop_names()
        if new_name in crop_name_list or \
                self.ui.cropNameComboBox.findText(new_name) != -1:
            err = True
            QMessageBox.critical(
                self, 'Error - Name already exists',
                'The selected name already exists in the database.',
                QMessageBox.Ok)
        return err

    def delete_crop(self):
        '''
        Delete selected crop from the database.
        '''
        crop_name = self.ui.cropNameComboBox.currentText()
        reply = QMessageBox.question(
            self,
            'Delete crop?',
            'Are you sure you want to delete the ' + crop_name + ' crop?\n '
            'This cannot be undone.',
            QMessageBox.Yes, QMessageBox.Cancel)

        if reply == QMessageBox.Yes:
            self.crops_info.delete_crop_record(crop_name)
            # need to fix the combo box
            self.ui.cropNameComboBox.removeItem(
                self.ui.cropNameComboBox.findText(crop_name))
            # reload the form
            default_crop = self.crops_info.query_default_crop_name()
            self.ui.cropNameComboBox.setCurrentIndex(
                self.ui.cropNameComboBox.findText(default_crop))

    def save_crop(self):
        '''
        Update crop database using widget selections.
        '''

        self.set_widget_val_list()
        self.crops_info.write_crop_record(self.widget_val_list)
        self.ui.saveButton.setEnabled(False)

    def set_widget_val_list(self):
        '''
        Get the widget values into a list
        '''
        self.widget_val_list =\
            [self.ui.cropNameComboBox.currentText(),
             self.ui.f1SpinBox.value(),
             self.ui.f2SpinBox.value(),
             self.ui.f3SpinBox.value(),
             self.ui.kc_iniSpinBox.value(),
             self.ui.kc_midSpinBox.value(),
             self.ui.kc_endSpinBox.value(),
             self.ui.maxRootSpinBox.value(),
             self.ui.iniRootSpinBox.value(),
             self.ui.maxDepletionSpinBox.value(),
             self.ui.crop_c1SpinBox.value(),
             self.ui.crop_c2SpinBox.value(),
             self.ui.defaultCropComboBox.currentText(),
             self.ui.commentLineEdit.text()]

    def save_enabled(self):
        '''
        Enable the save button. To save unnecessary writes to the
        database, the button should only be enabled if something has changed
        on the form.
        '''
        self.ui.saveButton.setEnabled(True)

    def import_crop(self):
        '''
        Import a crop
        '''
        ImportCrop()
