import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:intl/intl.dart';
import 'package:nb_utils/nb_utils.dart';
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;
import 'package:printing/printing.dart';
import 'package:salespro_admin/PDF/pdf_data.dart';
import 'package:salespro_admin/PDF/quation_invoice_pdf.dart';
import 'package:salespro_admin/model/personal_information_model.dart';

import '../commas.dart';
import '../const.dart';
import '../model/product_model.dart';

Future<Uint8List> generateStockReportPdf(BuildContext context, List<ProductModel>? data, PersonalInformationModel? business) async {
  final pdf = pw.Document();
  double totalAmount = 0;
  int quantity = 0;
  double totalStockValue = 0;

  final boldFont = await rootBundle.load('fonts/NotoSans/NotoSans-SemiBold.ttf');
  final notoSansBold = pw.Font.ttf(boldFont);

  final boldStyle = pw.TextStyle(
    fontSize: 15,
    font: notoSansBold,
    fontWeight: pw.FontWeight.bold,
  );

  if (data != null) {
    for (var item in data) {
      quantity += item.productStock.toInt();
    }
  }

  if (data != null) {
    for (var item in data) {
      totalStockValue += (item.productPurchasePrice.toDouble() * item.productStock.toDouble());
    }
  }

  // Calculate totals from data
  if (data != null) {
    for (var item in data) {
      // Parse the string to number safely
      totalAmount += num.tryParse(item.productPurchasePrice)?.toDouble() ?? 0;
    }
  }

  // Show loading indicator
  EasyLoading.show(status: 'Generating PDF');

  try {
    pdf.addPage(
      pw.MultiPage(
        pageFormat: PdfPageFormat.letter.copyWith(marginBottom: 1.5 * PdfPageFormat.cm),
        margin: const pw.EdgeInsets.symmetric(horizontal: 25, vertical: 25),

        //----------------pdf header--------------
        header: (pw.Context context) {
          return pw.Center(
            child: pw.Column(
              crossAxisAlignment: pw.CrossAxisAlignment.center,
              children: [
                pw.Text(
                  business?.companyName.toString() ?? 'Company Name',
                  style: pw.TextStyle(
                    fontWeight: pw.FontWeight.bold,
                    fontSize: 20,
                  ),
                ),
                pw.SizedBox(height: 2),
                pw.Text(
                  'Stock Report',
                  style: boldStyle.copyWith(fontSize: 18),
                ),
                pw.SizedBox(height: 2),
                pw.Center(
                  child: pw.Text(
                    'Date : ${DateFormat.yMMMMd().format(DateTime.parse(DateTime.now().toString()))}',
                    style: pw.TextStyle(fontSize: 14),
                  ),
                ),
                pw.SizedBox(height: 4),
              ],
            ),
          );
        },

        //-----------------pdf footer-------------
        footer: (pw.Context context) {
          return pw.Row(
            mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
            children: [
              pw.Text('Development By: YourCompany'),
              pw.Text('Page-${context.pageNumber}'),
            ],
          );
        },

        build: (pw.Context context) {
          final List<List<String>> tableData = [];

          if (data != null) {
            for (int i = 0; i < data.length; i++) {
              tableData.add([
                '${i + 1}',
                data[i].productName,
                data[i].productPurchasePrice,
                data[i].productStock.toString(),
                (data[i].productPurchasePrice.toDouble() * data[i].productStock.toDouble()).toString(),
              ]);
            }
          }

          return [
            pw.SizedBox(height: 16),

            // Main Table
            pw.Table.fromTextArray(
              headers: ['SL', 'Product Name', 'Price', 'Quantity', 'Stock Value'],
              data: tableData,
              headerDecoration: const pw.BoxDecoration(
                color: PdfColor.fromInt(0xff7500FD),
              ),
              border: pw.TableBorder.all(color: PdfColor.fromInt(0xffD9D9D9)),
              headerStyle: pw.TextStyle(
                fontWeight: pw.FontWeight.bold,
                color: PdfColors.white,
              ),
              rowDecoration: const pw.BoxDecoration(
                color: PdfColors.white,
              ),
              oddRowDecoration: pw.BoxDecoration(
                color: PdfColor.fromInt(0xffF8F8F8),
              ),
              cellPadding: const pw.EdgeInsets.all(8),
              columnWidths: {
                0: const pw.FlexColumnWidth(1),
                1: const pw.FlexColumnWidth(4),
                2: const pw.FlexColumnWidth(3),
                3: const pw.FlexColumnWidth(3),
                4: const pw.FlexColumnWidth(3),
              },
              cellAlignments: {
                0: pw.Alignment.center,
                1: pw.Alignment.centerLeft,
                2: pw.Alignment.center,
                3: pw.Alignment.center,
                4: pw.Alignment.centerRight,
              },
            ),

            // Totals row
            pw.Table.fromTextArray(
              border: const pw.TableBorder(
                left: pw.BorderSide(color: PdfColor.fromInt(0xffD9D9D9)),
                right: pw.BorderSide(color: PdfColor.fromInt(0xffD9D9D9)),
                bottom: pw.BorderSide(color: PdfColor.fromInt(0xffD9D9D9)),
              ),
              columnWidths: {
                0: const pw.FlexColumnWidth(2),
                1: const pw.FlexColumnWidth(3),
                2: const pw.FlexColumnWidth(3),
                3: const pw.FlexColumnWidth(3),
                4: const pw.FlexColumnWidth(3),
              },
              cellAlignments: {
                0: pw.Alignment.centerRight,
                1: pw.Alignment.center,
                2: pw.Alignment.center,
                3: pw.Alignment.center,
                4: pw.Alignment.centerRight,
              },
              data: [
                [
                  'Total',
                  '',
                  totalAmount,
                  quantity,
                  totalStockValue,
                ]
              ],
              headerDecoration: const pw.BoxDecoration(
                color: PdfColor.fromInt(0xff7500FD),
              ),
              headerStyle: pw.TextStyle(
                fontWeight: pw.FontWeight.bold,
                color: PdfColors.white,
              ),
              cellPadding: const pw.EdgeInsets.all(8),
            ),
          ];
        },
      ),
    );

    EasyLoading.dismiss();
    return pdf.save();
  } catch (e) {
    EasyLoading.dismiss();
    EasyLoading.showError('Error generating PDF: $e');
    print('Error during PDF generation: $e');
    rethrow;
  }
}

