import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:printing/printing.dart'; import 'package:pdf/pdf.dart'; import '../services/pdf_service.dart'; import '../models/sake_item.dart'; import '../providers/menu_providers.dart'; import '../theme/app_theme.dart'; class PdfPreviewScreen extends ConsumerWidget { final List items; final String title; final String date; final bool includePhoto; final bool includePoem; final bool includeChart; final bool includePrice; final bool includeDate; final bool includeQr; final String pdfSize; final bool isMonochrome; const PdfPreviewScreen({ super.key, required this.items, required this.title, required this.date, required this.includePhoto, required this.includePoem, required this.includeChart, required this.includePrice, required this.includeDate, required this.includeQr, required this.pdfSize, required this.isMonochrome, }); @override Widget build(BuildContext context, WidgetRef ref) { // Phase 4: Watch new PDF Settings final isPortrait = ref.watch(pdfIsPortraitProvider); final density = ref.watch(pdfDensityProvider); return Scaffold( backgroundColor: Colors.white, // 明示的に白背景を設定 appBar: AppBar( title: const Text('お品書きプレビュー'), automaticallyImplyLeading: false, // ヘッダー戻るボタンを無効化 actions: [ IconButton( icon: const Icon(Icons.close), onPressed: () => _showExitDialog(context, ref), tooltip: '終了', ), ], ), body: PdfPreview( build: (format) => PdfService.generateMenuPdf( items, title: title, date: date, includePhoto: includePhoto, includePoem: includePoem, includeChart: includeChart, includePrice: includePrice, includeDate: includeDate, includeQr: includeQr, pdfSize: pdfSize, isMonochrome: isMonochrome, isPortrait: isPortrait, density: density, ), initialPageFormat: _getPageFormat(pdfSize, isPortrait), canChangePageFormat: false, // User selects in Edit screen canChangeOrientation: false, canDebug: false, allowSharing: false, // Handled by custom button allowPrinting: false, // Handled by custom button if needed (or share -> print) useActions: false, // Disable default bottom bar scrollViewDecoration: const BoxDecoration( color: Colors.white, ), pdfPreviewPageDecoration: BoxDecoration( color: Colors.white, // FIX: Ensure paper is white boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.3), blurRadius: 10, spreadRadius: 2, ), ], ), loadingWidget: const Center(child: CircularProgressIndicator()), onError: (context, error) => Center(child: Text('エラーが発生しました: $error')), ), bottomNavigationBar: SafeArea( child: Column( mainAxisSize: MainAxisSize.min, children: [ // 操作ガイド (フッターの真上) Container( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12), child: Center( child: Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), decoration: BoxDecoration( color: Colors.black.withValues(alpha: 0.7), borderRadius: BorderRadius.circular(8), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.touch_app, color: Colors.white, size: 16), const SizedBox(width: 8), Flexible( child: Text( 'メニュー領域を2回タップで拡大・縮小', style: TextStyle(color: Colors.white, fontSize: 12), textAlign: TextAlign.center, ), ), ], ), ), ), ), // フッターボタン Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Theme.of(context).cardColor, boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.05), blurRadius: 8, offset: const Offset(0, -2), ), ], ), child: Row( children: [ // 戻るボタン (左端) SizedBox( width: 56, height: 56, child: OutlinedButton( onPressed: () => Navigator.pop(context), style: OutlinedButton.styleFrom( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), side: BorderSide(color: Colors.grey[300]!), padding: EdgeInsets.zero, ), child: Icon(Icons.arrow_back, color: Colors.grey[700]), ), ), const SizedBox(width: 12), // 共有・ダウンロードボタン (右側いっぱいに広がる) Expanded( child: SizedBox( height: 56, child: ElevatedButton.icon( onPressed: () async { // PDF生成して共有 final bytes = await PdfService.generateMenuPdf( items, title: title, date: date, includePhoto: includePhoto, includePoem: includePoem, includeChart: includeChart, includePrice: includePrice, includeDate: includeDate, includeQr: includeQr, pdfSize: pdfSize, isMonochrome: isMonochrome, isPortrait: isPortrait, density: density, ); await Printing.sharePdf(bytes: bytes, filename: 'shinagaki.pdf'); }, style: ElevatedButton.styleFrom( backgroundColor: AppTheme.posimaiBlue, foregroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), ), icon: const Icon(Icons.share), label: const Text('共有・保存', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), ), ), ), ], ), ), ], ), ), ); } PdfPageFormat _getPageFormat(String size, bool isPortrait) { PdfPageFormat format; switch (size) { case 'a5': format = PdfPageFormat.a5; break; case 'b5': format = PdfPageFormat(257 * PdfPageFormat.mm, 182 * PdfPageFormat.mm); break; case 'a4': default: format = PdfPageFormat.a4; break; } return isPortrait ? format : format.landscape; } Future _showExitDialog(BuildContext context, WidgetRef ref) async { final confirmed = await showDialog( context: context, builder: (context) => AlertDialog( title: const Text('お品書き作成を終了しますか?'), content: const Text('入力内容は保存されません。'), actions: [ TextButton( child: const Text('キャンセル'), onPressed: () => Navigator.pop(context, false), ), ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: AppTheme.posimaiBlue, foregroundColor: Colors.white, ), onPressed: () => Navigator.pop(context, true), child: const Text('終了'), ), ], ), ); if (confirmed == true && context.mounted) { ref.read(menuModeProvider.notifier).set(false); ref.read(selectedMenuSakeIdsProvider.notifier).clear(); Navigator.of(context).popUntil((route) => route.isFirst); } } }