import 'dart:io';
import 'dart:typed_data';

import 'package:aman_kassa_flutter/core/models/dialog_models.dart';
import 'package:aman_kassa_flutter/core/services/blue_print_service.dart';
import 'package:aman_kassa_flutter/widgets/fields/busy_button_icon.dart';
import 'package:aman_kassa_flutter/core/locator.dart';
import 'package:aman_kassa_flutter/core/logger.dart';
import 'package:aman_kassa_flutter/core/route_names.dart';
import 'package:aman_kassa_flutter/core/services/dialog_service.dart';
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
import 'package:aman_kassa_flutter/redux/state/setting_state.dart';
import 'package:aman_kassa_flutter/redux/store.dart';
import 'package:esc_pos_utils/esc_pos_utils.dart';
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:aman_kassa_flutter/views/settings/printer/PrinterTest.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:logger/logger.dart';

import 'component/setting_item.dart';
import './printer/data/settings_envi.dart';
import './printer/example/check_test.dart';

class SettingPrinterView extends StatefulWidget {
  @override
  _SettingPrinterViewState createState() => _SettingPrinterViewState();
}

class _SettingPrinterViewState extends State<SettingPrinterView> {
  NavigatorService _navigatorService = locator<NavigatorService>();
  final DialogService _dialogService = locator<DialogService>();
  final BluePrintService printerManager = locator<BluePrintService>();
  final Logger log = getLogger('SettingPrinterView');

  bool _printing = false;

  @override
  void initState() {
    super.initState();
    _permission();
  }
  @override
  void dispose() {
    disconnect();
    super.dispose();
  }

  disconnect() async {
    await printerManager.disconnect();
  }

  void _testPrint() async {
    setState(() {
      _printing = true;
    });
    try {
      final SettingState state = Redux.store!.state.settingState!;
      printerManager.device = state.printerBT!;

      await disconnect();
      await Future.delayed(Duration(seconds: 1));

      await printerManager.connect();
      await Future.delayed(Duration(seconds: 3));
      bool isIos = Platform.isIOS;
      int chunkSizeBytes = 3096;
      int queueSleepTimeMs = 100;

      if (isIos) {
        chunkSizeBytes = 75;
        queueSleepTimeMs = 10;
      }

      log.i(chunkSizeBytes);
      log.i(queueSleepTimeMs);

      // TODO Don't forget to choose printer's paper
      PaperSize paper = state.printerPaperSize == SettingPrinterPaperM80
          ? PaperSize.mm80
          : PaperSize.mm58;
      if (SettingPrinterEncodingImage == state.printerEncoding) {
        final bool res = await printerManager.printBytes(
            Uint8List.fromList(await testTicketImage(paper)),
            chunkSizeBytes: chunkSizeBytes,
            queueSleepTimeMs: queueSleepTimeMs);
        //_dialogService.showDialog(description: 'result is $res');
      } else {
        final bool res = await printerManager.printBytes(
            Uint8List.fromList(await printTextCheck(
                paper, state.printerEncoding!, exampleJson['check_text'])),
            chunkSizeBytes: chunkSizeBytes,
            queueSleepTimeMs: queueSleepTimeMs);
        //_dialogService.showDialog(description: 'result is $res');
      }
    } catch (e) {
      print('ERROR');
      print(e);
    }
    //10 sec safe disconnect
    await Future.delayed(Duration(seconds: 14));

    setState(() {
      _printing = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Настройка принтера'),
      ),
      body: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 8.0),
        child: StoreConnector<AppState, SettingState>(
            converter: (store) => store.state.settingState!,
            builder: (context, vm) {
              return Column(
                children: [
                  SettingItem(
                      title: 'Принтер',
                      name: vm.printerBT?.name ?? '',
                      value: vm.printerBT != null
                          ? 'BT: ${vm.printerBT?.address ?? ''} '
                          : 'не выбран',
                      onTap: () {
                        _navigatorService.push(SettingsPrinterBTRoute);
                      }),
                  SettingItem(
                      title: 'Кодировка',
                      name: vm.printerEncoding != null
                          ? encoding[vm.printerEncoding]
                          : '',
                      onTap: () {
                        _navigatorService.push(SettingsPrinterEncodingRoute);
                      }),
                  SettingItem(
                      title: 'Ширина ленты',
                      name: vm.printerPaperSize != null
                          ? paperSize[vm.printerPaperSize]
                          : null,
                      onTap: () {
                        _navigatorService.push(SettingsPrinterPaperRoute);
                      }),
                  Expanded(
                    child: Padding(
                      padding: const EdgeInsets.only(bottom: 24.0),
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.end,
                        children: [
                          BusyButtonIcon(
                            icon: Icons.local_printshop_outlined,
                            title: 'Напечатать тестовую страницу',
                            busy: _printing,
                            enabled: vm.printerBT != null,
                            onPressed: () {
                              _startInitialPrint();
                            },
                          ),
                        ],
                      ),
                    ),
                  )
                ],
              );
            }),
      ),
    );
  }

  //Метод для получения постоянного доступа к местополения
  //только для Android
  void _permission() async {
    if (Platform.isAndroid) {
      var status = await Permission.location.status;
      log.i(status);
      if (status.isDenied || status.isPermanentlyDenied) {
        DialogResponse response = await _dialogService.showConfirmationDialog(
          title: 'Доступ',
          description:
              'Для поиска устройств Bluetooth необходимо предоставить доступ к отслеживанию геолокации.',
          cancelTitle: 'Нет',
          confirmationTitle: 'Хорошо',
        );
        if (response.confirmed) {
          if (await Permission.location.request().isGranted) {
            print('Granted');
          } else {
            _dialogService.showDialog(
                description:
                    'Необходимо указать постоянный доступ к местоположении для поиска принтера');
            _navigatorService.pop();
          }
        } else {

          _navigatorService.pop();
        }
      }
    }
  }

  void _startInitialPrint() async {
    if (Platform.isIOS) {
      _testPrint();
    } else {
      printerManager.state.listen((val) {
        print("state = $val");
        if (!mounted) return;
        if (val == 12) {
          print('on');
          _testPrint();
        } else if (val == 10) {
          print('off');
          _dialogService.showDialog(
              description: 'Отсутвует соеденение Bluetooth или он отключен',
              title: 'Bluetooth');
        }
        print('state is $val');
      });
    }
  }
}
