import numpy as np


def group_metrics(y_true, y_pred, group, group_label):
    mask = group == group_label
    y_t, y_p = y_true[mask], y_pred[mask]
    positive_rate = y_p.mean()

    positives = y_t == 1
    negatives = y_t == 0
    tpr = y_p[positives].mean() if positives.sum() > 0 else float("nan")
    fpr = y_p[negatives].mean() if negatives.sum() > 0 else float("nan")

    return {
        "n": mask.sum(),
        "positive_rate": positive_rate,
        "true_positive_rate": tpr,
        "false_positive_rate": fpr,
        "base_rate": y_t.mean(),
    }


def fairness_audit(y_true, y_pred, group):
    labels = np.unique(group)
    results = {g: group_metrics(y_true, y_pred, group, g) for g in labels}

    print(f"{'Group':<10}{'N':<8}{'BaseRate':<12}{'PredPosRate':<14}"
          f"{'TPR':<10}{'FPR':<10}")
    for g, m in results.items():
        print(
            f"{str(g):<10}{m['n']:<8}{m['base_rate']:<12.3f}"
            f"{m['positive_rate']:<14.3f}{m['true_positive_rate']:<10.3f}"
            f"{m['false_positive_rate']:<10.3f}"
        )

    groups = list(results.keys())
    if len(groups) == 2:
        g1, g2 = groups
        dp_gap = abs(
            results[g1]["positive_rate"] - results[g2]["positive_rate"]
        )
        eo_gap = abs(
            results[g1]["true_positive_rate"]
            - results[g2]["true_positive_rate"]
        )
        print(f"\nDemographic parity gap: {dp_gap:.3f}")
        print(f"Equalized odds (TPR) gap: {eo_gap:.3f}")

    return results
