from typing import List
from typing import Dict
from typing import Optional


def aggregate_statuses(statuses: List[Dict], dc_voltage=False) -> Optional[Dict]:
    """Aggregates inverter statuses for use for PVOutput.org uploads.

    Does some rounding and integer conversion.

    Args:
        statuses: List of inverter statuses as returned by Inverter.status().
        dc_voltage: If True, aggregates DC voltage instead of AC voltage.

    Returns:
        Dictionary of keyword arguments for add_status() or None if no inverter
        has operation mode normal.
    """

    def avg(items):
        """Calculates average."""
        i = list(items)
        return sum(i) / len(i)

    # Calculate values for each inverter separately
    values = []
    for s in statuses:
        # Filter systems with normal operating mode
        if s['operation_mode'] != "Normal":
            continue

        # Calculate voltage
        if dc_voltage:
            # Takes average of PV1 and PV2 voltage
            voltage = avg([s['pv1_voltage'], s['pv2_voltage']])
        elif 'grid_voltage_r_phase' in s:
            # For three-phase inverters, take average voltage of all three phases
            voltage = avg([s['grid_voltage_r_phase'], s['grid_voltage_s_phase'], s['grid_voltage_t_phase']])
        else:
            # For one phase inverter, pick the grid voltage
            voltage = s['grid_voltage']

        values.append({
            'energy_gen': int(s['energy_today'] * 1000),
            'power_gen': int(s['output_power']),
            'temp': s['internal_temperature'],
            'voltage': voltage,
        })

    # Aggregate values of all inverters
    if not values:
        return None

    return {
        'energy_gen': sum(v['energy_gen'] for v in values),
        'power_gen': sum(v['power_gen'] for v in values),
        'temp': round(avg(v['temp'] for v in values), 1),
        'voltage': round(avg(v['voltage'] for v in values), 1),
    }