"""Phaxor — VLE Engine (Python port)"""
import math

def solve_vle(inputs: dict) -> dict | None:
    """VLE Calculator (Raoult + Rachford-Rice)."""
    pasat = float(inputs.get('pAsat', 0))
    pbsat = float(inputs.get('pBsat', 0))
    p_sys = float(inputs.get('P', 0))
    z = float(inputs.get('z', 0.5))

    if pasat <= 0 or pbsat <= 0 or p_sys <= 0:
        return None

    alpha = pasat / pbsat

    # Bubble & Dew Points
    p_bubble = z * pasat + (1.0 - z) * pbsat
    y_bubble = z * pasat / p_bubble

    p_dew = 1.0 / (z / pasat + (1.0 - z) / pbsat)
    x_dew = z * p_dew / pasat

    # Flash
    ka = pasat / p_sys
    kb = pbsat / p_sys
    
    v_frac = 0.5
    x_flash = z
    y_flash = z

    if p_sys >= p_bubble:
        v_frac = 0.0
        x_flash = z
        y_flash = (ka * z)
    elif p_sys <= p_dew:
        v_frac = 1.0
        y_flash = z
        x_flash = z / ka
    else:
        # Solve Rachford-Rice
        for _ in range(50):
            denom_a = 1.0 + v_frac * (ka - 1.0)
            denom_b = 1.0 + v_frac * (kb - 1.0)
            f = z * (ka - 1.0) / denom_a + (1.0 - z) * (kb - 1.0) / denom_b
            df = -z * pow(ka - 1.0, 2) / pow(denom_a, 2) - (1.0 - z) * pow(kb - 1.0, 2) / pow(denom_b, 2)
            
            if abs(df) < 1e-12: break
            v_new = v_frac - f / df
            if abs(v_new - v_frac) < 1e-6:
                v_frac = v_new
                break
            v_frac = v_new
            
        v_frac = max(0.0, min(1.0, v_frac))
        x_flash = z / (1.0 + v_frac * (ka - 1.0))
        y_flash = ka * x_flash

    xy_data = []
    xx = 0.0
    while xx <= 1.01:
        yy = (alpha * xx) / (1.0 + (alpha - 1.0) * xx)
        xy_data.append({
            'x': float(f"{xx:.3f}"),
            'y': float(f"{yy:.4f}"),
            'diag': float(f"{xx:.3f}")
        })
        xx += 0.05

    return {
        'alpha': float(f"{alpha:.3f}"),
        'Pbubble': float(f"{p_bubble:.2f}"),
        'yBubble': float(f"{y_bubble:.4f}"),
        'Pdew': float(f"{p_dew:.2f}"),
        'xDew': float(f"{x_dew:.4f}"),
        'V_frac': float(f"{v_frac:.4f}"),
        'xFlash': float(f"{x_flash:.4f}"),
        'yFlash': float(f"{y_flash:.4f}"),
        'xyData': xy_data
    }
