import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_download_manager/flutter_download_manager.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:gen_service/Models/amcQuotationListResponse.dart'; import 'package:gen_service/Models/complaintListResponse.dart'; import 'package:gen_service/Models/generatorDetailsResponse.dart'; import 'package:gen_service/Models/quotationListResponse.dart'; import 'package:gen_service/Models/scheduleListResponse.dart'; import 'package:http/http.dart' as http; import 'package:intl/intl.dart'; import 'package:path_provider/path_provider.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:url_launcher/url_launcher.dart'; import '../Services/api_calling.dart'; import '../Utility/CustomSnackbar.dart'; class Generatordetailsprovider extends ChangeNotifier{ final FlutterLocalNotificationsPlugin _notificationsPlugin = FlutterLocalNotificationsPlugin(); static const platform = MethodChannel("in.webgrid.genservices/download"); final GlobalKey webViewKey = GlobalKey(); var dl = DownloadManager(); generatorDetailsResponse? _detailsResponse; scheduleListResponse? _scheduleResponse; quotationListResponse? _quotationResponse; complaintListResponse? _complaintResponse; amcQuotationListResponse? _amcQuotationResponse; bool _isLoading = false; String? _errorMessage; bool _showMoreDetails = false; generatorDetailsResponse? get detailsResponse => _detailsResponse; scheduleListResponse? get scheduleResponse => _scheduleResponse; quotationListResponse? get quotationResponse => _quotationResponse; complaintListResponse? get complaintResponse => _complaintResponse; amcQuotationListResponse? get amcQuotationResponse => _amcQuotationResponse; bool get isLoading => _isLoading; String? get errorMessage => _errorMessage; bool get showMoreDetails => _showMoreDetails; set showMoreDetails(bool value) { _showMoreDetails = value; notifyListeners(); } Future fetchGeneratorDetails(String accId, String sessionId,genId) async { _isLoading = true; _errorMessage = null; notifyListeners(); try { final response = await ApiCalling.generatorDetailsAPI(accId, sessionId,genId); if (response != null) { if (response.error == "0") { _detailsResponse = response; } else { _errorMessage = response.message ?? "Something went wrong!"; } } else { _errorMessage = "No response from server."; } } catch (e) { _errorMessage = "Failed to fetch dashboard: $e"; } finally { _isLoading = false; notifyListeners(); } } Future fetchScheduleList(String accId, String sessionId,gen_id) async { _isLoading = true; _errorMessage = null; notifyListeners(); try { final response = await ApiCalling.scheduleListAPI(accId, sessionId,gen_id); if (response != null) { if (response.error == "0") { _scheduleResponse = response; notifyListeners(); } else { _errorMessage = response.message ?? "Something went wrong!"; } } else { _errorMessage = "No response from server."; } } catch (e) { _errorMessage = "Failed to fetch dashboard: $e"; } finally { _isLoading = false; notifyListeners(); } } Future fetchQuotationList(String accId, String sessionId,genID) async { _isLoading = true; _errorMessage = null; notifyListeners(); try { final response = await ApiCalling.quotationListAPI(accId, sessionId,genID); if (response != null) { if (response.error == "0") { _quotationResponse = response; notifyListeners(); } else { _errorMessage = response.message ?? "Something went wrong!"; } } else { _errorMessage = "No response from server."; } } catch (e) { _errorMessage = "Failed to fetch dashboard: $e"; } finally { _isLoading = false; notifyListeners(); } } Future fetchComplaintList(String accId, String sessionId) async { _isLoading = true; _errorMessage = null; notifyListeners(); try { final response = await ApiCalling.complaintListAPI(accId, sessionId); if (response != null) { if (response.error == "0") { _complaintResponse = response; notifyListeners(); } else { _errorMessage = response.message ?? "Something went wrong!"; } } else { _errorMessage = "No response from server."; } } catch (e) { _errorMessage = "Failed to fetch dashboard: $e"; } finally { _isLoading = false; notifyListeners(); } } Future fetchAmcQuotationList(String accId, String sessionId,genId) async { _isLoading = true; _errorMessage = null; notifyListeners(); try { final response = await ApiCalling.amcQuoteListAPI(accId, sessionId,genId); if (response != null) { if (response.error == "0") { _amcQuotationResponse = response; notifyListeners(); } else { _errorMessage = response.message ?? "Something went wrong!"; } } else { _errorMessage = "No response from server."; } } catch (e) { _errorMessage = "Failed to fetch dashboard: $e"; } finally { _isLoading = false; notifyListeners(); } } String getUniqueFilename(String baseName, [String ext = 'pdf']) { final now = DateTime.now(); final formattedDate = DateFormat('yyyyMMdd_HHmmss').format(now); return '${baseName}_$formattedDate.$ext'; } void openWhatsApp(String path) async { final Uri url = Uri.parse(path); // Example: 919876543210 if (await canLaunchUrl(url)) { await launchUrl(url, mode: LaunchMode.externalApplication); } else { throw 'Could not launch $url'; } } Future handleDownload( context, String url, String contentDisposition, String mimeType, String suggestedFilename, ) async { // Request notification permission for Android 13+ if (Platform.isIOS) { _handleIOSDownload(context, url, suggestedFilename); } else if (Platform.isAndroid) { if (await Permission.notification.request().isGranted) { try { // Show custom notification (optional, since DownloadManager shows its own) if (Platform.isAndroid) { // Call native Android Download Manager final userAgent = 'Flutter InAppWebView'; await platform.invokeMethod('startDownload', { 'url': url, 'userAgent': userAgent, 'contentDisposition': contentDisposition, 'mimeType': mimeType, 'suggestedFilename': suggestedFilename, }); await launchUrl( Uri.parse(url), mode: LaunchMode.externalApplication, ); } else if (Platform.isIOS) { _handleIOSDownload(context, url, suggestedFilename); } } catch (e) { print("Download Error $e"); } } else { CustomSnackBar.showError( context: context, message: "Failed to Download" ); } } } Future _handleIOSDownload( context, String url, String suggestedFilename, ) async { try { // Show initial download notification await _showDownloadNotification(0, suggestedFilename, isComplete: false); // Get the temporary directory for iOS final tempDir = await getTemporaryDirectory(); final fileName = suggestedFilename.isNotEmpty ? suggestedFilename : url.split('/').last; final filePath = '${tempDir.path}/$fileName'; // Download the file using http final response = await http.get(Uri.parse(url)); if (response.statusCode == 200) { // Save the file final file = File(filePath); await file.writeAsBytes(response.bodyBytes); // Show completion notification await _showDownloadNotification(100, fileName, isComplete: true); // Optionally, open the file or notify the user CustomSnackBar.showSuccess( context: context, message: "File downloaded successfully!" ); } else { throw Exception("Failed to download file: HTTP ${response.statusCode}"); } } catch (e) { print("iOS Download Error: $e"); await _showDownloadNotification( 0, suggestedFilename, isComplete: false, isError: true, ); CustomSnackBar.showError( context: context, message: "Failed to Download" ); } } Future _showDownloadNotification( int progress, String fileName, { bool isComplete = false, bool isError = false, }) async { final androidDetails = AndroidNotificationDetails( 'download_channel', 'Downloads', channelDescription: 'Notifications for file downloads', importance: Importance.high, priority: Priority.high, showProgress: !isComplete && !isError, maxProgress: 100, progress: progress, ongoing: !isComplete && !isError, playSound: isComplete || isError, styleInformation: BigTextStyleInformation( isError ? 'Download failed for $fileName' : isComplete ? 'Download complete: $fileName' : 'Downloading $fileName...', ), ); final iosDetails = DarwinNotificationDetails( presentAlert: true, presentBadge: true, presentSound: isComplete || isError, subtitle: isError ? 'Download failed' : isComplete ? 'Download complete' : 'Downloading...', threadIdentifier: 'download_thread', ); final notificationDetails = NotificationDetails( android: androidDetails, iOS: iosDetails, ); await _notificationsPlugin.show( fileName.hashCode, // Unique ID for the notification isError ? 'Download Failed' : isComplete ? 'Download Complete' : 'Downloading File', isError ? 'Failed to download $fileName' : isComplete ? 'Successfully downloaded $fileName' : 'Downloading $fileName ($progress%)', notificationDetails, ); } }