import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_bluetooth_serial/flutter_bluetooth_serial.dart';
import 'package:flutter_provisioning_for_iot/screens/bluetooth_device_settings.dart';

class BluetoothDiscovery extends StatefulWidget {
  final bool start;
  final String deviceID;

  const BluetoothDiscovery({
    super.key,
    required this.start,
    required this.deviceID
  });

  @override
  State<BluetoothDiscovery> createState() => _BluetoothDiscovery();
}

class _BluetoothDiscovery extends State<BluetoothDiscovery> {

  StreamSubscription<BluetoothDiscoveryResult>? _streamSubscription;
  List<BluetoothDiscoveryResult> results = List<BluetoothDiscoveryResult>.empty(growable: true);
  bool isDiscovering = false;

  @override
  Widget build(BuildContext context) {
    debugPrint("test: ${widget.deviceID}");
    debugPrint("bool: ${widget.start}");
    if(widget.start) {
      _startDiscovery();
    }
    return RefreshIndicator(
        onRefresh: () {
      debugPrint("refreshed");
      return Future(() => null);
    },
    child: ListView.builder(
      scrollDirection: Axis.vertical,
        shrinkWrap: true,
        itemCount: results.length,
        itemExtent: 50.0,
        itemBuilder:
          (BuildContext context, int index) {
            var device = results.elementAt(index).device;
            var deviceAddress = device.address;
            var deviceName = device.name;
            return Row(
              mainAxisAlignment: MainAxisAlignment.start,
              children: <Widget>[
                const Icon(Icons.bluetooth_disabled_rounded),
                TextButton(
                    onPressed: () {
                      debugPrint(deviceAddress);
                    },
                    onLongPress: () {
                      debugPrint("no need to press for this long...");
                    },
                    child: Text("$deviceAddress"
                        "${(deviceName != "" ? "" : " | $deviceName")}")),
                const Expanded(child: Text("")),
                IconButton(
                  icon: const Icon(Icons.settings),
                  onPressed: () {
                    debugPrint("this is a warning!");
                    debugPrint(device.address);
                    Navigator.push(context, MaterialPageRoute(builder: (context) => BluetoothDeviceSettings(device: device)));
                  },
                ),
              ],
            );
          },
        )
    );
  }

  @override
  void initState() {
    super.initState();

    isDiscovering = widget.start;
    if (isDiscovering) {
      _startDiscovery();
    }
  }

  void _restartDiscovery() {
    setState(() {
      results.clear();
      isDiscovering = true;
    });

    _startDiscovery();
  }

  void _startDiscovery() {
    _streamSubscription =
        FlutterBluetoothSerial.instance.startDiscovery().listen((r) {
      setState(() {
        final existingIndex = results.indexWhere(
            (element) => element.device.address == r.device.address);
        if (existingIndex >= 0) {
          results[existingIndex] = r;
        } else {
          results.add(r);
        }
      });
    });

    debugPrint("results: $results");

    _streamSubscription!.onDone(() {
      setState(() {
        isDiscovering = false;
      });
    });
  }

  @override
  void dispose() {
    // Avoid memory leak (`setState` after dispose) and cancel discovery
    _streamSubscription?.cancel();

    super.dispose();
  }

  void initScan() {
    _streamSubscription =
        FlutterBluetoothSerial.instance.startDiscovery().listen((r) {
      debugPrint("r: ${r.device.name} ${r.device.address}");
      setState(() {
        final existingIndex = results.indexWhere(
            (element) => element.device.address == r.device.address);
        if (existingIndex >= 0) {
          results[existingIndex] = r;
        } else {
          results.add(r);
        }
      });
      if (r.device.address == "38:F3:2E:41:82:74") {
        BluetoothConnection.toAddress(r.device.address).then((connection) {
          debugPrint('Connected to the device');
          //connection = _connection;
          //setState(() {
          //isConnecting = false;
          //isDisconnecting = false;
        });
      }
    });

    _streamSubscription!.onDone(() {
      setState(() {
        isDiscovering = false;
      });
    });
  }
}
