import os
import processing

from qgis.core import (QgsVectorLayer,QgsField,QgsFields,QgsFeature,QgsGeometry,QgsPointXY,QgsProject)

import pandapipes as pp
import pandas as pd

try:
    import xlsxwriter
    excel_available = True
except:
    excel_available = False

def get_fluid_parameter(parameter,chosen_fluid,temperature,pressure):
    pres = float(pressure)
    temp = float(temperature)

    fluid_properties = []

    available_fluids = ["hgas","lgas","hydrogen","methane","water","biomethane_pure","biomethane_treated","air"]

    if chosen_fluid not in available_fluids:
        script_dir = os.path.dirname(os.path.dirname(os.path.dirname(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)
        
        chosen_fluid_name = chosen_fluid.replace(' [USER DEFINED]',"")
        
        print(chosen_fluid_name)
        
        chosen_fluid = pp.create_constant_fluid(
                                            name=chosen_fluid_name,
                                            fluid_type = user_fluids_df.loc[user_fluids_df['name'] == chosen_fluid_name, "fluid_type"].iloc[0],
                                            compressibility=user_fluids_df.loc[user_fluids_df['name'] == chosen_fluid_name, "compressibility"].iloc[0],
                                            density=user_fluids_df.loc[user_fluids_df['name'] == chosen_fluid_name, "density"].iloc[0],
                                            heat_capacity=user_fluids_df.loc[user_fluids_df['name'] == chosen_fluid_name, "heat_capacity"].iloc[0],
                                            molar_mass=user_fluids_df.loc[user_fluids_df['name'] == chosen_fluid_name, "molar_mass"].iloc[0],
                                            viscosity=user_fluids_df.loc[user_fluids_df['name'] == chosen_fluid_name, "viscosity"].iloc[0],
                                            is_gas=user_fluids_df.loc[user_fluids_df['name'] == chosen_fluid_name, "is_gas"].iloc[0]
                                        )

    net = pp.create_empty_network(fluid=chosen_fluid)
    
    if parameter == 'compressibility':
        value = net.fluid.get_compressibility(pres)
        
    elif parameter == 'density':
        value = net.fluid.get_density(temp)
        
    elif parameter == 'heat_capacity':
        value = net.fluid.get_heat_capacity(temp)
        
    elif parameter == 'molar_mass':
        value = net.fluid.get_molar_mass()
        
    elif parameter == 'viscosity':
        value = net.fluid.get_viscosity(temp)
        
    else:
        print('Parameter not available. Check spelling.')
        return
    
    return value

def add_fluid_params_to_layer(layer,chosen_fluid,parameter,temperature,pressure,add_fluid):
    
    parameter_value = get_fluid_parameter(parameter=parameter,
                                          chosen_fluid=chosen_fluid,
                                          temperature=temperature,
                                          pressure=pressure)

    if add_fluid:
        print(chosen_fluid)
    
        layer = processing.run("native:fieldcalculator", 
                                        {'INPUT':layer,
                                         'FIELD_NAME':'fluid',
                                         'FIELD_TYPE':2, #text
                                         'FIELD_LENGTH':0,
                                         'FIELD_PRECISION':0,
                                         'FORMULA':f'\'{chosen_fluid}\'',
                                         'OUTPUT':'memory:'})['OUTPUT']

    parameter_added = processing.run("native:fieldcalculator", 
                                            {'INPUT':layer,
                                             'FIELD_NAME':parameter,
                                             'FIELD_TYPE':0, #decimal
                                             'FIELD_LENGTH':0,
                                             'FIELD_PRECISION':0,
                                             'FORMULA':f'{parameter_value}',
                                             'OUTPUT':'memory:'})['OUTPUT']

    parameter_added.setName(f'{parameter.capitalize()} Added')
    
    return parameter_added

