import copy


def apply_PI_params(model, fitted, input_matrix, output_matrix, target, exog, forecast_horizon):
    """
    Calculate custom prediction interval --> Confidence intervals are used as model parameters.
    Intervals are added to the forecast.

    Parameters
    ----------
    model : statsmodels.tsa.statespace.sarimax.SARIMAX
        The untrained model instance
    fitted : statsmodels.tsa.statespace.sarimax.SARIMAXResultsWrapper
        The fitted model instance
    input_matrix : list
        list of DataFrames for input
    output_matrix : list
        list of DataFrames for output
    target : string
        Name of target column
    exog : string
        Feature names
    forecast_horizon : int
        Number of future steps to be forecasted

    Returns
    -------
    list
        The upper interval for the given forecasts
    list
        The lower interval for the given forecasts
    """

    lower_limits = []
    upper_limits = []

    params_conf = fitted.conf_int()

    lower_params = params_conf[0]
    upper_params = params_conf[1]

    m_l = copy.deepcopy(fitted)
    m_u = copy.deepcopy(fitted)

    m_l.initialize(model=model, params=lower_params)
    m_u.initialize(model=model, params=upper_params)

    for i in range(len(input_matrix)):
        m_l = m_l.apply(input_matrix[i][target], exog = input_matrix[i][exog])
        fc_l = m_l.forecast(forecast_horizon, exog= output_matrix[i][exog])
        lower_limits.append(fc_l)

        m_u = m_u.apply(input_matrix[i][target], exog = input_matrix[i][exog])
        fc_u = m_u.forecast(forecast_horizon, exog= output_matrix[i][exog])
        upper_limits.append(fc_u)

    return upper_limits, lower_limits