import 'dart:async';

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

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

class GenerateLossProfitReport {
  Future<void> printLossProfitReport({required PersonalInformationModel personalInformationModel, required List<SaleTransactionModel> saleTransactionModel, required String fromDate, required String toDate, required String saleAmount, required String profit, required String loss, BuildContext? context, required GeneralSettingModel setting, bool? fromInventorySale}) async {
    final Uint8List pdf = await generateLossProfitReport(
      personalInformation: personalInformationModel,
      transactions: saleTransactionModel,
      fromDate: fromDate,
      toDate: toDate,
      saleAmount: saleAmount,
      profit: profit,
      loss: loss,
      generalSetting: setting,
    );

    await Printing.layoutPdf(
        dynamicLayout: true,
        onLayout: (PdfPageFormat format) async {
          return personalInformationModel.thermalPrinterPrintSize == "3 Inch (80 mm)" ? await generate3InchLossProfitReport(generalSetting: setting, personalInformation: personalInformationModel, transactions: saleTransactionModel ?? [], fromDate: fromDate, toDate: toDate, saleAmount: saleAmount, profit: profit, loss: loss) : await generateLossProfitReport(generalSetting: setting, personalInformation: personalInformationModel, transactions: saleTransactionModel ?? [], fromDate: fromDate, toDate: toDate, saleAmount: saleAmount, profit: profit, loss: loss);
        });
  }
}

///___________Pdf_Format____________________________________________________________________________________________________________________________
FutureOr<Uint8List> generateLossProfitReport({
  required List<SaleTransactionModel> transactions,
  required PersonalInformationModel personalInformation,
  required String fromDate,
  required String toDate,
  required String saleAmount,
  required String profit,
  required String loss,
  required GeneralSettingModel generalSetting,
}) async {
  final pw.Document doc = pw.Document();
  double totalAmount({required SaleTransactionModel transactions}) {
    double amount = 0;

    for (var element in transactions.productList!) {
      amount = amount + double.parse(element.subTotal) * double.parse(element.quantity.toString());
    }

    return double.parse(amount.toStringAsFixed(2));
  }

  doc.addPage(
    pw.MultiPage(
      // pageFormat: PdfPageFormat.letter.copyWith(marginBottom: 1.5 * PdfPageFormat.cm),
      margin: const pw.EdgeInsets.all(14.0),
      crossAxisAlignment: pw.CrossAxisAlignment.start,
      header: (pw.Context context) {
        return pw.Column(
          crossAxisAlignment: pw.CrossAxisAlignment.start,
          children: [
            ///________Company_Name_________________________________________________________
            pw.Center(
              child: pw.Text(
                personalInformation.companyName,
                style: pw.Theme.of(context).defaultTextStyle.copyWith(color: PdfColors.black, fontSize: 25.0, fontWeight: pw.FontWeight.bold),
              ),
            ),
            pw.Center(
              child: pw.Text(
                'Address: ${personalInformation.companyName}, Ph.no:${personalInformation.phoneNumber}',
                style: pw.Theme.of(context).defaultTextStyle.copyWith(color: PdfColors.black, fontSize: 11.0),
              ),
            ),
            pw.SizedBox(height: 10),
            pw.Center(
              child: pw.Container(
                  padding: pw.EdgeInsets.only(bottom: 2.0),
                  decoration: const pw.BoxDecoration(border: pw.Border(bottom: pw.BorderSide(color: PdfColors.black))),
                  child: pw.Text(
                    'Loss/Profit Report',
                    style: pw.Theme.of(context).defaultTextStyle.copyWith(color: PdfColors.black, fontSize: 16.0, fontWeight: pw.FontWeight.bold),
                  )),
            ),
            pw.SizedBox(height: 10),
            pw.Center(
                child: pw.Text(
              'Duration: From ${DateFormat.yMd().format(DateTime.parse(fromDate))} to ${DateFormat.yMd().format(DateTime.parse(toDate))}',
              style: pw.Theme.of(context).defaultTextStyle.copyWith(color: PdfColors.black, fontSize: 11.0),
            ))
          ],
        );
      },
      footer: (pw.Context context) {
        return pw.Column(children: [
          pw.Divider(color: PdfColors.grey600),
          pw.Center(child: pw.Text('Powered By ${generalSetting.companyName.isNotEmpty == true ? generalSetting.companyName : appsName}', style: const pw.TextStyle(fontSize: 10, color: PdfColors.black))),
        ]);
      },
      build: (pw.Context context) => <pw.Widget>[
        pw.Column(
          children: [
            pw.SizedBox(height: 20),

            ///___________Table__________________________________________________________
            pw.Table.fromTextArray(
              headerDecoration: const pw.BoxDecoration(color: PdfColors.grey200),
              context: context,
              border: const pw.TableBorder(
                left: pw.BorderSide(
                  color: PdfColors.grey600,
                ),
                right: pw.BorderSide(
                  color: PdfColors.grey600,
                ),
                bottom: pw.BorderSide(
                  color: PdfColors.grey600,
                ),
                top: pw.BorderSide(
                  color: PdfColors.grey600,
                ),
                verticalInside: pw.BorderSide(
                  color: PdfColors.grey600,
                ),
                horizontalInside: pw.BorderSide(
                  color: PdfColors.grey600,
                ),
              ),
              // headerDecoration: pw.BoxDecoration(color: PdfColor.fromHex('#D5D8DC')),
              columnWidths: <int, pw.TableColumnWidth>{
                0: const pw.FlexColumnWidth(1),
                1: const pw.FlexColumnWidth(1.5),
                2: const pw.FlexColumnWidth(1.5),
                3: const pw.FlexColumnWidth(5.0),
                4: const pw.FlexColumnWidth(2.0),
                5: const pw.FlexColumnWidth(1.7),
                6: const pw.FlexColumnWidth(1.7),
              },
              headerStyle: pw.TextStyle(color: PdfColors.black, fontSize: 11, fontWeight: pw.FontWeight.bold),
              rowDecoration: const pw.BoxDecoration(color: PdfColors.white),
              // oddRowDecoration: const pw.BoxDecoration(color: PdfColors.grey100),
              headerAlignments: <int, pw.Alignment>{
                0: pw.Alignment.center,
                1: pw.Alignment.centerLeft,
                2: pw.Alignment.center,
                3: pw.Alignment.centerLeft,
                4: pw.Alignment.center,
                5: pw.Alignment.center,
                6: pw.Alignment.center,
              },
              cellAlignments: <int, pw.Alignment>{
                0: pw.Alignment.center,
                1: pw.Alignment.centerLeft,
                2: pw.Alignment.center,
                3: pw.Alignment.centerLeft,
                4: pw.Alignment.center,
                5: pw.Alignment.center,
                6: pw.Alignment.center,
              },
              data: <List<String>>[
                <String>['SL', 'Date', 'Invoice', 'Party Name', 'Sale Amount', 'Profit', 'Loss'],
                for (int i = 0; i < transactions.length; i++)
                  <String>[
                    ('${i + 1}'),
                    (DateFormat.yMd().format(DateTime.parse(transactions.elementAt(i).purchaseDate))),
                    (transactions.elementAt(i).invoiceNumber),
                    (transactions.elementAt(i).customerName),
                    (myFormat.format(double.tryParse(transactions.elementAt(i).totalAmount.toString()) ?? 0)),
                    (myFormat.format(double.tryParse(transactions.elementAt(i).lossProfit!.isNegative ? ' 0' : transactions.elementAt(i).lossProfit!.toStringAsFixed(2)) ?? 0)),
                    (myFormat.format(double.tryParse(transactions.elementAt(i).lossProfit!.isNegative ? transactions.elementAt(i).lossProfit!.toStringAsFixed(2) : ' 0') ?? 0)),
                  ],
                <String>['', '', '', 'Sub Total:', (saleAmount.toString()), (profit.toString()), (loss.toString())],
              ],
            ),
          ],
        ),
      ],
    ),
  );
  return doc.save();
}

