import 'dart:async';

import 'package:dbus/dbus.dart';
import 'package:flutter/material.dart';
import 'package:nm/nm.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';

part 'wifi_controller.g.dart';

@riverpod
class WifiController extends _$WifiController {
  @override
  Future<NetworkManagerClient> build() async {
    try {
      NetworkManagerClient client = NetworkManagerClient();
      await client.connect();

      return client;
    } catch (e) {
      return Future.error(e);
    }
  }

  NetworkManagerDevice get _device => state.value!.devices
      .firstWhere((d) => d.deviceType == NetworkManagerDeviceType.wifi);

  Stream<(NetworkManagerDevice, NetworkManagerClient)> wifiStream() {
    return Stream.periodic(const Duration(milliseconds: 100), (_) {
      return (_device, state.value!);
    });
  }

  void disconnectFromWifiNetwork({
    required NetworkManagerAccessPoint accessPoint,
  }) async {
    try {
      final device = _device;
      var active = await state.value!.activateConnection(device: device);
      await state.value!.deactivateConnection(active);
    } catch (e) {
      debugPrint(e.toString());
    }
  }

  void connectToWifiNetwork({
    required NetworkManagerAccessPoint accessPoint,
    String? psk,
  }) async {
    try {
      final device = _device;
      // Has password
      if (psk != null) {
        await state.value!.addAndActivateConnection(
          device: device,
          accessPoint: accessPoint,
          connection: {
            '802-11-wireless-security': {
              'key-mgmt': const DBusString('wpa-psk'),
              'psk': DBusString(psk)
            }
          },
        );
      } else {
        await state.value!
            .addAndActivateConnection(device: device, accessPoint: accessPoint);
      }
    } catch (e) {
      debugPrint(e.toString());
    }
  }
}
