"""Phaxor — Atomic Packing Factor Engine (Python port)"""
import math

def solve_apf(inputs: dict) -> dict | None:
    """APF Calculator."""
    structure = inputs.get('structure', 'BCC')
    radius = float(inputs.get('radius', 0))
    molar_mass = float(inputs.get('molarMass', 0))

    if radius <= 0 or molar_mass <= 0:
        return None

    na = 6.022e23
    n = 0
    apf = 0.0
    a = 0.0
    v_nm3 = 0.0

    if structure == 'SC':
        n = 1
        apf = 0.5236
        a = 2 * radius
        v_nm3 = a ** 3
    elif structure == 'BCC':
        n = 2
        apf = 0.6802
        a = 4 * radius / math.sqrt(3)
        v_nm3 = a ** 3
    elif structure == 'FCC':
        n = 4
        apf = 0.7405
        a = 2 * math.sqrt(2) * radius
        v_nm3 = a ** 3
    elif structure == 'HCP':
        n = 6
        apf = 0.7405
        a = 2 * radius
        v_nm3 = 3 * math.sqrt(2) * (a ** 3)
    elif structure == 'Diamond':
        n = 8
        apf = 0.3401
        a = 8 * radius / math.sqrt(3)
        v_nm3 = a ** 3
    
    v_cm3 = v_nm3 * 1e-21
    rho = (n * molar_mass) / (na * v_cm3) if v_cm3 > 0 else 0
    void_frac = 1.0 - apf

    return {
        'apf': apf,
        'a': float(f"{a:.4f}"),
        'rho': float(f"{rho:.2f}"),
        'V_nm3': float(f"{v_nm3:.4f}"),
        'n': n,
        'voidFrac': float(f"{void_frac:.3f}")
    }