//-------------3 inch thermal printer---------------------------
Future<Uint8List> generate3InchStockReportPdf(BuildContext context, List<ProductModel>? data, PersonalInformationModel? personalInformation) async {
  final doc = pw.Document();
  double totalAmount = 0;
  int quantity = 0;
  double totalStockValue = 0;

  final String imageUrl = personalInformation!.pictureUrl;
  print('------------image url-------${personalInformation.pictureUrl}--------------');
  dynamic imageData = await PDFCommonFunctions().getNetworkImage(imageUrl);
  imageData ??= await PDFCommonFunctions().loadAssetImage(appLogo);
  // Load the NotoSans font
  final font = await rootBundle.load('fonts/NotoSans/NotoSans-Regular.ttf');
  final boldFont = await rootBundle.load('fonts/NotoSans/NotoSans-SemiBold.ttf');
  final notoSansBold = pw.Font.ttf(boldFont);
  final notoSans = pw.Font.ttf(font);

  // Define styles for thermal printer
  final headerStyle = pw.TextStyle(
    fontSize: 12,
    fontWeight: pw.FontWeight.bold,
    font: notoSansBold,
  );
  //------------store style---------------
  final storeStyle = pw.TextStyle(
    fontSize: 14,
    fontWeight: pw.FontWeight.bold,
    font: notoSansBold,
  );
  final normalStyle = pw.TextStyle(
    fontSize: 9,
    font: notoSans,
  );
  final smallStyle = pw.TextStyle(
    fontSize: 9,
    font: notoSans,
  );
  final boldStyle = pw.TextStyle(
    fontSize: 9,
    fontWeight: pw.FontWeight.bold,
    font: notoSansBold,
  );

  if (data != null) {
    for (var item in data) {
      quantity += item.productStock.toInt();
    }
  }

  if (data != null) {
    for (var item in data) {
      totalStockValue += (item.productPurchasePrice.toDouble() * item.productStock.toDouble());
    }
  }

  // Calculate totals from data
  if (data != null) {
    for (var item in data) {
      // Parse the string to number safely
      totalAmount += num.tryParse(item.productPurchasePrice)?.toDouble() ?? 0;
    }
  }

  try {
    EasyLoading.show(status: 'Generating PDF');

    doc.addPage(
      pw.Page(
        pageFormat: PdfPageFormat(80 * PdfPageFormat.mm, double.infinity, marginAll: 3),
        build: (pw.Context context) {
          return pw.Column(
            crossAxisAlignment: pw.CrossAxisAlignment.start,
            children: [
              /// Header Section
              /// Header Section
              // image section
              if (imageData is Uint8List)
                pw.Center(
                  child: pw.Container(
                    height: 54.12,
                    width: 52,
                    child: pw.Image(
                      pw.MemoryImage(imageData),
                      fit: pw.BoxFit.cover,
                    ),
                  ),
                )
              else if (imageData is String)
                pw.Center(
                  child: pw.Container(
                    height: 54.12,
                    width: 52,
                    child: pw.SvgImage(
                      svg: imageData,
                      fit: pw.BoxFit.cover,
                    ),
                  ),
                )
              else
                pw.Center(
                  child: pw.Container(
                    height: 54.12,
                    width: 52,
                    child: pw.Image(pw.MemoryImage(imageData)),
                  ),
                ),
              pw.SizedBox(width: 20.0),
              pw.Center(
                child: pw.Text(
                  personalInformation.companyName,
                  style: storeStyle,
                  textAlign: pw.TextAlign.center,
                ),
              ),
              pw.SizedBox(height: 2),
              pw.Center(
                child: pw.Text(
                  'Mobile: ${personalInformation.phoneNumber}',
                  style: normalStyle,
                  textAlign: pw.TextAlign.center,
                ),
              ),
              pw.SizedBox(height: 2),
              pw.Center(
                child: pw.Padding(
                  padding: pw.EdgeInsets.only(right: 22),
                  child: pw.Text(
                    'Address: ${personalInformation.countryName ?? 'n/a'}',
                    style: normalStyle,
                    textAlign: pw.TextAlign.center,
                  ),
                ),
              ),
              if (personalInformation.gst.trim().isNotEmpty) pw.SizedBox(height: 2),
              if (personalInformation.gst.trim().isNotEmpty)
                pw.Center(
                  child: pw.Text(
                    '${personalInformation.gstOrTinNameType == "" ? 'GST' : personalInformation.gstOrTinNameType}: ${personalInformation.gst}',
                    style: normalStyle,
                    textAlign: pw.TextAlign.center,
                  ),
                ),
              pw.SizedBox(height: 6),
              pw.Center(
                child: pw.DecoratedBox(
                    decoration: pw.BoxDecoration(
                      border: pw.Border(
                        bottom: pw.BorderSide(color: PdfColors.black),
                      ),
                    ),
                    child: pw.Text(
                      'Current Stock',
                      style: headerStyle,
                    )),
              ),
              pw.SizedBox(height: 14),
              // Invoice Info
              buildInfoEnd(
                title: 'Date',
                value: DateFormat.yMd().format(DateTime.parse(DateTime.now().toString())),
                normalFont: notoSans,
                boldFont: notoSans,
              ),
              pw.SizedBox(height: 2),
              buildInfo(
                title: 'Time',
                value: DateFormat.jm().format(DateTime.parse(DateTime.now().toString())),
                normalFont: notoSans,
                boldFont: notoSans,
              ),
              pw.SizedBox(height: 2),
              buildInfoEnd(
                title: 'Print By',
                value: 'Admin',
                normalFont: notoSans,
                boldFont: notoSans,
              ),
              pw.SizedBox(height: 12),
              buildDottedLine(),
              pw.Padding(
                padding: pw.EdgeInsets.symmetric(vertical: 4),
                child: pw.Row(children: [
                  pw.Container(
                    width: 20,
                    alignment: pw.Alignment.centerLeft,
                    child: pw.Text('SL', style: boldStyle),
                  ),
                  pw.Container(
                    width: 70,
                    alignment: pw.Alignment.centerLeft,
                    padding: pw.EdgeInsets.all(1),
                    child: pw.Text('Product', style: boldStyle),
                  ),
                  pw.Container(
                    width: 28,
                    alignment: pw.Alignment.center,
                    padding: pw.EdgeInsets.all(1),
                    child: pw.Text('Qty', style: boldStyle),
                  ),
                  pw.Container(
                    width: 35,
                    alignment: pw.Alignment.center,
                    padding: pw.EdgeInsets.all(1),
                    child: pw.Text('Price', style: boldStyle),
                  ),
                  pw.Container(
                    width: 46,
                    padding: pw.EdgeInsets.all(1),
                    alignment: pw.Alignment.centerRight,
                    child: pw.Text('Value', style: boldStyle),
                  ),
                ]),
              ),
              buildDottedLine(),
              pw.SizedBox(height: 2),

              /// Table Rows
              pw.Column(
                children: List.generate(
                  data!.length,
                  (i) {
                    final product = data[i];
                    return pw.Padding(
                      padding: const pw.EdgeInsets.symmetric(vertical: 1),
                      child: pw.Row(
                        crossAxisAlignment: pw.CrossAxisAlignment.start,
                        children: [
                          pw.Container(
                            width: 20,
                            alignment: pw.Alignment.centerLeft,
                            child: pw.Text('${i + 1}', style: smallStyle),
                          ),
                          pw.Container(
                            width: 70,
                            alignment: pw.Alignment.centerLeft,
                            padding: pw.EdgeInsets.all(1),
                            child: pw.Text(
                              product.productName,
                              style: smallStyle,
                            ),
                          ),
                          pw.Container(
                            width: 28,
                            alignment: pw.Alignment.center,
                            padding: pw.EdgeInsets.all(1),
                            child: pw.Text(
                              product.productStock.toString(),
                              style: smallStyle,
                              textAlign: pw.TextAlign.center,
                            ),
                          ),
                          pw.Container(
                            width: 35,
                            alignment: pw.Alignment.center,
                            padding: pw.EdgeInsets.all(1),
                            child: pw.Text(
                              myFormat.format(product.productPurchasePrice.toDouble()),
                              style: smallStyle,
                              textAlign: pw.TextAlign.center,
                            ),
                          ),
                          pw.Container(
                            width: 46,
                            alignment: pw.Alignment.centerRight,
                            padding: pw.EdgeInsets.all(1),
                            child: pw.Text(
                              myFormat.format(product.productPurchasePrice.toDouble() * product.productStock.toDouble()),
                              style: smallStyle,
                              textAlign: pw.TextAlign.center,
                            ),
                          ),
                        ],
                      ),
                    );
                  },
                ),
              ),

              /// Totals Row
              buildDottedLine(),
              pw.SizedBox(height: 6),
              pw.Align(
                alignment: pw.Alignment.centerRight,
                child: pw.SizedBox(
                    width: 160,
                    child: pw.Column(crossAxisAlignment: pw.CrossAxisAlignment.end, mainAxisAlignment: pw.MainAxisAlignment.end, children: [
                      pw.Row(
                        mainAxisAlignment: pw.MainAxisAlignment.end,
                        crossAxisAlignment: pw.CrossAxisAlignment.end,
                        children: [
                          pw.Expanded(
                            flex: 2,
                            child: pw.Text(
                              'Total Stock : ',
                              style: normalStyle,
                              textAlign: pw.TextAlign.end,
                            ),
                          ),
                          pw.Expanded(
                            child: pw.Text(
                              myFormat.format(quantity),
                              style: normalStyle,
                              textAlign: pw.TextAlign.end,
                            ),
                          ),
                          pw.SizedBox(width: 22),
                        ],
                      ),
                      pw.SizedBox(height: 4),
                      pw.Row(
                        mainAxisAlignment: pw.MainAxisAlignment.end,
                        crossAxisAlignment: pw.CrossAxisAlignment.end,
                        children: [
                          pw.Expanded(
                            flex: 2,
                            child: pw.Text(
                              'Stock Value : ',
                              style: boldStyle,
                              textAlign: pw.TextAlign.end,
                            ),
                          ),
                          pw.Expanded(
                            child: pw.Text(
                              myFormat.format(double.tryParse(totalStockValue.toString()) ?? 0),
                              style: boldStyle,
                              textAlign: pw.TextAlign.end,
                            ),
                          ),
                          pw.SizedBox(width: 22),
                        ],
                      ),
                      pw.SizedBox(height: 4),
                    ])),
              ),
              buildDottedLine(),
              pw.SizedBox(height: 6),

              /// Footer
              if (personalInformation.invoiceNote.toString().isNotEmpty)
                pw.Padding(
                  padding: pw.EdgeInsets.only(right: 22),
                  child: buildInfo(
                    title: 'Note',
                    value: personalInformation.invoiceNote.toString(),
                    normalFont: notoSansBold,
                    boldFont: notoSans,
                  ),
                ),
              pw.SizedBox(height: 6),
              pw.Center(
                child: pw.BarcodeWidget(
                  barcode: pw.Barcode.qrCode(),
                  data: 'https://acnoo.com',
                  // width: 65,
                  // height: 49,
                  width: 55,
                  height: 39,
                ),
              ),
              pw.SizedBox(height: 6),
              pw.Center(
                child: pw.Text(
                  'Developed by acnoo.com',
                  style: normalStyle,
                  textAlign: pw.TextAlign.center,
                ),
              ),
            ],
          );
        },
      ),
    );

    EasyLoading.dismiss();
    return doc.save();
  } catch (e) {
    EasyLoading.dismiss();
    EasyLoading.showError('Error generating PDF: $e');
    print('Error during PDF generation: $e');
    rethrow;
  }
}

