import random


def data_split(df, y_col, to_drop=[], random_state=None, hold1_size=.1, hold2_size=.1, hold3_size=.1):
    """ Splits the dataframe into the train set and 3 hold-out sets.

    Drops columns to drop and the target variable from the DataFrame df. Then the rows are reshuffled and split into 4 groups: train set and 3 hold-out sets.

    Args:
        df: pandas DataFrame with the data.
        y_col: the name of the column with the target variable.
        to_drop: list of columns to drop from further analysis.
        random_state: the seed used by the random number generator.
        hold1_size: the size of the first hold-out set as a fraction of total.
        hold2_size: the size of the second hold-out set as a fraction of total.
        hold3_size: the size of the third hold-out set as a fraction of total.

    Returns:
        A tuple of length 9 containing train set, 3 hold-out sets split of inputs and a list of column labels.
    """
    df_filtered = df.drop(columns=to_drop)
    rows = list(df_filtered.index)
    if random_state is not None:
        random.seed(random_state)
    random.shuffle(rows)
    length = len(rows)
    train_rows = rows[:int(length * (1 - (hold1_size + hold2_size + hold3_size)))]
    hold1_rows = rows[int(length * (1 - (hold1_size + hold2_size + hold3_size))):int(
        length * (1 - (hold2_size + hold3_size)))]
    hold2_rows = rows[int(length * (1 - (hold1_size + hold3_size))):int(length * (1 - hold3_size))]
    hold3_rows = rows[int(length * (1 - hold3_size)):]
    X_train = df_filtered.drop(columns=[y_col]).iloc[train_rows].values
    y_train = df_filtered.loc[train_rows, y_col].values
    X_hold1 = df_filtered.drop(columns=[y_col]).iloc[hold1_rows].values
    y_hold1 = df_filtered.loc[hold1_rows, y_col].values
    X_hold2 = df_filtered.drop(columns=[y_col]).iloc[hold2_rows].values
    y_hold2 = df_filtered.loc[hold2_rows, y_col].values
    X_hold3 = df_filtered.drop(columns=[y_col]).iloc[hold3_rows].values
    y_hold3 = df_filtered.loc[hold3_rows, y_col].values
    cols = df_filtered.drop(columns=[y_col]).columns
    return X_train, y_train, X_hold1, y_hold1, X_hold2, y_hold2, X_hold3, y_hold3, cols