import 'dart:convert';

import 'package:esc_pos_bluetooth/esc_pos_bluetooth.dart';
import 'package:flutter/material.dart';
import 'package:satu/core/entity/transaction_entity.dart';
import 'package:satu/core/models/dialog_models.dart';
import 'package:satu/core/models/entity_data/transaction_data.dart';
import 'package:satu/core/models/flow/sell_response.dart';
import 'package:satu/core/models/settings/printer_setting.dart';
import 'package:satu/core/models/ui_dao/popup_item_dao.dart';
import 'package:satu/core/redux/store.dart';
import 'package:satu/core/services/data_service.dart';
import 'package:satu/core/services/dialog_service.dart';
import 'package:satu/core/services/navigator_service.dart';
import 'package:satu/core/utils/locator.dart';
import 'package:satu/core/utils/pos_printer.dart';
import 'package:satu/routes/route_names.dart';
import 'package:satu/shared/app_colors.dart';
import 'package:satu/widgets/bar/products_app_bar.dart';

class ReceiptView extends StatefulWidget {
  const ReceiptView({
    required this.transactionId,
    Key? key,
  }) : super(key: key);

  final int transactionId;

  @override
  State<ReceiptView> createState() => _ReceiptViewState();
}

class _ReceiptViewState extends State<ReceiptView> {
  final DialogService _dialogService = locator<DialogService>();
  final DataService _dataService = locator<DataService>();
  final NavigatorService _navigatorService = locator<NavigatorService>();
  PrinterBluetoothManager printerManager = PrinterBluetoothManager();
  bool printerLocked = false;

  List<PopupItemDao> menus = [];
  TransactionData transactionData = TransactionData();

  @override
  void initState() {
    loadData();

    super.initState();
  }

  void loadData() async {
    final Transaction? transaction =
        await _dataService.getTransactionById(widget.transactionId);
    final TransactionData? _transactionData =
        await _dataService.getTransactionDataById(widget.transactionId);

    if (transaction != null && transactionTypeSell == transaction.type) {
      menus.add(PopupItemDao(code: 'return', name: 'Возврат'));
    }
    //menus.add(PopupItemDao(code: 'share', name: 'Поделится'));

    setState(() {
      transactionData = _transactionData!;
      menus = menus;
    });
  }

  void printRec() async {
    setState(() {
      printerLocked = true;
    });
    try {
      PrinterSetting printerSetting = Redux.store!.state.settingState!.printer!;
      printerManager.selectPrinter(
        PrinterBluetooth(
          printerDeviceToBluetoothDevice(printerSetting.device!),
        ),
      );
      final int chunkSizeBytes = getChunkSize();
      final int queueSleepTimeMs = getQueueSleep();

      List<int> data = List.empty();
      if (PrinterConst.encodingBigEncoding == printerSetting.encoding) {
        data = await getReceiptImg(
          printerSetting.paperSize!,
          base64Decode(transactionData.sellResponse!.checkPng!),
        );
      } else {
        data = await getReceipt(printerSetting.encoding!,
            printerSetting.paperSize!, transactionData.sellResponse!.check!);
      }

      final PosPrintResult printResult = await printerManager.writeBytes(
        data,
        chunkSizeBytes: chunkSizeBytes,
        queueSleepTimeMs: queueSleepTimeMs,
      );
      if (printResult.value != 1) {
        _dialogService.showDialog(description: printResult.msg);
      }
    } finally {
      await Future.delayed(const Duration(seconds: 7));
      setState(() {
        printerLocked = false;
      });
    }
  }

  void onSelectChoice(PopupItemDao itemDao) {
    if ('return' == itemDao.code) {
      returnTransaction();
    }
  }

  void returnTransaction() async {
    DialogResponse dialogResponse = await _dialogService.showConfirmationDialog(
      description: 'Вы действительно хотете сделать возврат платежа?',
      confirmationTitle: 'Возврат',
      cancelTitle: 'Отмена',
    );
    if (dialogResponse.confirmed) {
      final int? trId =
          await _dataService.returnBtnHandler(trId: widget.transactionId);
      if (trId != null) {
        _navigatorService.pop();
        _navigatorService.push(receiptViewRoute, arguments: trId);
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: whiteColor,
      appBar: ProductsAppBar(
        title: 'Просмотр чека',
        actions: [
          PopupMenuButton<PopupItemDao>(
            onSelected: onSelectChoice,
            itemBuilder: (BuildContext context) {
              return menus.map((PopupItemDao choice) {
                return PopupMenuItem<PopupItemDao>(
                  value: choice,
                  child: Text(choice.name),
                );
              }).toList();
            },
          ),
        ],
      ),
      body: Column(
        children: [
          Expanded(
            child: SingleChildScrollView(
              physics: const BouncingScrollPhysics(),
              child: Center(
                child: imageFromBase64String(transactionData.sellResponse),
              ),
            ),
          )
        ],
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          final PrinterSetting printerSetting =
              Redux.store!.state.settingState!.printer!;
          final bool success =
              printerSetting.device != null && printerLocked == false;
          if (success) {
            printRec();
          } else {
            _dialogService.showDialog(
              description: 'Необходимо настроить принтер',
            );
          }
        },
        backgroundColor: successColor,
        child: const Icon(
          Icons.print,
          size: 25,
        ),
      ),
    );
  }
}

Widget imageFromBase64String(SellResponse? sellResponse) {
  final String? base64String = sellResponse?.checkPng;
  if (base64String == null) {
    return const Padding(
      padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 8.0),
      child: Center(
        child: Text('Отсутсвует информация о чеке'),
      ),
    );
  }
  return Padding(
    padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 8.0),
    child: Image.memory(base64Decode(base64String)),
  );
}
