import 'dart:convert';
import 'dart:io';
import 'package:aman_kassa_flutter/core/entity/Voucher.dart';
import 'dart:typed_data';
import 'package:aman_kassa_flutter/core/locator.dart';
import 'package:aman_kassa_flutter/core/models/check_data.dart';
import 'package:aman_kassa_flutter/core/models/check_image_modal.dart';
import 'package:aman_kassa_flutter/core/models/aman_dao.dart';
import 'package:aman_kassa_flutter/core/models/card_data.dart';
import 'package:aman_kassa_flutter/core/models/dialog_models.dart';
import 'package:aman_kassa_flutter/core/models/response.dart';
import 'package:aman_kassa_flutter/core/route_names.dart';
import 'package:aman_kassa_flutter/core/services/BankService.dart';
import 'package:aman_kassa_flutter/core/services/DataService.dart';
import 'package:aman_kassa_flutter/core/services/blue_print_service.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/actions/setting_actions.dart';
import 'package:aman_kassa_flutter/redux/actions/user_actions.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:aman_kassa_flutter/shared/app_colors.dart';
import 'package:aman_kassa_flutter/shared/ui_helpers.dart';
import 'package:aman_kassa_flutter/views/settings/printer/PrinterTest.dart';
import 'package:aman_kassa_flutter/views/payment/halyk_pos_service.dart';
import 'package:aman_kassa_flutter/widgets/fields/busy_button_icon.dart';
import 'package:aman_kassa_flutter/widgets/loader/Dialogs.dart';
import 'package:aman_kassa_flutter/core/models/bluetooth_device.dart';
import 'package:esc_pos_utils/esc_pos_utils.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
import 'package:share_plus/share_plus.dart';
import 'package:path_provider/path_provider.dart';
import 'package:url_launcher/url_launcher.dart';

import '../../core/models/aman_dao.dart';
import '../../redux/state/bank_state.dart';
import '../payment/forte_pos_service.dart';

class ImageShowContainer extends StatefulWidget {
  final ImageShowModel showModel;

  ImageShowContainer(this.showModel);

  @override
  _ImageShowContainerState createState() => _ImageShowContainerState();
}

class _ImageShowContainerState extends State<ImageShowContainer> {
  final BluePrintService printerManager = locator<BluePrintService>();
  final DialogService _dialogService = locator<DialogService>();
  final BluetoothDevice? printerBtDevice =
      Redux.store!.state.settingState!.printerBT;

  bool _printing = false;

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

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


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

  void _print() async {
    final SettingState state = Redux.store!.state.settingState!;
    if (state.printerBT == null) {
      _dialogService.showDialog(
          description: 'Укажите в настройках принтер для печати чеков');
      return;
    }

    bool isIos = Platform.isIOS;
    int chunkSizeBytes = 3096;
    int queueSleepTimeMs = 100;

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

    setState(() {
      _printing = true;
    });
    try {
      printerManager.device = state.printerBT!;
      await printerManager.connect();
      PaperSize paper = state.printerPaperSize == SettingPrinterPaperM80
          ? PaperSize.mm80
          : PaperSize.mm58;
      if (SettingPrinterEncodingImage == state.printerEncoding) {
        final bool res = await printerManager.printBytes(
            Uint8List.fromList(await printImageCheck(paper, widget.showModel.data!.base64Data!)));
        if (!res) {
          _dialogService.showDialog(description: 'Ошибка при печати');
        }
      } else {
        final bool res = await printerManager.printBytes(
            Uint8List.fromList(await printTextCheck(paper, state.printerEncoding!,
                jsonDecode(widget.showModel.data!.textData!)))
        );
        if (!res) {
          _dialogService.showDialog(description: 'Ошибка при печати');
        }
      }

    } catch (e) {
      print(e);
    }
    await Future.delayed(Duration(seconds: 15));

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        //backgroundColor: fillColor,
        title: Text(widget.showModel.title),
        actions: [
          if (_printing)
            Padding(
              padding: const EdgeInsets.only(right: 8.0),
              child: SizedBox(
                width: 36.0,
                child: Center(
                  child: CircularProgressIndicator(
                    strokeWidth: 2,
                    valueColor: new AlwaysStoppedAnimation<Color>(whiteColor),
                  ),
                ),
              ),
            )
          else
            IconButton(icon: Icon(Icons.print), onPressed: _preparePrint)
        ],
      ),
      body: ListView(
        children: <Widget>[
          imageFromBase64String(widget.showModel.data!.base64Data!)
        ],
      ),
      floatingActionButton: MyFloatingActionButton(widget.showModel),
    );
  }
}