//----------------print stock invoice----------------------------
Future<void> print3InchStockInvoice({
  required PersonalInformationModel personalInformationModel,
  required List<ProductModel> products,
  required BuildContext context,
}) async {
  try {
    EasyLoading.show(status: 'Generating PDF...', dismissOnTap: false);

    final pdfData = await generate3InchStockReportPdf(context, products, personalInformationModel);

    await Printing.layoutPdf(
      onLayout: (PdfPageFormat format) => pdfData,
    );

    EasyLoading.dismiss();
  } catch (e) {
    EasyLoading.dismiss();
    EasyLoading.showError('Failed to print: $e');
    print('Printing error: $e');
  }
}

//----------------print stock invoice----------------------------
Future<void> printStockInvoice({
  required PersonalInformationModel personalInformationModel,
  required List<ProductModel> products,
  required BuildContext context,
}) async {
  try {
    EasyLoading.show(status: 'Generating PDF...', dismissOnTap: false);

    final pdfData = await generateStockReportPdf(context, products, personalInformationModel);

    await Printing.layoutPdf(
      onLayout: (PdfPageFormat format) => pdfData,
    );

    EasyLoading.dismiss();
  } catch (e) {
    EasyLoading.dismiss();
    EasyLoading.showError('Failed to print: $e');
    print('Printing error: $e');
  }
}
