import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;
import 'package:provider/provider.dart';
import '../../models/models.dart';
import '../../viewmodels/viewmodels.dart';
import 'package:printing/printing.dart';
import 'package:flutter/services.dart' show rootBundle;

Future<void> imprimirTicketsJuntos(BuildContext context, Pedido pedido) async {
  bool ticketCocinaActivo =
      await Provider.of<VariableViewModel>(context, listen: false)
          .isVariableActive('ticket_cocina');
  final pdf = pw.Document();
  final image = pw.MemoryImage(
    (await rootBundle.load('assets/OlivaLogo-BN.png')).buffer.asUint8List(),
  );

  pdf.addPage(
    generarPaginaPrimerTicket(pedido, image),
  );

  if (ticketCocinaActivo) {
    pdf.addPage(
      generarPaginaSegundoTicket(pedido),
    );
  }

  await printPdf(Uint8List.fromList(await pdf.save()));
}

pw.Page generarPaginaPrimerTicket(Pedido pedido, pw.MemoryImage image) {
  final numberFormat = NumberFormat('#,##0.00', 'es_MX');

  double totalSinDescuento = 0;
  double totalConDescuento = 0;
  double descuento = pedido.descuento?.toDouble() ?? 0.0;
  double precioDescuento = 0;

  final productList = pedido.productos
      .map(
        (producto) {
          final productPrice = double.parse(producto.producto?.precio ?? '0');
          final productTotal = productPrice * (producto.cantidad ?? 1);

          totalSinDescuento += productTotal;

          final toppingsList = producto.toppings.where((topping) {
            final toppingPrice = double.parse(topping.topping?.precio ?? '0');
            return toppingPrice > 0;
          }).map((topping) {
            final toppingPrice = double.parse(topping.topping?.precio ?? '0');
            totalSinDescuento += toppingPrice * (producto.cantidad ?? 1);

            return pw.Row(
              children: [
                pw.Text(
                    '- ${topping.topping?.nombre ?? "Topping no especificado"}',
                    style: const pw.TextStyle(fontSize: 7)),
                pw.Spacer(),
                pw.Text('\$${numberFormat.format(toppingPrice)}',
                    style: const pw.TextStyle(fontSize: 7)),
              ],
            );
          }).toList();

          return [
            pw.Row(
              mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
              children: [
                pw.Expanded(
                  flex: 2,
                  child: pw.Text(
                      producto.producto?.nombre ?? "Producto no especificado",
                      style: const pw.TextStyle(fontSize: 7)),
                ),
                pw.Expanded(
                  flex: 1,
                  child: pw.Text('x${producto.cantidad}',
                      style: const pw.TextStyle(fontSize: 7)),
                ),
                pw.Padding(
                  padding: pw.EdgeInsets.only(right: 2),
                  child: pw.Expanded(
                    flex: 1,
                    child: pw.Text('\$${numberFormat.format(productPrice)}',
                        style: const pw.TextStyle(fontSize: 8)),
                  ),
                )
              ],
            ),
            ...toppingsList,
          ];
        },
      )
      .expand((e) => e)
      .toList();

  precioDescuento = totalSinDescuento * (descuento / 100);
  totalConDescuento = totalSinDescuento - precioDescuento;

  return pw.Page(
      pageFormat: PdfPageFormat.roll57,
      build: (pw.Context context) {
        return pw.Column(
            crossAxisAlignment: pw.CrossAxisAlignment.center,
            children: [
              pw.Padding(
                  padding: const pw.EdgeInsets.only(right: 20),
                  child:
                      pw.Center(child: pw.Image(image, width: 50, height: 50))),
              pw.SizedBox(height: 10),
              pw.Padding(
                  padding: const pw.EdgeInsets.only(right: 15),
                  child: pw.Column(children: [
                    pw.SizedBox(height: 5),
                    pw.Text('Fecha: ${pedido.peticion}',
                        style: const pw.TextStyle(fontSize: 9)),
                    pw.Text('Oliva Mía',
                        style: const pw.TextStyle(fontSize: 9)),
                    pw.Text('Hermosillo',
                        style: const pw.TextStyle(fontSize: 9)),
                  ])),
              pw.SizedBox(height: 10),
              pw.Text('Pedido: ${pedido.folio}',
                  style: pw.TextStyle(
                      fontWeight: pw.FontWeight.bold, fontSize: 10)),
              pw.SizedBox(height: 10),
              pw.Padding(
                  padding: const pw.EdgeInsets.only(right: 20),
                  child: pw.Column(children: productList)),
              pw.Divider(),
              pw.Row(
                mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
                children: [
                  pw.Text('Subtotal:',
                      style: pw.TextStyle(
                          fontWeight: pw.FontWeight.bold, fontSize: 9)),
                  pw.Padding(
                    padding: const pw.EdgeInsets.only(right: 30),
                    child: pw.Text(
                        '\$${numberFormat.format(totalSinDescuento)}',
                        style: pw.TextStyle(
                            fontWeight: pw.FontWeight.bold, fontSize: 9)),
                  ),
                ],
              ),
              if (descuento > 0) ...[
                pw.Row(
                  mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
                  children: [
                    pw.Text('Descuento:',
                        style: pw.TextStyle(
                            fontWeight: pw.FontWeight.bold, fontSize: 9)),
                    pw.Padding(
                      padding: const pw.EdgeInsets.only(right: 30),
                      child: pw.Text(
                          '-\$${numberFormat.format(precioDescuento)}',
                          style: pw.TextStyle(
                              fontWeight: pw.FontWeight.bold, fontSize: 9)),
                    ),
                  ],
                ),
              ],
              pw.Row(
                mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
                children: [
                  pw.Text('Total:',
                      style: pw.TextStyle(
                          fontWeight: pw.FontWeight.bold, fontSize: 9)),
                  pw.Padding(
                    padding: const pw.EdgeInsets.only(right: 30),
                    child: pw.Text(
                        '\$${numberFormat.format(totalConDescuento)}',
                        style: pw.TextStyle(
                            fontWeight: pw.FontWeight.bold, fontSize: 9)),
                  ),
                ],
              ),
              pw.SizedBox(height: 5),
              pw.Padding(
                  padding: const pw.EdgeInsets.only(right: 15),
                  child: pw.Text('¡GRACIAS POR SU COMPRA!',
                      style: pw.TextStyle(
                          fontSize: 8, fontWeight: pw.FontWeight.bold))),
              pw.Divider(),
              pw.SizedBox(height: 20),
              pw.Text('.', style: pw.TextStyle(fontSize: 1)),
            ]);
      });
}

