import pandas as pd


def build_supplier_features(df: pd.DataFrame) -> pd.DataFrame:
    if "supplier_id" not in df.columns:
        raise ValueError("Missing required column: supplier_id")

    out = df.copy()

    defaults = {
        "annual_spend": 0.0,
        "esg_score": 50.0,
        "on_time_rate": 0.85,
        "defect_rate": 0.02,
    }

    for col, default in defaults.items():
        if col not in out.columns:
            out[col] = default
        out[col] = pd.to_numeric(out[col], errors="coerce").fillna(default)

    out["late_risk"] = 1.0 - out["on_time_rate"].clip(0, 1)
    out["quality_risk"] = out["defect_rate"].clip(0, 1)
    out["esg_risk"] = 1.0 - (out["esg_score"].clip(0, 100) / 100.0)

    total_spend = max(out["annual_spend"].sum(), 1.0)
    out["spend_share"] = out["annual_spend"] / total_spend

    if "category" in out.columns:
        out["category_count"] = out.groupby("supplier_id")["category"].transform("nunique")
    else:
        out["category_count"] = 1

    features = out[
        [
            "supplier_id",
            "annual_spend",
            "late_risk",
            "quality_risk",
            "esg_risk",
            "spend_share",
            "category_count",
        ]
    ].drop_duplicates("supplier_id")

    return features.set_index("supplier_id")
