// lib/screens/pdf_viewer_screen.dart import 'package:flutter/material.dart'; import 'package:syncfusion_flutter_pdfviewer/pdfviewer.dart'; import 'package:http/http.dart' as http; // Importação essencial para o download import 'dart:typed_data'; // Para lidar com os bytes import '../services/toast_service.dart'; class PdfViewerScreen extends StatefulWidget { final String pdfUrl; const PdfViewerScreen({Key? key, required this.pdfUrl}) : super(key: key); @override State createState() => _PdfViewerScreenState(); } class _PdfViewerScreenState extends State { bool _isLoading = true; Uint8List? _pdfBytes; // Variável para guardar os bytes do PDF String? _errorMessage; @override void initState() { super.initState(); // Inicia o carregamento assíncrono do PDF _loadPdf(); } // Função para buscar o PDF como bytes (Contorna o CORS) Future _loadPdf() async { try { // 🚨 CORREÇÃO PRINCIPAL: Usa http.get para contornar o problema de CORS. final response = await http.get(Uri.parse(widget.pdfUrl)); if (response.statusCode == 200) { // Sucesso: armazena os bytes _pdfBytes = response.bodyBytes; _errorMessage = null; } else { // Erro HTTP (ex: 404 Not Found) _errorMessage = 'Falha ao carregar o livro. Código HTTP: ${response.statusCode}.'; } } catch (e) { // Erro de rede (incluindo o erro de fetch/CORS) _errorMessage = 'Erro de rede ou URL inválida. Detalhes: $e'; } // Atualiza o estado se o widget ainda estiver montado if (mounted) { setState(() { _isLoading = false; }); } } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0xFF1A1A2E), body: Stack( children: [ // 1. Indicador de Carregamento if (_isLoading) const Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ CircularProgressIndicator(color: Color(0xFFE94560)), SizedBox(height: 16), Text("A carregar Livro...", style: TextStyle(color: Colors.white, fontSize: 16)), ], ), ) // 2. Visualizador do PDF (usando a memória/bytes) else if (_pdfBytes != null) // 🚨 CORREÇÃO: Usa SfPdfViewer.memory() que aceita os bytes. SfPdfViewer.memory( _pdfBytes!, onDocumentLoadFailed: (details) { // Se o arquivo for baixado mas corrompido ou inválido ToastService.show( message: 'Erro interno ao renderizar o PDF: ${details.error}', type: ToastType.error, ); }, ) // 3. Mensagem de Erro else Center( child: Padding( padding: const EdgeInsets.all(24.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const Icon(Icons.error_outline, color: Colors.red, size: 60), const SizedBox(height: 16), Text( _errorMessage ?? 'Erro desconhecido ao carregar o PDF.', textAlign: TextAlign.center, style: const TextStyle(color: Colors.white, fontSize: 16), ), const SizedBox(height: 16), ElevatedButton( onPressed: () => Navigator.of(context).pop(), style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFFE94560), foregroundColor: Colors.white, ), child: const Text('Voltar'), ), ], ), ), ), // Botão de Fechar Positioned( top: 40, left: 10, child: Container( decoration: BoxDecoration( color: Colors.black54, borderRadius: BorderRadius.circular(20), ), child: IconButton( icon: const Icon(Icons.close, color: Colors.white, size: 28), onPressed: () => Navigator.of(context).pop(), ), ), ), ], ), ); } }