import pvlib as pv
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

def define_site(lat, long, tz, alt, name):
    location = pv.location.Location(latitude=lat,
                    longitude=long,
                    tz=tz,
                    altitude=alt,
                    name=name)
    return location
    
def define_module(celltype, pdc0, vmp, imp, voc, isc,
                  alphasc, betavoc, gammapmp, cellsinseries, tempref):
    cell_type = celltype; pdc_0 = pdc0
    v_mp = vmp; i_mp = imp
    v_oc = voc; i_sc = isc 
    alpha_sc = i_sc * alphasc; beta_voc = v_oc * betavoc; gamma_pmp = gammapmp
    cells_in_series = cellsinseries; temp_ref = tempref

    # Fit Module Parameters to CEC single diode model using SAM SDK
    single_diode_model = \
    pv.ivtools.sdm.fit_cec_sam(
        celltype = celltype,
        v_mp = v_mp,
        i_mp = i_mp,
        v_oc = v_oc,
        i_sc = i_sc,
        alpha_sc = alpha_sc,
        beta_voc = beta_voc,
        gamma_pmp = gamma_pmp,
        cells_in_series = cells_in_series,
        temp_ref = temp_ref
    )
    return single_diode_model

def define_inverter():
    return ""

def iv_curve(eff_irr, mod_temp, sde, isc, alphasc):
    i_sc = isc
    alpha_sc = i_sc * alphasc
    # Import Effective Irradiance (POA) and Cell Temperature
    # Calculates five parameters values for SDE at effective irradiance and cell temperature
    # using the CEC model.
    cec_params = pv.pvsystem.calcparams_cec(eff_irr,
                                            mod_temp,
                                            alpha_sc,
                                            sde[4], # a_ref
                                            sde[0], # I_L_ref
                                            sde[1], # I_o_ref
                                            sde[3], # R_sh_ref
                                            sde[2], # R_s
                                            sde[5], # Adjust
    )

    # Calculate I,V, and P at MPP, based on module parameters and weather conditions
    mpp = pv.pvsystem.max_power_point(*cec_params, method='newton')
    return mpp

def pv_dc(mpp, modulesperstring, stringsperinverter,surfacetilt,surfaceazimuth):
    # Scale up to PVSystem
    system = pv.pvsystem.PVSystem(modules_per_string = modulesperstring,
                                strings_per_inverter = stringsperinverter,
                                surface_tilt = surfacetilt,
                                surface_azimuth = surfaceazimuth,)
    dc_scaled = system.scale_voltage_current_power(mpp)
    return dc_scaled

if __name__ == "__main__":
    single_diode_model = define_module('monoSi',385,39.9,9.65,49.04,10.17,0.0006,-0.003,-0.37,6*12,25)
    df = pd.read_excel(r"")
    df.index = pd.to_datetime(df['Site Time'])
    poa = df['POA']
    module_temperature = df['Module Temperature']
    mpp = iv_curve(poa, module_temperature, single_diode_model, 10.17, 0.0006)
    pvlib_dc = pv_dc(mpp,26,174,20,180)

    # pvlib_dc.plot(figsize=(16,9))
    # plt.show()

    df['pvlib_dc'] = pvlib_dc['p_mp']/1000
    df[['Real Power','pvlib_dc']].plot(figsize=(16,9),ylim=(0,2500))

    plt.show()

    # Single Axis Tracking Below
    # times = pd.date_range(start='2025-02-01', end='2025-03-16',
    #                       freq='5min', tz=location.tz)
    
    # mount = pv.pvsystem.SingleAxisTrackerMount(axis_tilt=0,axis_azimuth=180,
    #                                            max_angle=60, backtrack=False)
    
    # sol_pos = location.get_solarposition()
    # orientation = mount.get_orientation(solar_zenith=sol_pos['apparent_zenith'],
    #                                     solar_azmith=sol_pos['azimuth'])
    # orientation['tracker_theta'].fillna(0)

    # array = Array(mount=mount, module_parameters=module, temperature_model_parameters=temperature_parameters,
    #               modules_per_string=modules_per_string, strings=strings_per_inverter)
    
    # system = pv.pvsystem.PVSystem(arrays=[array],inverter_parameters=inverter)