import math

SERVICE_LEVEL_TO_Z = {
    0.90: 1.28,
    0.95: 1.64,
    0.975: 1.96,
    0.99: 2.33,
}


def get_z_for_service_level(service_level: float) -> float:
    if service_level in SERVICE_LEVEL_TO_Z:
        return SERVICE_LEVEL_TO_Z[service_level]
    closest = min(SERVICE_LEVEL_TO_Z.keys(), key=lambda k: abs(k - service_level))
    return SERVICE_LEVEL_TO_Z[closest]


def compute_safety_stock(
    avg_daily_demand: float,
    sigma_daily_demand: float,
    lead_time_days: int,
    service_level: float,
) -> float:
    if lead_time_days <= 0 or sigma_daily_demand <= 0:
        return 0.0
    Z = get_z_for_service_level(service_level)
    sigma_lt = sigma_daily_demand * math.sqrt(lead_time_days)
    return max(Z * sigma_lt, 0.0)


def compute_reorder_point(
    avg_daily_demand: float,
    safety_stock: float,
    lead_time_days: int,
) -> float:
    lead_time_demand = avg_daily_demand * float(lead_time_days)
    return max(lead_time_demand + safety_stock, 0.0)
