"""Phaxor — Flywheel Design Engine (Python port)"""
import math

# Material Data (simplified from mechanicalCivilData.ts)
FLYWHEEL_MATERIALS = {
    'steel-a36': {'label': 'Structural Steel A36', 'density': 7850, 'Sy': 250},
    'steel-a572-50': {'label': 'Steel A572 Gr.50', 'density': 7850, 'Sy': 345},
    'steel-s355': {'label': 'Steel S355', 'density': 7850, 'Sy': 355},
    'steel-4140': {'label': 'AISI 4140 (Cr-Mo)', 'density': 7850, 'Sy': 655},
    'steel-4340': {'label': 'AISI 4340 (Ni-Cr-Mo)', 'density': 7850, 'Sy': 710},
    'steel-1018': {'label': 'AISI 1018 (Mild)', 'density': 7870, 'Sy': 220},
    'steel-1045': {'label': 'AISI 1045 (Medium Carbon)', 'density': 7870, 'Sy': 310},
    'ss-304': {'label': 'Stainless Steel 304', 'density': 8000, 'Sy': 215},
    'ss-316': {'label': 'Stainless Steel 316', 'density': 8000, 'Sy': 205},
    'ss-410': {'label': 'Stainless Steel 410', 'density': 7740, 'Sy': 275},
    'al-6061-t6': {'label': 'Aluminum 6061-T6', 'density': 2700, 'Sy': 276},
    'al-7075-t6': {'label': 'Aluminum 7075-T6', 'density': 2810, 'Sy': 503},
    'al-2024-t3': {'label': 'Aluminum 2024-T3', 'density': 2780, 'Sy': 345},
    'al-5052-h32': {'label': 'Aluminum 5052-H32', 'density': 2680, 'Sy': 193},
    'ti-6al4v': {'label': 'Titanium Ti-6Al-4V', 'density': 4430, 'Sy': 830},
    'ti-cp-gr2': {'label': 'Titanium CP Grade 2', 'density': 4510, 'Sy': 275},
    'copper-c11000': {'label': 'Copper C11000 (ETP)', 'density': 8960, 'Sy': 69},
    'brass-c26000': {'label': 'Brass C26000 (70/30)', 'density': 8530, 'Sy': 200},
    'bronze-c93200': {'label': 'Bronze C93200 (Bearing)', 'density': 8930, 'Sy': 125},
    'cast-iron-gray': {'label': 'Gray Cast Iron (Class 30)', 'density': 7200, 'Sy': 170},
    'cast-iron-ductile': {'label': 'Ductile Cast Iron (60-40-18)', 'density': 7100, 'Sy': 276},
    'inconel-625': {'label': 'Inconel 625', 'density': 8440, 'Sy': 414},
    'monel-400': {'label': 'Monel 400', 'density': 8800, 'Sy': 240},
    'tungsten': {'label': 'Tungsten', 'density': 19250, 'Sy': 750},
    'magnesium-az31b': {'label': 'Magnesium AZ31B', 'density': 1770, 'Sy': 200},
}

def solve_flywheel(inputs: dict) -> dict | None:
    """Flywheel Design Calculator."""
    rpm = float(inputs.get('rpm', 0))
    power_kw = float(inputs.get('powerKW', 0))
    cf = float(inputs.get('cf', 0))
    mat_key = inputs.get('matKey', 'cast-iron-gray')
    rim_ratio = float(inputs.get('rimRatio', 0.8))
    width_ratio = float(inputs.get('widthRatio', 0.3))

    if rpm <= 0 or power_kw <= 0 or cf <= 0:
        return None

    mat = FLYWHEEL_MATERIALS.get(mat_key, FLYWHEEL_MATERIALS['cast-iron-gray'])

    omega = (2 * math.pi * rpm) / 60
    omega_max = omega * (1 + cf / 2)
    omega_min = omega * (1 - cf / 2)

    torque_mean = (power_kw * 1000) / omega
    energy_fluctuation = torque_mean * 2 * math.pi * cf

    # Required moment of inertia: I = ΔE / (Cf × ω²)
    I = energy_fluctuation / (cf * omega ** 2)

    # Rim dimensions
    rho = mat['density']
    
    term1 = 2 * I
    term2 = rho * math.pi * width_ratio * (1 - pow(rim_ratio, 4))
    
    ro = 0.1
    if term2 > 0:
        ro = pow(term1 / term2, 0.2)
    
    ro = max(ro, 0.05)
    ri = ro * rim_ratio
    b = ro * width_ratio

    volume = math.pi * (pow(ro, 2) - pow(ri, 2)) * b
    mass = rho * volume
    i_actual = 0.5 * mass * (pow(ro, 2) + pow(ri, 2))

    # Hoop stress: σ = ρ × v² = ρ × (ω * R)² (at outer radius)
    hoop_stress = rho * pow(omega_max * ro, 2) / 1e6 # MPa

    kinetic_energy = 0.5 * i_actual * pow(omega, 2)

    return {
        'torqueMean': float(f"{torque_mean:.2f}"),
        'energyFluctuation': float(f"{energy_fluctuation:.2f}"),
        'momentOfInertia': float(f"{i_actual:.4f}"),
        'mass': float(f"{mass:.2f}"),
        'rimOuterDia': float(f"{ro * 2 * 1000:.1f}"), # mm
        'rimInnerDia': float(f"{ri * 2 * 1000:.1f}"), # mm
        'rimWidth': float(f"{b * 1000:.1f}"),         # mm
        'hoopStress': float(f"{hoop_stress:.2f}"),    # MPa
        'kineticEnergy': float(f"{kinetic_energy:.1f}"),
        'angularVelocity': float(f"{omega:.2f}"),
        'angularVelocityMax': float(f"{omega_max:.2f}"),
        'angularVelocityMin': float(f"{omega_min:.2f}"),
        'safe': hoop_stress < mat['Sy'] * 0.5
    }
