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

import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
import 'package:charset_converter/charset_converter.dart';
import 'package:esc_pos_utils/esc_pos_utils.dart';
import 'package:flutter/services.dart';
import 'package:image/image.dart' as Im;
import 'package:path_provider/path_provider.dart';
import 'package:qr_flutter/qr_flutter.dart';

Future<List<int>> testTicket(PaperSize paper) async {

  final profile = await CapabilityProfile.load();
  final ticket = Generator(PaperSize.mm80, profile);
  List<int> bytes  = [];
  bytes += ticket.text(
      'Regular: aA bB cC dD eE fF gG hH iI jJ kK lL mM nN oO pP qQ rR sS tT uU vV wW xX yY zZ');
  //ticket.text('Special 1: àÀ èÈ éÉ ûÛ üÜ çÇ ôÔ', styles: PosStyles(codeTable: PosCodeTable.westEur));
  //ticket.text('Special 2: blåbærgrød', styles: PosStyles(codeTable: PosCodeTable.westEur));

  bytes += ticket.text('Bold text', styles: PosStyles(bold: true));
  bytes += ticket.text('Reverse text', styles: PosStyles(reverse: true));
  bytes += ticket.text('Underlined text',
      styles: PosStyles(underline: true), linesAfter: 1);
  bytes += ticket.text('Align left', styles: PosStyles(align: PosAlign.left));
  bytes += ticket.text('Align center', styles: PosStyles(align: PosAlign.center));
  bytes += ticket.text('Align right',
      styles: PosStyles(align: PosAlign.right), linesAfter: 1);

  bytes += ticket.row([
    PosColumn(
      text: 'col3',
      width: 3,
      styles: PosStyles(align: PosAlign.center, underline: true),
    ),
    PosColumn(
      text: 'col6',
      width: 6,
      styles: PosStyles(align: PosAlign.center, underline: true),
    ),
    PosColumn(
      text: 'col3',
      width: 3,
      styles: PosStyles(align: PosAlign.center, underline: true),
    ),
  ]);

  bytes += ticket.text('Text size 200%',
      styles: PosStyles(
        height: PosTextSize.size2,
        width: PosTextSize.size2,
      ));

  // Print image
  //final ByteData data = await rootBundle.load('assets/images/logo.png');
  //final Uint8List bytes = data.buffer.asUint8List();
  // Print image using alternative commands
  // ticket.imageRaster(image);
  // ticket.imageRaster(image, imageFn: PosImageFn.graphics);

  // Print barcode
  final List<int> barData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 4];
  bytes += ticket.barcode(Barcode.upcA(barData));



  bytes += ticket.feed(2);

  bytes += ticket.cut();
  return bytes;
}

Future<List<int>> testTicketImage(PaperSize paper) async {
  final profile = await CapabilityProfile.load();
  final ticket = Generator(paper, profile);
  List<int> bytesResult  = [];

  // Print image
  final ByteData byteData = await rootBundle.load('assets/images/check.png');
  final Uint8List bytes = byteData.buffer.asUint8List();
  final Im.Image? image = Im.decodeImage(bytes);
  // Using `ESC *`
  //ticket.image(imagea);
  // Using `GS v 0` (obsolete)
  //ticket.imageRaster(imagea);
  // Using `GS ( L`
  if(image !=null) {
    bytesResult += ticket.imageRaster(image, imageFn: PosImageFn.bitImageRaster);
  }
  //ticket.image(imagea);


  bytesResult += ticket.feed(2);

  bytesResult += ticket.cut();
  return bytesResult;
}

Future<List<int>> printImageCheck(PaperSize paper, String base64Src) async {
  final profile = await CapabilityProfile.load();
  final ticket = Generator(paper, profile);
  List<int> bytesResult  = [];
  final Uint8List bytes = base64Decode(base64Src);
  final Im.Image? image = Im.decodeImage(bytes);
  if(image != null) {
    bytesResult += ticket.imageRaster(image, imageFn: PosImageFn.bitImageRaster);
  }
  bytesResult += ticket.feed(2);
  bytesResult += ticket.cut();
  return bytesResult;
}


Future<List<int>> printTextCheck(PaperSize paper, String encoding, var data ) async {
  final profile = await CapabilityProfile.load();
  final ticket = Generator(paper, profile);
  List<int> bytesResult  = [];
  String codeTable = 'CP866';
  if(encoding == SettingPrinterEncodingCp866) {
    codeTable = 'CP866';
  } else if(encoding == SettingPrinterEncodingWin1251) {
    codeTable = 'CP1251';
  }
  ticket.setGlobalCodeTable(codeTable);
  bytesResult += ticket.emptyLines(1);
  String qr = data['qr'];


  List<dynamic> rows =  data['rows'] as List;
  for(dynamic element in rows) {
    var text = element['text'];
    int size = element['size'] as int;
    bool center = element['center'] !=null ? element['center'] as bool : false;
    if(text is List) {
      Uint8List firstCol = await CharsetConverter.encode(encoding, (text).first as String);
      Uint8List lastCol = await CharsetConverter.encode(encoding, (text).last as String);
      bytesResult += ticket.row([
        PosColumn(
          textEncoded: firstCol,
          width: 6,
          styles: PosStyles(align: PosAlign.left, codeTable: codeTable ),
        ),
        PosColumn(
          textEncoded: lastCol,
          width: 6,
          styles: PosStyles(align: PosAlign.right, codeTable: codeTable ),
        ),
      ]);
    } else {
      String line = text as String;
      if(line == 'breakline') {
        bytesResult += ticket.hr();
      } else if(line == 'br') {
        bytesResult += ticket.emptyLines(1);
      } else if(line.trim() == '') {
        bytesResult += ticket.emptyLines(1);
      } else {
        line = line.replaceAll("«", '\"');
        line = line.replaceAll("»", '\"');
        Uint8List encTxt11 = await CharsetConverter.encode(encoding, line);
        bytesResult += ticket.textEncoded( encTxt11, styles: PosStyles( align: center ? PosAlign.center : PosAlign.left, codeTable: codeTable  ));
      }
    }
  }

  // Print barcode
  //final List<int> barData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 4];
  //ticket.barcode(Barcode.upcA(barData));
  //ticket.qrcode(qr, align: PosAlign.center);
  bytesResult += ticket.emptyLines(1);
  const double qrSize = 200;
  try {
    final uiImg = await QrPainter(
      data: qr,
      version: QrVersions.auto,
      gapless: true,
    ).toImageData(qrSize);
    //final dir = await getTemporaryDirectory();
    //final pathName = '${dir.path}/qr_tmp.png';
    //final qrFile = File(pathName);
    //final imgFile = await qrFile.writeAsBytes(uiImg.buffer.asUint8List());
    if(uiImg !=null) {
      final Im.Image? img = Im.decodePng(uiImg.buffer.asUint8List());
      if(img !=null) {
        bytesResult += ticket.image(img);
      }
    }

    //ticket.qrcode(qr, size: QRSize.Size1 );
  } catch (e) {
    print(e);
  }


  bytesResult += ticket.emptyLines(1);
  bytesResult += ticket.feed(1);

  bytesResult += ticket.cut();
  return bytesResult;
}