Padding imageFromBase64String(String base64String) {
  return Padding(
    padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 8.0),
    child: Image.memory(base64Decode(base64String)),
  );
}

class ImageShowModel {
  final CheckImageModal? data;
  final String title;
  final String? url;
  final CardData? cardData;
  final Voucher? voucher;

  ImageShowModel({this.data, required this.title, this.url, this.cardData, this.voucher});
}

class MyFloatingActionButton extends StatefulWidget {
  final ImageShowModel data;

  MyFloatingActionButton(this.data);

  @override
  _MyFloatingActionButtonState createState() => _MyFloatingActionButtonState();
}

class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
  bool showFab = true;
  DialogService _dialog = locator<DialogService>();
  NavigatorService _navigatorService = locator<NavigatorService>();
  final GlobalKey<State> _keyLoader = new GlobalKey<State>();
  final DataService _dataService = locator<DataService>();

  double sheetHeight = 260;



  @override
  Widget build(BuildContext context) {
    //print(widget.data.cardData.transactionType);
    if (showFab) {
      return Column(
        mainAxisAlignment: MainAxisAlignment.end,
        children: [
          if (widget.data.cardData?.transactionType == "payment")
            FloatingActionButton(
              backgroundColor: redColor,
              tooltip: 'Отмена',
              child: Icon(
                Icons.cancel,
                color: whiteColor,
              ),
              onPressed: () async {
                var today = new DateTime.now();
                var yesterday = today.subtract(new Duration(days: 1));
                if(Redux.store?.state.userState?.smena?.startedAt == null
                    || yesterday.isAfter(Redux.store!.state.userState!.smena!.startedAt!)) {
                  _dialog.showDialog(description: 'Текущая смена открыта более 24 ч. Необходимо закрыть смену и открыть ее заново.');
                  return;
                }
                try {
                  await Redux.store!.dispatch(changePinSkipFromSetting(true));
                  // Определяем метод отмены в зависимости от типа сессии
                  final BankState? state = Redux.store?.state.bankState;
                  final isForteSessionActive = state?.sessionType == 'Forte';

                  final AmanDao<CardData> response = isForteSessionActive
                      ? await reversalFortePos(widget.data.cardData!, widget.data.voucher!.total!)
                      : await reversalHalykPos(widget.data.cardData!, widget.data.voucher!.total!);
                  if (response.success == true) {
                    pressRefund();
                  } else {
                    _dialog.showDialog(description: response.msg!);
                  }
                } finally {
                  await Redux.store!.dispatch(changePinSkipFromSetting(false));
                }
                _navigatorService.replace(HomeViewRoute);
              },
              heroTag: null,
            )
          else
            SizedBox(
              height: 0,
            ),
          SizedBox(
            height: 10,
          ),
          if (widget.data.cardData != null && widget.data.cardData?.transactionType == "payment")
            FloatingActionButton(
              backgroundColor: redColor,
              tooltip: 'Возврат',
              child: Icon(
                Icons.settings_backup_restore,
                color: whiteColor,
              ),
              onPressed: () async {
                var today = new DateTime.now();
                var yesterday = today.subtract(new Duration(days: 1));
                if( Redux.store!.state.userState == null
                    || Redux.store!.state.userState?.smena == null
                    || Redux.store!.state.userState?.smena?.startedAt == null
                    || yesterday.isAfter(Redux.store!.state.userState!.smena!.startedAt!)) {
                  _dialog.showDialog(description: 'Текущая смена открыта более 24 ч. Необходимо закрыть смену и открыть ее заново.');
                  return;
                }

                try {
                  await Redux.store!.dispatch(changePinSkipFromSetting(true));
                  final BankState? state = Redux.store?.state.bankState;
                  final isForteSessionActive = state?.sessionType == 'Forte';

                  final AmanDao<CardData> response = isForteSessionActive
                      ? await refundFortePos(widget.data.cardData!, widget.data.voucher!.total!)
                      : await refundHalykPos(widget.data.cardData!, widget.data.voucher!.total!);
                  if (response.success == true) {
                    pressRefund();
                  } else {
                    _dialog.showDialog(description: response.msg!);
                  }
                } finally {
                  await Redux.store!.dispatch(changePinSkipFromSetting(false));
                }
              },
              heroTag: null,
            )
          else
            SizedBox(
              height: 0,
            ),
          SizedBox(
            height: 10,
          ),
          FloatingActionButton(
            child: Icon(Icons.share),
            onPressed: () {
              var bottomSheetController = showBottomSheet(
                  context: context,
                  builder: (bottomSheetContext) => Container(
                      padding: const EdgeInsets.symmetric(horizontal: 10.0),
                      decoration: BoxDecoration(
                          color: Colors.white,
                          borderRadius: BorderRadius.all(Radius.circular(15)),
                          boxShadow: [BoxShadow(blurRadius: 10, color: Colors.grey[300]!, spreadRadius: 5)]),
                      height: 260,
                      child: Column(
                        children: <Widget>[
                          verticalSpaceSmall,
                          BusyButtonIcon(
                            title: 'WhatsApp',
                            onPressed: callWhatsApp,
                            mainColor: greenColor,
                            icon: MdiIcons.whatsapp,
                            enabled: widget.data.url != null,
                          ),
                          verticalSpaceSmall,
                          BusyButtonIcon(
                            title: 'QR-код чека',
                            onPressed: qrGenerate,
                            mainColor: primaryColor,
                            icon: MdiIcons.qrcode,
                            enabled: widget.data.url != null,
                          ),
                          verticalSpaceSmall,
                          BusyButtonIcon(
                            title: 'Поделиться',
                            onPressed: shareFile,
                            mainColor: yellowColor,
                            icon: Icons.share,
                          ),
                        ],
                      )));
              showFloatingActionButton(false);
              bottomSheetController.closed.then((value) {
                showFloatingActionButton(true);
              });
            },
          ),
        ],
      );
    } else {
      return Container();
    }
  }

  pressRefund() async {
    Dialogs.showLoadingDialog(context, _keyLoader);
    try {
      AppState _state = Redux.store!.state;
      String _token = _state.userState!.user!.token!;
      CardData _cardData = widget.data.cardData!;
      CheckData _checkData = CheckData.fromJson(json.decode(widget.data.voucher!.data!));
      Response<dynamic>? response =
          await _dataService.refundM4Bank(token: _token, cardData: _cardData, checkData: _checkData);
      if (response != null) {
        if (response.operation) {
          String message = response.body['message'];
          String check = response.body['check'];
          var checkText = response.body['check_text'];
          String url = response.body['link'];
          print('url : $url');
          Redux.store!.dispatch(checkMoney);
          Redux.store!.dispatch(openSmenaPseudo);
          Navigator.of(_keyLoader.currentContext!, rootNavigator: true).pop();
          _navigatorService.replace(HomeViewRoute);
          _navigatorService.push(ImageShowRoute,
              arguments: ImageShowModel(
                  data: new CheckImageModal(
                      base64Data: check, textData: checkText != null ? jsonEncode(checkText) : null),
                  title: message,
                  url: url));
        } else if (!response.operation && ![401, 402, 403, 412, 500].contains(response.status)) {
          Navigator.of(_keyLoader.currentContext!, rootNavigator: true).pop();
          _dialog.showDialog(description: response.body['message']);
        } else {
          Navigator.of(_keyLoader.currentContext!, rootNavigator: true).pop();
        }
      } else {
        Navigator.of(_keyLoader.currentContext!, rootNavigator: true).pop();
      }
    } catch (e) {
      print(e);
      Navigator.of(_keyLoader.currentContext!, rootNavigator: true).pop();
    }
  }

  void shareFile() async {
    try {
      final bytes = base64Decode(widget.data.data!.base64Data!);
      final tempDir = await getTemporaryDirectory();
      final file = File('${tempDir.path}/aman_kassa_check.png');
      await file.writeAsBytes(bytes);
      await Share.shareXFiles([XFile(file.path, mimeType: 'image/png')], subject: 'Aman Kassa');
    } catch (e) {
      print('error: $e');
    }
  }

  void qrGenerate() async {
    _navigatorService.push(QrViewRoute, arguments: ImageShowModel(url: widget.data.url, title: 'Спасибо за покупку'));
  }

  void callWhatsApp() async {
    DialogResponse response = await _dialog.showConfirmationDialogInput(
        description: 'Номер телефона', cancelTitle: 'Отмена', confirmationTitle: 'Отправить', formatType: 'phone');
    if (response.confirmed) {
      String phoneNumber = response.responseText!;
      String msg = "Спасибо за покупку! \r\n ${widget.data.url} ";
      launchWhatsApp(phone: phoneNumber, message: msg);
    }
  }

  void launchWhatsApp({
    required String phone,
    required String message,
  }) async {
    String url() {
      if (Platform.isIOS) {
        return "whatsapp://wa.me/$phone/?text=${Uri.encodeFull(message)}";
      } else {
        return "whatsapp://send?phone=$phone&text=${Uri.encodeFull(message)}";
      }
    }

    if (await canLaunch(url())) {
      await launch(url());
    } else {
      _dialog.showDialog(description: 'Отсутсвует приложение WhatsApp');
    }
  }

  void showFloatingActionButton(bool value) {
    setState(() {
      showFab = value;
    });
  }
}
