import 'dart:developer';
import 'dart:math';

import 'package:flutter/material.dart';
import 'dart:async';

import 'package:flutter/services.dart';
import 'package:flutter_zsdk/flutter_zsdk.dart';
import 'package:flutter_zsdk/src/models/flutter_zsdk_exception.dart';
import 'package:flutter_zsdk_example/models/bluetooth_printer.dart';

void main() {
  runApp(const MaterialApp(home: MyApp()));
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  bool _isDiscovering = false;
  List<BluetoothPrinter> _discoveredBluetoothPrinters = [];
  String? _connectedPrinter;
  final _flutterZsdkPlugin = FlutterZsdk();
  String? _selectedBluetoothPrinterMacAddress;
  bool _disconnecting = false;

  @override
  void initState() {
    super.initState();
    // initPlatformState();
  }

  // Platform messages are asynchronous, so we initialize in an async method.
  // Future<void> initPlatformState() async {
  //   String platformVersion;
  //   // Platform messages may fail, so we use a try/catch PlatformException.
  //   // We also handle the message potentially returning null.
  //   try {
  //     platformVersion =
  //         await _flutterZsdkPlugin.getPlatformVersion() ?? 'Unknown platform version';
  //   } on PlatformException {
  //     platformVersion = 'Failed to get platform version.';
  //   }

  //   // If the widget was removed from the tree while the asynchronous platform
  //   // message was in flight, we want to discard the reply rather than calling
  //   // setState to update our non-existent appearance.
  //   if (!mounted) return;

  //   setState(() {
  //     _platformVersion = platformVersion;
  //   });
  // }

  StreamSubscription? _bluetoothPrinterSubscription;

  void showSnackBar(String message) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text(message))
    );
  }

  Future<void> discoverBluetoothDevices() async {
    try {
      Stream<dynamic> stream = await _flutterZsdkPlugin.findBluetoothPrinters();
      _bluetoothPrinterSubscription = stream.listen((event) {
        print(event);

        if (event == 'SOS') {
          _isDiscovering = true;

        }

        if (event is List) {
          _discoveredBluetoothPrinters.clear();
          for (var printer in event) {
            BluetoothPrinter bluetoothPrinter = BluetoothPrinter.fromMap(printer);

            _discoveredBluetoothPrinters.add(bluetoothPrinter);
          }

        }

        if (event == 'EOS') {
          _isDiscovering = false;
          showSnackBar('Bluetooth discovery finished, found ${_discoveredBluetoothPrinters.length} printers');
          _bluetoothPrinterSubscription?.cancel();
        }

        setState(() {});
      });
    
    } on PlatformException catch (e) {
      inspect(e);
      showSnackBar(e.message.toString());

    } on FlutterZsdkException catch (e) { 
      inspect(e);
      showSnackBar(e.message);

    } catch (e) {
      inspect(e);
      showSnackBar('Unexpected error while discovering bluetooth printers');

    }
  }

  Future<void> openConnection() async {
    print('invoked openConnection from dart');
    try {
      await _flutterZsdkPlugin.openConnection(_selectedBluetoothPrinterMacAddress ?? ''); 
      _connectedPrinter = _selectedBluetoothPrinterMacAddress ?? 'Unknown printer';
      print('Connection opened successfully from dart');
      
    } on FlutterZsdkException catch (e) {
      inspect(e);
      showSnackBar(e.message);

    } catch (e) {
      inspect(e);
      showSnackBar('Unexpected error while connecting to bluetooth printers');
    }

    setState(() {});
  }

  Future<void> closeConnection() async {
    print('invoked closeConnection from dart');
    try {
      setState(() {
        _disconnecting = true;
      });
      await _flutterZsdkPlugin.closeConnection(); 
      _connectedPrinter = null;
      _disconnecting = false;
      print('Connection closed successfully from dart');
      
    } on FlutterZsdkException catch (e) {
      inspect(e);
      showSnackBar(e.message);

    } catch (e) {
      inspect(e);
      showSnackBar('Unexpected error while disconnecting bluetooth printers');
    }

    setState(() {});
  }

  Future<void> printZplOverBluetooth() async {
    print('invoked printZplOverBluetooth from dart');
    try {
      await _flutterZsdkPlugin.printZplOverBluetooth("^XA^PW624^LL800^FO20,20^A0N,25,25^FDThis is a ZPL test.^FS^FO20,60^BQ ,2,10 , , , A ^FDQA,http://192.168.102.170:4218/?q=IDC4C321S023^FS^^FO20,500^A0N,25,25^FDDart Zpl Test.^FS^XZ");
      print('printZplOverBluetooth successfully from dart');
      
    } on FlutterZsdkException catch (e) {
      inspect(e);
      showSnackBar(e.message);

    } catch (e) {
      inspect(e);
      showSnackBar('Unexpected error when send data to printers');
    }

    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Plugin example app'),
      ),
      body: Center(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Connected printer: ${_connectedPrinter ?? "Unknown printer"}\n'),
            Text('Selected printer Mac Address: $_selectedBluetoothPrinterMacAddress\n'),
            SizedBox(height: 20),
        
            ElevatedButton(
              child: Text('Connect to $_selectedBluetoothPrinterMacAddress'),
              onPressed: _selectedBluetoothPrinterMacAddress == null ? null : openConnection,
            ),
            SizedBox(height: 20),

            ElevatedButton(
              child: Text(_disconnecting ? 'Disconnecting...' : 'Disconnect from $_connectedPrinter'),
              onPressed: _connectedPrinter == null || _disconnecting ? null : closeConnection,
            ),
            SizedBox(height: 20),

            ElevatedButton(
              child: Text('Print zpl over bluetooth'),
              onPressed: _connectedPrinter == null ? null : printZplOverBluetooth,
            ),
            SizedBox(height: 20),

            ElevatedButton(
              child: Text('Check connection status'),
              onPressed: () async {
                bool isConnected =await _flutterZsdkPlugin.isConnected();
              
                print('isConnected from dart: $isConnected');
              },
            ),
            SizedBox(height: 20),
            
            ElevatedButton(
              child: Text(_isDiscovering ? 'Discovering bluetooth printers...' : 'Discover nearby bluetooth printers'),
              onPressed: _isDiscovering ? null : () async {
                discoverBluetoothDevices();
              },
            ),
            SizedBox(height: 20),

            for (var printer in _discoveredBluetoothPrinters) ... [
              InkWell(
                onTap: () {
                  _selectedBluetoothPrinterMacAddress = printer.macAddress;
                  setState(() {});
                },
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Text(printer.friendlyName),
                    Text(printer.macAddress),
                    SizedBox(height: 10)
                  ],
                ),
              )
            ]
          ] 
          
        ),
      ),

    );
  }
}