//---------------------------3inch thermal printer----------------------
Future<Uint8List> generate3InchLossProfitReport({
  required List<SaleTransactionModel> transactions,
  required PersonalInformationModel personalInformation,
  required String fromDate,
  required String toDate,
  required String saleAmount,
  required String profit,
  required String loss,
  required GeneralSettingModel generalSetting,
}) async {
  final doc = pw.Document();

  // 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,
  );
  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,
  );

  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
            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,
                ),
              ),
            ),
            pw.SizedBox(height: 6),
            pw.Center(
              child: pw.DecoratedBox(
                decoration: pw.BoxDecoration(
                  border: pw.Border(
                    bottom: pw.BorderSide(color: PdfColors.black),
                  ),
                ),
                child: pw.Text(
                  'LOSS/PROFIT REPORT',
                  style: headerStyle,
                ),
              ),
            ),
            pw.SizedBox(height: 6),
            pw.Center(
              child: pw.Text(
                'From ${DateFormat.yMd().format(DateTime.parse(fromDate))} to ${DateFormat.yMd().format(DateTime.parse(toDate))}',
                style: normalStyle,
                textAlign: pw.TextAlign.center,
              ),
            ),
            pw.SizedBox(height: 12),
            buildDottedLine(),

            // Table Header
            pw.Padding(
              padding: pw.EdgeInsets.symmetric(vertical: 4),
              child: pw.Row(children: [
                pw.Container(
                  width: 15,
                  alignment: pw.Alignment.centerLeft,
                  child: pw.Text('SL', style: boldStyle),
                ),
                pw.Container(
                  width: 40,
                  alignment: pw.Alignment.centerLeft,
                  child: pw.Text('Date', style: boldStyle),
                ),
                pw.Container(
                  width: 40,
                  alignment: pw.Alignment.centerLeft,
                  child: pw.Text('Invoice', style: boldStyle),
                ),
                pw.Container(
                  width: 45,
                  alignment: pw.Alignment.centerRight,
                  child: pw.Text('Amount', style: boldStyle),
                ),
                pw.Container(
                  width: 30,
                  alignment: pw.Alignment.centerRight,
                  child: pw.Text('Profit', style: boldStyle),
                ),
                pw.Container(
                  width: 30,
                  alignment: pw.Alignment.centerRight,
                  child: pw.Text('Loss', style: boldStyle),
                ),
              ]),
            ),
            buildDottedLine(),
            pw.SizedBox(height: 2),

            // Table Rows
            pw.Column(
              children: List.generate(
                transactions.length,
                (i) {
                  final transaction = transactions[i];
                  return pw.Padding(
                    padding: const pw.EdgeInsets.symmetric(vertical: 1),
                    child: pw.Row(
                      crossAxisAlignment: pw.CrossAxisAlignment.start,
                      children: [
                        pw.Container(
                          width: 15,
                          alignment: pw.Alignment.centerLeft,
                          child: pw.Text('${i + 1}', style: smallStyle),
                        ),
                        pw.Container(
                          width: 40,
                          alignment: pw.Alignment.centerLeft,
                          child: pw.Text(
                            DateFormat.Md().format(DateTime.parse(transaction.purchaseDate)),
                            style: smallStyle,
                          ),
                        ),
                        pw.Container(
                          width: 40,
                          alignment: pw.Alignment.centerLeft,
                          child: pw.Text(
                            transaction.invoiceNumber,
                            style: smallStyle,
                          ),
                        ),
                        pw.Container(
                          width: 45,
                          alignment: pw.Alignment.centerRight,
                          child: pw.Text(
                            myFormat.format(double.tryParse(transaction.totalAmount.toString()) ?? 0),
                            style: smallStyle,
                          ),
                        ),
                        pw.Container(
                          width: 30,
                          alignment: pw.Alignment.centerRight,
                          child: pw.Text(
                            myFormat.format(double.tryParse(transaction.lossProfit!.isNegative ? '0' : transaction.lossProfit!.toStringAsFixed(2)) ?? 0),
                            style: smallStyle,
                          ),
                        ),
                        pw.Container(
                          width: 30,
                          alignment: pw.Alignment.centerRight,
                          child: pw.Text(
                            myFormat.format(double.tryParse(transaction.lossProfit!.isNegative ? transaction.lossProfit!.toStringAsFixed(2) : '0') ?? 0),
                            style: smallStyle,
                          ),
                        ),
                      ],
                    ),
                  );
                },
              ),
            ),
            pw.SizedBox(height: 2),
            buildDottedLine(),

            // Summary Row
            pw.Padding(
              padding: const pw.EdgeInsets.symmetric(vertical: 1),
              child: pw.Row(
                crossAxisAlignment: pw.CrossAxisAlignment.start,
                children: [
                  pw.Container(
                    width: 15,
                    alignment: pw.Alignment.centerLeft,
                    child: pw.Text('', style: smallStyle),
                  ),
                  pw.Container(
                    width: 80,
                    alignment: pw.Alignment.centerLeft,
                    child: pw.Text('Sub Total:', style: boldStyle),
                  ),
                  pw.Container(
                    width: 45,
                    alignment: pw.Alignment.centerRight,
                    child: pw.Text(
                      saleAmount,
                      style: boldStyle,
                    ),
                  ),
                  pw.Container(
                    width: 30,
                    alignment: pw.Alignment.centerRight,
                    child: pw.Text(
                      profit,
                      style: boldStyle,
                    ),
                  ),
                  pw.Container(
                    width: 30,
                    alignment: pw.Alignment.centerRight,
                    child: pw.Text(
                      loss,
                      style: boldStyle,
                    ),
                  ),
                ],
              ),
            ),
            buildDottedLine(),
            pw.SizedBox(height: 12),

            // Footer
            pw.Center(
              child: pw.BarcodeWidget(
                barcode: pw.Barcode.qrCode(),
                data: 'https://acnoo.com',
                width: 55,
                height: 39,
              ),
            ),
            pw.SizedBox(height: 6),
            pw.Center(
              child: pw.Text(
                'Developed by acnoo.com',
                style: normalStyle,
                textAlign: pw.TextAlign.center,
              ),
            ),
          ],
        );
      },
    ),
  );

  return doc.save();
}
