import numpy as np
import pandas as pd

def project_shadow(point, light_dir, plane_normal, plane_point):
    w = point - plane_point
    dist = np.dot(w, plane_normal)
    return point - dist * plane_normal

def reflect_on_mirror(shadow_point, scale):
    return shadow_point * scale

def hybrid_parallel(df, target_col, minority_class, ratio=1.0):

    features = [c for c in df.columns if c != target_col]
    minority_df = df[df[target_col] == minority_class].reset_index(drop=True)

    if minority_df.empty:
        raise ValueError("Minority class not found.")

    total_synth = int(len(minority_df) * ratio)
    if total_synth < 1:
        raise ValueError("Ratio too small.")

    X_min = minority_df[features].values

    light_dir = np.ones(len(features))
    light_dir /= np.linalg.norm(light_dir)

    plane_normal = light_dir.copy()
    plane_point = np.zeros(len(features))

    synthetic = []

    for i in range(total_synth):
        idx = np.random.randint(0, len(X_min))
        original = X_min[idx]

        shadow = project_shadow(original, light_dir, plane_normal, plane_point)
        scale = np.random.uniform(0.7, 1.3, size=len(features))
        reflected = reflect_on_mirror(shadow, scale)

        synthetic.append(
            dict({target_col: minority_class}, **dict(zip(features, reflected)))
        )

    df_synth = pd.DataFrame(synthetic)
    combined = pd.concat([df, df_synth], ignore_index=True)

    X = combined.drop(columns=[target_col])
    y = combined[target_col]

    return X, y
