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

def solve_pfr(inputs: dict) -> dict | None:
    """PFR Design Calculator."""
    ca0 = float(inputs.get('cA0', 0))
    k = float(inputs.get('k', 0))
    order = str(inputs.get('order', '1'))
    flow = float(inputs.get('flowRate', 0))
    x_target = float(inputs.get('targetX', 0))

    if ca0 <= 0 or k <= 0 or flow <= 0 or x_target <= 0 or x_target >= 1:
        return None

    # Calculate Tau
    tau = 0.0
    if order == '0':
        tau = ca0 * x_target / k
    elif order == '1':
        tau = -math.log(1.0 - x_target) / k
    else: # order 2
        tau = x_target / (k * ca0 * (1.0 - x_target))

    vol = flow * tau
    ca_exit = ca0 * (1 - x_target)

    # CSTR comparison
    ra_exit_cstr = 0.0
    if order == '0': ra_exit_cstr = k
    elif order == '1': ra_exit_cstr = k * ca_exit
    else: ra_exit_cstr = k * ca_exit * ca_exit
    
    tau_cstr = ca0 * x_target / (ra_exit_cstr if ra_exit_cstr > 0 else 1e-9)
    vol_cstr = flow * tau_cstr
    ratio = vol_cstr / vol if vol > 0 else 0

    # Profile Data
    profile_data = []
    n_steps = 50
    for i in range(n_steps + 1):
        frac = i / n_steps
        t_local = frac * tau
        x_local = 0.0
        
        if order == '0':
            x_local = min(k * t_local / ca0, 1.0)
        elif order == '1':
            x_local = 1.0 - math.exp(-k * t_local)
        else:
            kt = k * ca0 * t_local
            x_local = kt / (1.0 + kt)
            
        profile_data.append({
            'pos': int(frac * 100),
            'X': float(f"{x_local:.4f}"),
            'cA': float(f"{ca0 * (1.0 - x_local):.4f}")
        })

    # Levenspiel Data
    levenspiel_data = []
    xx = 0.0
    while xx <= 0.99:
        ca = ca0 * (1.0 - xx)
        ra = 0.0
        if order == '0': ra = k
        elif order == '1': ra = k * ca
        else: ra = k * ca * ca
        
        if ra > 1e-12:
            levenspiel_data.append({
                'X': float(f"{xx:.2f}"),
                'invR': float(f"{ca0/ra:.4f}")
            })
        xx += 0.02

    return {
        'V': float(f"{vol:.2f}"),
        'tau': float(f"{tau:.2f}"),
        'cA_exit': float(f"{ca_exit:.4f}"),
        'V_cstr': float(f"{vol_cstr:.2f}"),
        'volumeRatio': float(f"{ratio:.2f}"),
        'profileData': profile_data,
        'levenspielData': levenspiel_data
    }