pw.Page generarPaginaSegundoTicket(Pedido pedido) {
  return pw.Page(
      pageFormat: PdfPageFormat.roll57,
      build: (pw.Context context) {
        List<pw.Widget> content = [
          pw.SizedBox(height: 20),
          pw.Text('.', style: pw.TextStyle(fontSize: 1)),
          pw.Padding(
              padding: const pw.EdgeInsets.only(right: 15),
              child: pw.Text('Fecha: ${pedido.peticion}',
                  style: pw.TextStyle(
                      fontSize: 9, fontWeight: pw.FontWeight.bold))),
          pw.SizedBox(height: 5),
          pw.Text('Pedido: ${pedido.folio}',
              style: pw.TextStyle(fontWeight: pw.FontWeight.bold, fontSize: 9)),
          pw.SizedBox(height: 10),
          pw.Text('Cliente: ${pedido.nombreCliente}',
              style: pw.TextStyle(fontWeight: pw.FontWeight.bold, fontSize: 9)),
          pw.SizedBox(height: 10),
        ];

        content.addAll(pedido.productos
            .map((producto) {
              final productPrice =
                  double.parse(producto.producto?.precio ?? '0');
              final productTotal = productPrice * (producto.cantidad ?? 1);

              final toppingsList = producto.toppings.map((topping) {
                return pw.Row(
                  children: [
                    pw.Text(
                        '-${topping.topping?.nombre ?? "Topping no especificado"}',
                        style: const pw.TextStyle(fontSize: 7)),
                  ],
                );
              }).toList();

              return [
                pw.Row(
                  mainAxisAlignment: pw.MainAxisAlignment.start,
                  children: [
                    pw.Expanded(
                      flex: 3,
                      child: pw.Text(
                          producto.producto?.nombre ??
                              "Producto no especificado",
                          style: const pw.TextStyle(fontSize: 9)),
                    ),
                    pw.Expanded(
                      flex: 1,
                      child: pw.Text('x${producto.cantidad}',
                          style: const pw.TextStyle(fontSize: 9)),
                    ),
                  ],
                ),
                ...toppingsList,
              ];
            })
            .expand((e) => e)
            .toList());

        if (pedido.comentarios != null && pedido.comentarios!.isNotEmpty) {
          content.add(pw.SizedBox(height: 10));
          content.add(pw.Text('Comentarios:',
              style:
                  pw.TextStyle(fontWeight: pw.FontWeight.bold, fontSize: 9)));
          content.add(pw.Padding(
            padding: const pw.EdgeInsets.only(right: 15),
            child: pw.Text(pedido.comentarios!,
                style: const pw.TextStyle(fontSize: 9)),
          ));
          content.add(pw.Text('.', style: pw.TextStyle(fontSize: 1)));
          content.add(pw.Text('.', style: pw.TextStyle(fontSize: 1)));
        }

        content.add(pw.SizedBox(height: 20));
        content.add(pw.Text('.', style: pw.TextStyle(fontSize: 1)));
        return pw.Column(
            crossAxisAlignment: pw.CrossAxisAlignment.center,
            children: content);
      });
}

Future<void> printPdf(Uint8List pdfBytes) async {
  await Printing.layoutPdf(
    onLayout: (PdfPageFormat format) => pdfBytes,
  );
}
