import sys
import datetime
import dateutil

# Our files
from pyemvue.device import VueDevice, VueUsageDevice
from pyemvue.enums import Scale, Unit
from pyemvue.pyemvue import PyEmVue

def print_recursive(usage_dict: dict[int, VueUsageDevice], info: dict[int, VueDevice], scaleBy: float=1, unit='kWh', depth=0):
    for gid, device in usage_dict.items():
        for channelnum, channel in device.channels.items():
            name = channel.name
            if name == 'Main':
                name = info[gid].device_name
            usage = channel.usage or 0
            print('-'*depth, f'{gid} {channelnum} {name} {usage*scaleBy} {unit}')
            if channel.nested_devices:
                print_recursive(channel.nested_devices, info, scaleBy=scaleBy, unit=unit, depth=depth+1)

def main():
    errorMsg = 'Please pass a file containing the "email" and "password" as json.'
    if len(sys.argv) == 1:
        print(errorMsg)
        sys.exit(1)

    filepath = sys.argv[1]
    vue = PyEmVue()
    vue.login(token_storage_file=filepath)
    print('Logged in. Authtoken follows:')
    print(vue.auth.tokens["id_token"])
    print()
    channelTypes = vue.get_channel_types()
    devices = vue.get_devices()
    deviceGids: list[int] = []
    deviceInfo: dict[int, VueDevice] = {}
    for device in devices:
        if not device.device_gid in deviceGids:
            deviceGids.append(device.device_gid)
            deviceInfo[device.device_gid] = device
            print(device.device_gid, device.manufacturer_id, device.model, device.firmware)
            for chan in device.channels:
                channelTypeInfo = next((c for c in channelTypes if c.channel_type_gid == chan.channel_type_gid), None)
                print('\t', chan.device_gid, chan.name, chan.channel_num, chan.channel_multiplier, channelTypeInfo.description if channelTypeInfo else chan.channel_type_gid)
        else:
            deviceInfo[device.device_gid].channels += device.channels
            for chan in device.channels:
                channelTypeInfo = next((c for c in channelTypes if c.channel_type_gid == chan.channel_type_gid), None)
                print('\t', chan.device_gid, chan.name, chan.channel_num, chan.channel_multiplier, channelTypeInfo.description if channelTypeInfo else chan.channel_type_gid)

    monthly, start = vue.get_chart_usage(devices[0].channels[0],scale=Scale.MONTH.value)
    print(monthly[0], 'kwh used since', start.isoformat())
    now = datetime.datetime.now(datetime.timezone.utc)
    midnight=(datetime.datetime
             .now(dateutil.tz.gettz(devices[0].time_zone))
             .replace(hour=0, minute=0, second=0, microsecond=0)
             .astimezone(dateutil.tz.tzutc()))
    yesterday = midnight - datetime.timedelta(days=1)
    yesterday = yesterday.replace(tzinfo=None)
    print('Total usage for today in kwh: ')

    use = vue.get_device_list_usage(deviceGids, now, Scale.DAY.value)
    print_recursive(use, deviceInfo)
    print('Total usage for yesterday in kwh: ')
    for gid, device in deviceInfo.items():
        for chan in device.channels:
            usage = vue.get_chart_usage(chan, yesterday, yesterday+datetime.timedelta(hours=23, minutes=59), Scale.DAY.value)
            if usage and usage[0]:
                print(f'{chan.device_gid} ({chan.channel_num}): {usage[0][0]} kwh')
    print('Average usage over the last minute in watts: ')
    use = vue.get_device_list_usage(deviceGids, None, Scale.MINUTE.value)
    print_recursive(use, deviceInfo, scaleBy=60000, unit='W')

    usage_over_time, start_time = vue.get_chart_usage(devices[0].channels[0], datetime.datetime.now(datetime.timezone.utc)-datetime.timedelta(days=7), datetime.datetime.now(datetime.timezone.utc), scale=Scale.DAY.value, unit=Unit.KWH.value)

    print('Usage for the last seven days starting', start_time.isoformat())
    for usage in usage_over_time:
        print(usage, 'kwh')

    (outlets, chargers) = vue.get_devices_status(devices)
    print('List of Outlets:')
    for outlet in outlets:
        print(f"\t{outlet.device_gid} On? {outlet.outlet_on}")

    print('List of Chargers:')
    for charger in chargers:
        print(f"\t{charger.device_gid} On? {charger.charger_on} Charge rate: {charger.charging_rate}/{charger.max_charging_rate} Status: {charger.status}")

    try:
        vehicles = vue.get_vehicles()
        print('List of Vehicles')
        for vehicle in vehicles:
            print(f'\t{vehicle.vehicle_gid} ({vehicle.display_name}) - {vehicle.year} {vehicle.make} {vehicle.model}')

        print('List of Vehicle Statuses')
        for vehicle in vehicles:
            vehicleStatus = vue.get_vehicle_status(vehicle.vehicle_gid)
            if vehicleStatus:
                print(f'\t{vehicleStatus.vehicle_gid} {vehicleStatus.vehicle_state} - Charging: {vehicleStatus.charging_state} Battery level: {vehicleStatus.battery_level}')
            else:
                print(f'\t{vehicle.vehicle_gid} - No status available')
    except Exception as e:
        print(f'Error getting vehicles: {e}')

if __name__ == '__main__':
    main()

