import 'package:flutter/services.dart'; import 'package:pdf/pdf.dart'; import 'package:pdf/widgets.dart' as pw; import 'package:printing/printing.dart'; import '../models/user_profile.dart'; import '../models/cycle_entry.dart'; import 'package:intl/intl.dart'; class PdfService { static Future generateCycleReport( UserProfile user, List entries) async { final pdf = pw.Document(); final logo = pw.MemoryImage( (await rootBundle.load('assets/images/logo.png')).buffer.asUint8List(), ); // Group entries by month final Map> groupedEntries = {}; for (var entry in entries) { final month = DateFormat('MMMM yyyy').format(entry.date); if (!groupedEntries.containsKey(month)) { groupedEntries[month] = []; } groupedEntries[month]!.add(entry); } // Sort months chronologically (most recent first) final sortedMonths = groupedEntries.keys.toList() ..sort((a, b) { final dateA = DateFormat('MMMM yyyy').parse(a); final dateB = DateFormat('MMMM yyyy').parse(b); return dateB.compareTo(dateA); }); pdf.addPage( pw.MultiPage( pageFormat: PdfPageFormat.a4, margin: const pw.EdgeInsets.all(32), build: (pw.Context context) { return [ pw.Row( mainAxisAlignment: pw.MainAxisAlignment.spaceBetween, children: [ pw.Column( crossAxisAlignment: pw.CrossAxisAlignment.start, children: [ pw.Text('Cycle History Report', style: pw.TextStyle( fontSize: 24, fontWeight: pw.FontWeight.bold, color: PdfColors.blueGrey900)), pw.Text('Generated for ${user.name}', style: const pw.TextStyle( fontSize: 14, color: PdfColors.blueGrey600)), pw.Text( 'Date Range: ${DateFormat('MMM yyyy').format(entries.last.date)} - ${DateFormat('MMM yyyy').format(entries.first.date)}', style: const pw.TextStyle( fontSize: 12, color: PdfColors.blueGrey400)), ], ), pw.SizedBox(height: 50, width: 50, child: pw.Image(logo)), ], ), pw.SizedBox(height: 30), for (var month in sortedMonths) ...[ pw.Column( crossAxisAlignment: pw.CrossAxisAlignment.start, children: [ pw.SizedBox(height: 10), pw.Text(month, style: pw.TextStyle( fontSize: 18, fontWeight: pw.FontWeight.bold, color: PdfColors.blueGrey800)), pw.SizedBox(height: 5), pw.TableHelper.fromTextArray( context: context, headerStyle: pw.TextStyle(fontWeight: pw.FontWeight.bold), headers: ['Date', 'Phase', 'Details', 'Notes'], data: groupedEntries[month]!.map((e) { return [ DateFormat('MMM d').format(e.date), e.isPeriodDay ? 'Period' : (e.flowIntensity == FlowIntensity.spotting ? 'Spotting' : 'Other'), e.flowIntensity != null ? 'Flow: ${e.flowIntensity.toString().split('.').last}' : '-', e.notes ?? '-', ]; }).toList(), ), pw.SizedBox(height: 20), ], ), ], ]; }, ), ); await Printing.layoutPdf( onLayout: (PdfPageFormat format) async => pdf.save(), ); } }