"""Phaxor — Ideal Gas Law Engine (Python port)"""

import math

R_UNIVERSAL = 8.314  # J/(mol·K)

GASES = {
    'air':      {'name': 'Air',             'M': 28.97,  'gamma': 1.4,   'cp': 1.005, 'cv': 0.718},
    'nitrogen': {'name': 'Nitrogen (N₂)',   'M': 28.01,  'gamma': 1.4,   'cp': 1.040, 'cv': 0.743},
    'oxygen':   {'name': 'Oxygen (O₂)',     'M': 32.0,   'gamma': 1.395, 'cp': 0.918, 'cv': 0.658},
    'hydrogen': {'name': 'Hydrogen (H₂)',   'M': 2.016,  'gamma': 1.41,  'cp': 14.30, 'cv': 10.16},
    'helium':   {'name': 'Helium (He)',     'M': 4.003,  'gamma': 1.667, 'cp': 5.193, 'cv': 3.116},
    'co2':      {'name': 'Carbon Dioxide',  'M': 44.01,  'gamma': 1.289, 'cp': 0.844, 'cv': 0.655},
    'argon':    {'name': 'Argon (Ar)',      'M': 39.95,  'gamma': 1.667, 'cp': 0.520, 'cv': 0.312},
    'methane':  {'name': 'Methane (CH₄)',   'M': 16.04,  'gamma': 1.32,  'cp': 2.226, 'cv': 1.687},
    'steam':    {'name': 'Steam (H₂O)',     'M': 18.015, 'gamma': 1.33,  'cp': 1.996, 'cv': 1.507},
    'neon':     {'name': 'Neon (Ne)',       'M': 20.18,  'gamma': 1.667, 'cp': 1.030, 'cv': 0.618},
}


def solve_ideal_gas(inputs: dict) -> dict | None:
    """
    Solve PV = nRT for any unknown variable.

    Args:
        inputs: dict with keys 'solveFor' ('pressure'|'volume'|'moles'|'temperature'),
                and the other three known values, plus optional 'gas' key.
    """
    gas_key = inputs.get('gas', 'air')
    gas = GASES.get(gas_key, GASES['air'])

    P = inputs.get('pressure', 0)
    V = inputs.get('volume', 0)
    n = inputs.get('moles', 0)
    T = inputs.get('temperature', 0)
    solve_for = inputs.get('solveFor', 'pressure')

    if solve_for == 'pressure' and V > 0 and n > 0 and T > 0:
        P = (n * R_UNIVERSAL * T) / V
    elif solve_for == 'volume' and P > 0 and n > 0 and T > 0:
        V = (n * R_UNIVERSAL * T) / P
    elif solve_for == 'moles' and P > 0 and V > 0 and T > 0:
        n = (P * V) / (R_UNIVERSAL * T)
    elif solve_for == 'temperature' and P > 0 and V > 0 and n > 0:
        T = (P * V) / (n * R_UNIVERSAL)

    if P <= 0 or V <= 0 or n <= 0 or T <= 0:
        return None

    mass_kg = n * (gas['M'] / 1000)
    R_specific = R_UNIVERSAL / (gas['M'] / 1000)

    return {
        'P': P, 'V': V, 'n': n, 'T': T,
        'Tcelsius': T - 273.15,
        'Patm': P / 101325,
        'Pbar': P / 1e5,
        'Ppsi': P * 0.000145038,
        'Vliters': V * 1000,
        'massKg': mass_kg,
        'densityKgM3': mass_kg / V,
        'speedOfSound': math.sqrt(gas['gamma'] * R_specific * T),
        'Rspecific': R_specific,
        'internalEnergy': n * gas['cv'] * (gas['M'] / 1000) * T,
        'enthalpy': n * gas['cp'] * (gas['M'] / 1000) * T,
        'gasProperties': gas,
    }
