// lib/widgets/lesson_detail_sheet.dart import 'package:flutter/material.dart'; import 'package:flutter_downloader/flutter_downloader.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:chewie/chewie.dart'; import 'package:video_player/video_player.dart'; import '../models/app_models.dart'; import '../services/i18n_service.dart'; import '../services/toast_service.dart'; class LessonDetailSheet extends StatefulWidget { final QuickLesson lesson; final bool isCompleted; final Function(QuickLesson) onMarkComplete; const LessonDetailSheet({ super.key, required this.lesson, required this.isCompleted, required this.onMarkComplete, }); @override State createState() => _LessonDetailSheetState(); } class _LessonDetailSheetState extends State { late VideoPlayerController _videoPlayerController; ChewieController? _chewieController; bool _isLoading = true; @override void initState() { super.initState(); _initializePlayer(); } Future _initializePlayer() async { _videoPlayerController = VideoPlayerController.network(widget.lesson.videoUrl!); await _videoPlayerController.initialize(); _chewieController = ChewieController( videoPlayerController: _videoPlayerController, autoPlay: true, looping: true, ); setState(() { _isLoading = false; }); } @override void dispose() { _videoPlayerController.dispose(); _chewieController?.dispose(); super.dispose(); } Future _downloadVideo(String url, String fileName) async { final status = await Permission.storage.request(); if (status.isGranted) { final taskId = await FlutterDownloader.enqueue( url: url, savedDir: '/storage/emulated/0/Download', fileName: fileName, showNotification: true, openFileFromNotification: true, ); // Chamada corrigida ToastService.show(message: 'Download iniciado'); } else { // Chamada corrigida, com um tipo de erro ToastService.show( message: 'Permissão de armazenamento negada', type: ToastType.error, ); } } @override Widget build(BuildContext context) { final i18n = I18nService(); return Container( decoration: const BoxDecoration( color: Color.fromARGB(255, 14, 14, 96), borderRadius: BorderRadius.vertical(top: Radius.circular(30)), boxShadow: [ BoxShadow( color: Color.fromARGB(50, 0, 0, 0), blurRadius: 20, offset: Offset(0, -5), ), ], ), child: Stack( children: [ SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildVideoPlayer(), Padding( padding: const EdgeInsets.all(24.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( widget.lesson.titulo, style: TextStyle( fontSize: 28, fontWeight: FontWeight.bold, color: Colors.deepPurple.shade900, ), ), const SizedBox(height: 12), Text( widget.lesson.conteudo!, style: TextStyle( fontSize: 16, color: Colors.grey.shade700, ), ), const SizedBox(height: 24), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ _buildDurationWidget(i18n), _buildMarkCompleteButton(i18n), ], ), const SizedBox(height: 24), _buildDownloadButton(i18n), ], ), ), ], ), ), Positioned( top: 10, right: 10, child: IconButton( onPressed: () => Navigator.pop(context), icon: Icon(Icons.close, color: Colors.grey.shade600, size: 28), ), ), ], ), ); } Widget _buildVideoPlayer() { return Container( height: 250, decoration: BoxDecoration( borderRadius: const BorderRadius.vertical(top: Radius.circular(30)), color: Colors.black, ), child: _isLoading ? const Center(child: CircularProgressIndicator(color: Color.fromARGB(255, 17, 6, 42))) : ClipRRect( borderRadius: const BorderRadius.vertical(top: Radius.circular(30)), child: Chewie(controller: _chewieController!), ), ); } Widget _buildDurationWidget(I18nService i18n) { return Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), decoration: BoxDecoration( color: Colors.deepPurple.withOpacity(0.1), borderRadius: BorderRadius.circular(20), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ const Icon(Icons.access_time_rounded, size: 20, color: Colors.deepPurple), const SizedBox(width: 8), Text( '${i18n.t('lesson_duration')}: ${widget.lesson.duracao}', style: TextStyle( fontSize: 14, color: Colors.deepPurple, fontWeight: FontWeight.w600, ), ), ], ), ); } Widget _buildMarkCompleteButton(I18nService i18n) { return ElevatedButton.icon( onPressed: widget.isCompleted ? null : () { widget.onMarkComplete(widget.lesson); Navigator.pop(context); ToastService.show(message: 'Lição concluída!'); }, icon: widget.isCompleted ? const Icon(Icons.check_circle_rounded, color: Colors.white) : const Icon(Icons.check_circle_outline_rounded, color: Colors.white), label: Text( widget.isCompleted ? i18n.t('completed') : i18n.t('mark_as_completed'), style: const TextStyle(fontWeight: FontWeight.bold), ), style: ElevatedButton.styleFrom( foregroundColor: Colors.white, backgroundColor: widget.isCompleted ? Colors.green.shade700 : Colors.deepPurple.shade600, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(25), ), padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12), elevation: 5, ), ); } Widget _buildDownloadButton(I18nService i18n) { return InkWell( onTap: () { if (widget.lesson.videoUrl != null) { _downloadVideo(widget.lesson.videoUrl!, widget.lesson.titulo!); } else { // Opcional: mostrar um toast se a URL for nula ToastService.show( message: 'URL do vídeo não disponível.', type: ToastType.error); } }, child: Container( height: 60, width: double.infinity, decoration: BoxDecoration( borderRadius: BorderRadius.circular(30), gradient: const LinearGradient( colors: [Color(0xFFE94560), Color(0xFFF07E3F)], begin: Alignment.centerLeft, end: Alignment.centerRight, ), boxShadow: [ BoxShadow( color: const Color(0xFFE94560).withOpacity(0.4), blurRadius: 10, offset: const Offset(0, 5), ), ], ), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ const Icon(Icons.cloud_download_rounded, color: Colors.white, size: 28), const SizedBox(width: 10), Text( i18n.t('download_video'), style: const TextStyle( color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold, ), ), ], ), ), ); } }