# -*- coding: utf-8 -*-
"""
Created on Fri Jul 26 10:57:15 2024
wrapper to call ht-database and pressure loss

@author: welp
"""

import carbatpy as cb
import numpy as np
from .two_phase_correlations import (
    DengHTC, MQTPressureDrop, MacdonaldPressureDrop, FangPressureDrop,
)
from .one_phase_correlations import VDIHeatTransfer, VDIPressureLoss

fluidmodel = 'TREND'

def get_correct_trans_string(fluid):
    DEFAULTS = cb.CB_DEFAULTS
    if fluid.props == 'TREND':
        thermo = DEFAULTS["Fluid_Defaults"]['THERMO_TREND']
        trans = DEFAULTS["Fluid_Defaults"]['TRANS_TREND_MIX']

    elif fluid.props == 'REFPROP':      
        thermo = DEFAULTS["Fluid_Defaults"]['THERMO_TREND']
        trans = DEFAULTS["Fluid_Defaults"]['TRANS_STRING']

    return thermo, trans


def calc_alpha_dpdl_tube(fluid, fluidstate, mdot, l, d_big, d_small=0, pl_method='Macdonald_et_al-2016', dT_wall=5, ht_method='Deng_et_al-2019', CT='HC'):
    """
    heat transfer coefficient and pressure drop for working fluid, changes
    automatically to 1phase if necessary.

    Parameters
    ----------
    fluid : TYPE
        DESCRIPTION.
    fluidstate : TYPE
        DESCRIPTION.
    mdot : TYPE
        DESCRIPTION. mass flow rate [kg/s]
    method : TYPE
        DESCRIPTION. Nusselt correlation as in ht database or constant
    l : TYPE
        DESCRIPTION. length of tube (only used for flow field as reference 
                                     length) [m]
    d_big : TYPE
        DESCRIPTION. diameter [m]
        
    U_i : TYPE, optional
        DESCRIPTION. The default is 0. please set, if constant U shall be used

    Returns
    -------
    alpha_KM : TYPE
        DESCRIPTION. heat transfer coefficient [W/(m^2*K)]
    dp_wf : TYPE
        DESCRIPTION. differential pressure loss [Pa/m]

    """
    thermo, trans = get_correct_trans_string(fluid)

    if 0 < fluidstate.quality < 1:#
        G = mdot / (np.pi * d_big ** 2 * 0.25)

        alpha_KM = calc_2P_heat_transfer(ht_method, mdot, fluidstate, fluid, d_big, dT_wall, CT)
        dp_wf = calc_2P_pressure_loss(pl_method, d_big, G, fluidstate, fluid, mdot, heat_transfer_rate=None, eps=1e-5)

    else:
        # if refrigerant in 1phasestate, mdot, l, d_big, d_small=0
        fluidstate = fluid.set_state([fluidstate.temperature, fluidstate.pressure],
                                     "TP", trans, output="FluidState")
        alpha_KM = VDIHeatTransfer(fluid, fluidstate, mdot, l, d_big, d_small).calc()["alpha"]
        dp_wf    = VDIPressureLoss(fluid, fluidstate, mdot, l, d_big, d_small).calc()["dpdl"]

    if np.isnan(alpha_KM):
        raise ValueError("error in alpha_wf: nan value detected")

    if np.iscomplexobj(alpha_KM):
        raise ValueError("error in alpha_wf: complex value detected")
    if np.isnan(dp_wf):
        raise ValueError("error in dpwf: nan value detected")
    return float(alpha_KM) , float(dp_wf)


def calc_2P_pressure_loss(pl_method, d_big, G, state, fluid, mdot, heat_transfer_rate=None, eps=1e-5):
    if pl_method == "Macdonald_et_al-2016":
        pr_loss = MacdonaldPressureDrop(d_big, G, state, fluid)
    elif pl_method == "Moreno_Quiben_Thome-2007":
        pr_loss = MQTPressureDrop(d_big, G, state, fluid)
    elif pl_method == "Fang_et_al-2019":
        pr_loss = FangPressureDrop(state, fluid, mdot, d_big)
    else:
        raise ValueError(f"pl_method {pl_method} not implemented.")
    return pr_loss.calc()["dpdl"]


def calc_2P_heat_transfer(ht_method, mdot, fluidstate, fluid, d_big, dT_wall, CT):
    thermo, trans = get_correct_trans_string(fluid)

    if fluid.props == 'TREND':
        sigma = fluid.set_state([fluidstate.pressure, 0], "PQ", thermo
                                + ['ST'])[-1]
        if sigma <= 0:
            print("Warning: surface tension not correcly calculated.")

    elif fluid.props == 'REFPROP':
        sigma = fluid.set_state([fluidstate.pressure, 0], "PQ", 'STN')

    G = mdot / (np.pi * d_big ** 2 * 0.25)
    T_wall = fluidstate.temperature - dT_wall

    if ht_method == "Deng_et_al-2019":
        ht_deng = DengHTC(d_big, G, T_wall, CT, fluidstate, fluid)
        alpha_KM = ht_deng.calc()["alpha"]

    else:
        raise ValueError(f"method {ht_method} for heat transfer not implemented")
    return alpha_KM


