# -*- coding: utf-8 -*-
"""
/***************************************************************************
 PandaPipesForQGISDockWidget
                                 A QGIS plugin
 An interface between the open source fluid modelling tool, Panda Pipes and QGIS.
 Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
                             -------------------
        begin                : 2025-05-26
        git sha              : $Format:%H$
        copyright            : (C) 2025 by Thomas Raj
        email                : lemungineer@gmail.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 os

from qgis.PyQt import QtGui, QtWidgets, uic
from qgis.PyQt.QtCore import pyqtSignal
from qgis.PyQt.QtCore import QAbstractTableModel, Qt

import pandas as pd
import numpy as np

from qgis.core import (QgsVectorLayer,QgsField,QgsFields,QgsFeature,QgsGeometry,QgsPointXY,QgsProject)
from PyQt5.QtCore import QVariant
from qgis.core import QgsEditorWidgetSetup, QgsProject
from qgis.core import QgsProcessingFeatureSourceDefinition, QgsProject, QgsFeatureRequest, QgsVectorLayer, QgsMapLayerProxyModel, QgsMapLayer
from PyQt5.QtWidgets import QHeaderView
from PyQt5.QtWidgets import QTreeWidgetItem, QDialog, QMessageBox
from PyQt5.QtCore import QCoreApplication
from qgis.gui import QgsFileWidget
import processing

#matplotlib backend
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt5agg import (NavigationToolbar2QT as NavigationToolbar)

from PyQt5.QtWidgets import QVBoxLayout

#importing logic files
from .fluids.fluid_properties import *

import pandapipes as pp

FORM_CLASS, _ = uic.loadUiType(os.path.join(
    os.path.dirname(__file__), 'fluids_dialog_base.ui'))

#Creating table window
class TableModel(QAbstractTableModel):
    def __init__(self,data):
        super().__init__()
        self._data = data

    def data(self, index, role):
        if role == Qt.DisplayRole:
            value = self._data.iloc[index.row(), index.column()]
            return str(value)
    
    def rowCount(self, index):
        return self._data.shape[0]
    
    def columnCount(self, index):
        return self._data.shape[1]
    
    def headerData(self, section, orientation, role):
        if role == Qt.DisplayRole:
            if orientation == Qt.Horizontal:
                return str(self._data.columns[section])
            
            if orientation == Qt.Vertical:
                return(self._data.index[section])

class FluidsDialog(QDialog, FORM_CLASS):
    def __init__(self, parent=None):
        super(FluidsDialog, self).__init__(parent)
        self.setupUi(self)  # Load the UI components
    
        # Combo Boxes
        # Fluid Combo Box
        available_fluids = ["hgas","lgas","hydrogen","methane","water","biomethane_pure","biomethane_treated","air"]

        script_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
        user_fluids_path = os.path.join(script_dir, 'user_settings','user_fluids.csv')

        print(user_fluids_path)

        user_fluids_df = pd.read_csv(user_fluids_path)
        
        user_fluids_list = user_fluids_df['name'].tolist()
        
        self.cmbUserFluids.addItems(user_fluids_list)
        
        for entry in user_fluids_list:
            
            user_entry = entry + ' [USER DEFINED]'
            
            available_fluids.append(user_entry)
        
        
        self.cmbFluid.addItems(available_fluids)
        self.cmbFluid.currentIndexChanged.connect(self.update_fluid_table_contents)
        self.cmbFluid.setCurrentText('methane')

        # Default Pressure and Temperature
        self.leFluidName.setText('methane_treated')
        self.leFluidType.setText('gas')
        
        self.dsbFluidPressure.setValue(1)
        self.dsbFluidPressure.valueChanged.connect(self.update_fluid_table_contents)
        
        self.dsbTempK.setMaximum(100000)
        self.dsbTempK.setValue(293.15)
        self.dsbTempK.valueChanged.connect(self.update_fluid_table_contents)

        self.dsbHeatCap.setDecimals(6)
        self.dsbHeatCap.setMaximum(1000000)
        self.dsbHeatCap.setValue(1)
        
        self.dsbDensity.setDecimals(6)
        self.dsbDensity.setMaximum(1000000)
        self.dsbDensity.setValue(1)
        
        self.dsbCompresibility.setDecimals(6)
        self.dsbCompresibility.setMaximum(1)
        self.dsbCompresibility.setValue(1)
        
        self.dsbMolarMass.setDecimals(6)
        self.dsbMolarMass.setMaximum(1000000)
        self.dsbMolarMass.setValue(16.04)
        
        self.dsbViscosity.setDecimals(6)
        self.dsbViscosity.setMaximum(10000)
        self.dsbViscosity.setValue(0.00002)
        
        self.cbIsGas.setChecked(True)

        
        # Create New Fluid Dialog
        
        self.pbCreateFluid.clicked.connect(self.create_fluid)
        
        # Remove Fluid
        self.pbRemoveFluid.clicked.connect(self.remove_fluid)

    def update_fluid_table_contents(self):
        chosen_fluid = self.cmbFluid.currentText()
        pressure = self.dsbFluidPressure.value()
        temperature = self.dsbTempK.value()

        try:
            df = get_fluid_properties(chosen_fluid,temperature,pressure)
            model = TableModel(df)
            self.twFluidProperties.setModel(model)
        except:
            QMessageBox.warning(
                window,
                "Warning",
                "Fluid is not selected"
            )
        # Make columns stretch to fill the horizontal space
        self.twFluidProperties.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
    
    def create_fluid(self):
        
        script_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
        user_fluids_path = os.path.join(script_dir, 'user_settings','user_fluids.csv')
        user_fluids_df = pd.read_csv(user_fluids_path)
        
        fluid_name = self.leFluidName.text()
        fluid_type = self.leFluidType.text()
        compressibility = self.dsbCompresibility.value()
        density = self.dsbDensity.value()
        heat_capacity = self.dsbHeatCap.value()
        molar_mass = self.dsbMolarMass.value()
        viscosity = self.dsbViscosity.value()
        is_gas = self.cbIsGas.isChecked()
        
        user_fluid_df = pd.DataFrame( 
                                        {
                                            "name": [fluid_name],
                                            "fluid_type": [fluid_type],
                                            "compressibility": [compressibility],
                                            "density": [density],
                                            "heat_capacity": [heat_capacity],
                                            "molar_mass": [molar_mass],
                                            "viscosity": [viscosity],
                                            "is_gas": [is_gas]
                                        }
                                    )
    
        print(user_fluid_df)
    
        user_fluids_df = pd.concat([user_fluids_df,user_fluid_df],ignore_index = True)
        
        user_fluids_df.to_csv(user_fluids_path,index=False)

        user_entry = fluid_name + ' [USER DEFINED]'
            
        self.cmbFluid.addItems([user_entry])
        
        self.cmbUserFluids.addItems([fluid_name])
    
    def remove_fluid(self):
        
        fluid_to_remove = self.cmbUserFluids.currentText()
        
        script_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
        user_fluids_path = os.path.join(script_dir, 'user_settings','user_fluids.csv')
        user_fluids_df = pd.read_csv(user_fluids_path)
        
        user_fluids_df = user_fluids_df[user_fluids_df['name'] != fluid_to_remove]
        
        user_fluids_df.to_csv(user_fluids_path,index=False)
        
        user_fluids_list = user_fluids_df['name'].tolist()
        
        self.cmbUserFluids.clear()
        self.cmbUserFluids.addItems(user_fluids_list)
        
        self.cmbFluid.clear()
        
        available_fluids = ["hgas","lgas","hydrogen","methane","water","biomethane_pure","biomethane_treated","air"]
        
        for entry in user_fluids_list:
            
            user_entry = entry + ' [USER DEFINED]'
            
            available_fluids.append(user_entry)
        
        
        self.cmbFluid.addItems(available_fluids)