import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/services.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:generp/Utils/commonServices.dart';
import 'package:http/http.dart' as http;
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_download_manager/flutter_download_manager.dart';
import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:generp/Utils/app_colors.dart';
import 'package:generp/Utils/commonWidgets.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'dart:math';

import 'package:flutter/widgets.dart';
import 'package:url_launcher/url_launcher.dart';

import '../services/api_calling.dart';

// const MAX_PROGRESS = 100;

Future runErpScreenApp() async {
  await FlutterDownloader.initialize(
    debug: true, // optional: set false to disable printing logs to console
  );
  await Permission.storage.request();
}

class WebErpScreen extends StatefulWidget {
  final String erp_url;

  const WebErpScreen({super.key, required this.erp_url});

  @override
  State<WebErpScreen> createState() => _WebErpScreenState();
}

class _WebErpScreenState extends State<WebErpScreen> {
  Map _source = {ConnectivityResult.mobile: true};
  final MyConnectivity _connectivity = MyConnectivity.instance;

  final Completer<InAppWebViewController> _controller =
      Completer<InAppWebViewController>();
  var empId = "";
  var sessionId = "";
  bool isLoading = true;
  InAppWebViewController? _webViewController;
  PullToRefreshController? pullToRefreshController;
  PullToRefreshSettings pullToRefreshSettings = PullToRefreshSettings(
    color: AppColors.app_blue,
  );
  bool pullToRefreshEnabled = true;
  final FlutterLocalNotificationsPlugin _notificationsPlugin =
      FlutterLocalNotificationsPlugin();
  static const platform = MethodChannel('in.webgrid.generp/download');

  final GlobalKey webViewKey = GlobalKey();
  var dl = DownloadManager();

  @override
  void initState() {
    //  loadData();
    super.initState();
    _connectivity.initialise();
    _connectivity.myStream.listen((source) {
      setState(() => _source = source);
    });
    pullToRefreshController =
        kIsWeb
            ? null
            : PullToRefreshController(
              settings: pullToRefreshSettings,
              onRefresh: () async {
                if (defaultTargetPlatform == TargetPlatform.android) {
                  _webViewController?.reload();
                } else if (defaultTargetPlatform == TargetPlatform.iOS) {
                  _webViewController?.loadUrl(
                    urlRequest: URLRequest(
                      url: await _webViewController?.getUrl(),
                    ),
                  );
                }
              },
            );
    // print("URL:${widget.url}");
    _initializeNotifications();
  }

  Future<void> _initializeNotifications() async {
    const AndroidInitializationSettings initializationSettingsAndroid =
        AndroidInitializationSettings('@mipmap/ic_launcher');
    final InitializationSettings initializationSettings =
        InitializationSettings(android: initializationSettingsAndroid);
    await _notificationsPlugin.initialize(initializationSettings);

    // Create a notification channel for Android
    const AndroidNotificationChannel channel = AndroidNotificationChannel(
      'download_channel',
      'Downloads',
      description: 'Notifications for file downloads',
      importance: Importance.high,
    );
    await _notificationsPlugin
        .resolvePlatformSpecificImplementation<
          AndroidFlutterLocalNotificationsPlugin
        >()
        ?.createNotificationChannel(channel);
  }

  @override
  void dispose() {
    super.dispose();
    _connectivity.disposeStream();
  }

  @override
  Widget build(BuildContext context) {
    switch (_source.keys.toList()[0]) {
      case ConnectivityResult.mobile:
        connection = 'Online';
        break;
      case ConnectivityResult.wifi:
        connection = 'Online';
        break;
      case ConnectivityResult.none:
      default:
        connection = 'Offline';
    }
    return WillPopScope(
      onWillPop: () async {
        if (await _webViewController!.canGoBack()) {
          _webViewController!.goBack();
          return false; // Prevent default back button behavior
        }
        return true; // Allow default back button behavior
      },
      child:
          connection == "Online"
              ? SafeArea(
                top: false,
                bottom: Platform.isIOS ? false : true,
                child: Scaffold(
                  resizeToAvoidBottomInset: true,
                  appBar: appbar(context, "ERP"),
                  body: Container(
                    child: Column(
                      children: <Widget>[
                        Expanded(
                          child: Stack(
                            children: [
                              InAppWebView(
                                initialUrlRequest: URLRequest(
                                  url: WebUri(widget.erp_url),
                                  allowsCellularAccess: true,
                                  allowsConstrainedNetworkAccess: true,
                                  allowsExpensiveNetworkAccess: true,
                                ),
                                androidOnGeolocationPermissionsShowPrompt: (
                                  InAppWebViewController controller,
                                  String origin,
                                ) async {
                                  return GeolocationPermissionShowPromptResponse(
                                    origin: origin,
                                    allow: true,
                                    retain: true,
                                  );
                                },
                                initialOptions: InAppWebViewGroupOptions(
                                  android: AndroidInAppWebViewOptions(
                                    useWideViewPort: true,
                                    loadWithOverviewMode: true,
                                    allowContentAccess: true,
                                    geolocationEnabled: true,
                                    allowFileAccess: true,
                                    databaseEnabled: true,
                                    // Enables the WebView database
                                    domStorageEnabled: true,
                                    // Enables DOM storage
                                    builtInZoomControls: true,
                                    // Enables the built-in zoom controls
                                    displayZoomControls: false,
                                    // Disables displaying zoom controls
                                    safeBrowsingEnabled: true,
                                    // Enables Safe Browsing
                                    clearSessionCache: true,
                                    loadsImagesAutomatically: true,
                                    thirdPartyCookiesEnabled: true,
                                    blockNetworkImage: false,
                                    supportMultipleWindows: true,
                                    blockNetworkLoads: false,
                                    networkAvailable: true,
                                    useShouldInterceptRequest: true,
                                    hardwareAcceleration: true,

                                    // Enable camera access
                                  ),
                                  ios: IOSInAppWebViewOptions(
                                    allowsInlineMediaPlayback: true,
                                    allowsLinkPreview: true,
                                    allowsBackForwardNavigationGestures: true,
                                  ),
                                  crossPlatform: InAppWebViewOptions(
                                    javaScriptEnabled: true,
                                    useOnDownloadStart: true,
                                    allowFileAccessFromFileURLs: true,
                                    allowUniversalAccessFromFileURLs: true,
                                    mediaPlaybackRequiresUserGesture: true,
                                  ),
                                ),

                                androidOnPermissionRequest: (
                                  InAppWebViewController controller,
                                  String origin,
                                  List<String> resources,
                                ) async {
                                  return PermissionRequestResponse(
                                    resources: resources,
                                    action:
                                        PermissionRequestResponseAction.GRANT,
                                  );
                                },
                                onPermissionRequest: (
                                  controller,
                                  request,
                                ) async {
                                  return PermissionResponse(
                                    resources: request.resources,
                                    action: PermissionResponseAction.GRANT,
                                  );
                                },
                                keepAlive: InAppWebViewKeepAlive(),

                                onWebViewCreated: (controller) {
                                  _webViewController = controller;
                                  _controller.complete(controller);

                                  // _webViewController!.addJavaScriptHandler(
                                  //   handlerName: 'downloadBlobHandler',
                                  //   callback: (args) async {
                                  //     String base64Data = args[0];
                                  //     String mimeType = args[1];
                                  //     String filename = args[2];
                                  //
                                  //     // Save the file
                                  //     await saveBase64File(base64Data, filename, mimeType);
                                  //   },
                                  // );
                                  _webViewController!.addJavaScriptHandler(
                                    handlerName: 'MobileAppJavascriptInterface',
                                    callback: (args) {
                                      print(
                                        "JavaScript called MobileAppJavascriptInterface with args: $args",
                                      );
                                      return {'status': 'success'};
                                    },
                                  );
                                  _webViewController!.addJavaScriptHandler(
                                    handlerName: 'downloadFile',
                                    callback: (args) async {
                                      if (Platform.isAndroid) {
                                        final url = args[0] as String;
                                        await _handleDownload(
                                          url,
                                          '',
                                          'application/octet-stream',
                                          '',
                                          // controller,context
                                        );
                                      }
                                    },
                                  );
                                },
                                pullToRefreshController:
                                    pullToRefreshController,
                                onLoadStart: (controller, url) {
                                  return setState(() {
                                    isLoading = true;
                                  });
                                },
                                initialSettings: InAppWebViewSettings(
                                  allowUniversalAccessFromFileURLs: true,
                                  allowFileAccessFromFileURLs: true,
                                  allowFileAccess: true,
                                  allowsInlineMediaPlayback: true,
                                  allowsPictureInPictureMediaPlayback: true,
                                  allowsBackForwardNavigationGestures: true,
                                  iframeAllow: "camera;microphone;files;media;",
                                  domStorageEnabled: true,
                                  allowContentAccess: true,
                                  javaScriptEnabled: true,
                                  supportZoom: true,
                                  builtInZoomControls: true,
                                  displayZoomControls: false,
                                  textZoom: 125,
                                  blockNetworkImage: false,
                                  loadsImagesAutomatically: true,
                                  safeBrowsingEnabled: true,
                                  useWideViewPort: true,
                                  loadWithOverviewMode: true,
                                  javaScriptCanOpenWindowsAutomatically: true,
                                  mediaPlaybackRequiresUserGesture: false,
                                  geolocationEnabled: true,
                                  useOnDownloadStart: true,
                                  allowsLinkPreview: true,
                                  databaseEnabled: true,
                                  // Enables the WebView database
                                  clearSessionCache: true,
                                  mediaType: "image/*,application/pdf",
                                  useShouldInterceptRequest: true,
                                  hardwareAcceleration: true,
                                ),
                                shouldInterceptRequest: (
                                  controller,
                                  request,
                                ) async {
                                  final url = request.url.toString();
                                  print(
                                    'Intercepting request: $url, Headers: ${request.headers}',
                                  );
                                  if (url.endsWith('.pdf')) {
                                    final response = await http.get(
                                      Uri.parse(url),
                                      headers: {'Accept': 'application/pdf'},
                                    );
                                    if (response.statusCode == 200 &&
                                        response.headers['content-type']
                                                ?.contains('application/pdf') ==
                                            true) {
                                      return WebResourceResponse(
                                        contentType: 'application/pdf',
                                        data: response.bodyBytes,
                                      );
                                    } else {
                                      print(
                                        'Failed to load PDF: Status ${response.statusCode}, Content-Type: ${response.headers['content-type']}',
                                      );
                                    }
                                  }
                                  return null;
                                },
                                shouldOverrideUrlLoading: (
                                  controller,
                                  navigationAction,
                                ) async {
                                  var uri = navigationAction.request.url!;
                                  print("urib scgefes");
                                  print(uri);
                                  print(uri.scheme);
                                  if (uri.toString().contains(
                                        'file_viewer_name.php',
                                      ) &&
                                      uri.toString().contains('.pdf')) {
                                    final pdfPath =
                                        Uri.parse(
                                          uri.toString(),
                                        ).queryParameters['file_path'];
                                    if (pdfPath != null) {
                                      final pdfUrl =
                                          'https://erp.gengroup.in/$pdfPath';
                                      await controller.loadUrl(
                                        urlRequest: URLRequest(
                                          url: WebUri(pdfUrl),
                                        ),
                                      );
                                      return NavigationActionPolicy.CANCEL;
                                    }
                                  }
                                  if (uri.scheme == "tel") {
                                    // Launch the phone dialer app with the specified phone number
                                    if (await canLaunch(uri.toString())) {
                                      await launch(uri.toString());
                                      return NavigationActionPolicy.CANCEL;
                                    }
                                  } else if (uri.scheme == "mailto") {
                                    if (await canLaunch(uri.toString())) {
                                      await launch(uri.toString());
                                      return NavigationActionPolicy.CANCEL;
                                    }
                                  } else if (uri.scheme == "whatsapp") {
                                    // Launch WhatsApp with the specified chat or phone number
                                    if (await canLaunch(uri.toString())) {
                                      await launch(uri.toString());
                                      return NavigationActionPolicy.CANCEL;
                                    }
                                  }
                                  // // Check if the URL is trying to access the camera for image upload
                                  // if (uri.scheme == 'camera' && uri.path.contains('/camera/')) {
                                  //   // Handle camera image upload here
                                  //   // You might want to display a custom UI for image selection or directly trigger the camera
                                  //   // You can use platform-specific plugins like image_picker for this purpose
                                  //   // Once the image is selected, you can pass it to the web view using JavaScript injection
                                  //   if (await canLaunch(uri.toString())) {
                                  //     await launch(uri.toString());
                                  //     return NavigationActionPolicy.CANCEL;
                                  //   }
                                  // }
                                  return NavigationActionPolicy.ALLOW;
                                },

                                onLoadStop: (controller, url) async {
                                  if (url.toString().contains(
                                        'file_viewer_name.php',
                                      ) &&
                                      url.toString().contains('.pdf')) {
                                    final uri = Uri.parse(url.toString());
                                    final pdfPath =
                                        uri.queryParameters['file_path'];
                                    if (pdfPath != null) {
                                      final pdfUrl =
                                          'https://erp.gengroup.in/$pdfPath';
                                      await controller.evaluateJavascript(
                                        source: '''
            var pdfjsLib = window.pdfjsLib || document.createElement('script');
            pdfjsLib.src = 'https://mozilla.github.io/pdf.js/build/pdf.js';
            document.head.appendChild(pdfjsLib);
            pdfjsLib.onload = function() {
              pdfjsLib.getDocument('$pdfUrl').promise.then(function(pdf) {
                pdf.getPage(1).then(function(page) {
                  var canvas = document.createElement('canvas');
                  document.body.appendChild(canvas);
                  var context = canvas.getContext('2d');
                  var viewport = page.getViewport({ scale: 1.0 });
                  canvas.height = viewport.height;
                  canvas.width = viewport.width;
                  page.render({
                    canvasContext: context,
                    viewport: viewport
                  });
                });
              }).catch(function(error) {
                console.error('PDF.js error: ' + error);
              });
            };
          ''',
                                      );
                                    }
                                  }
                                  pullToRefreshController?.endRefreshing();
                                  return setState(() {
                                    isLoading = false;
                                  });
                                },
                                onReceivedError: (controller, request, error) {
                                  pullToRefreshController?.endRefreshing();
                                  return setState(() {
                                    isLoading = false;
                                  });
                                },
                                onProgressChanged: (controller, progress) {
                                  if (progress == 100) {
                                    pullToRefreshController?.endRefreshing();
                                  }
                                },
                                onConsoleMessage: (controller, consoleMessage) {
                                  if (kDebugMode) {
                                    debugPrint("consoleMessage$consoleMessage");
                                  }
                                  debugPrint(
                                    "JavaScript console message: ${consoleMessage.message}",
                                  );
                                },

                                // onDownloadStartRequest: (controller, url) async {
                                //   await ApiCalling.download_files(
                                //       empId, sessionId, "${url.url}", context)
                                //       .then((data) => {debugPrint(data)});
                                //
                                // },
                                onDownloadStartRequest: (
                                  controller,
                                  downloadStartRequest,
                                ) async {
                                  // String url = downloadStartRequest.url.toString();
                                  //
                                  // // Use url_launcher or another plugin to handle the download externally
                                  // if (await canLaunchUrl(Uri.parse(url))) {
                                  //   await launchUrl(
                                  //     Uri.parse(url),
                                  //     mode: LaunchMode.externalApplication,
                                  //   );
                                  // } else {
                                  //   print("Could not launch $url");
                                  // }
                                  if (Platform.isAndroid) {
                                    await _handleDownload(
                                      downloadStartRequest.url.toString(),
                                      downloadStartRequest.suggestedFilename!,
                                      downloadStartRequest.mimeType!,
                                      downloadStartRequest.suggestedFilename ??
                                          '',
                                      // controller,context
                                    );
                                  }
                                },
                              ),
                              if (isLoading) ...[
                                Container(
                                  color: Colors.white.withOpacity(0.7),
                                  child: Column(
                                    crossAxisAlignment:
                                        CrossAxisAlignment.center,
                                    mainAxisAlignment: MainAxisAlignment.center,
                                    children: [
                                      SpinKitRing(
                                        color: AppColors.app_blue,
                                        lineWidth: 4,
                                        // duration: Duration(seconds: 2),
                                        size: 50,
                                      ),
                                      const SizedBox(height: 15),
                                      SizedBox(
                                        width: 200,
                                        child: Text(
                                          "Please wait.......",
                                          textAlign: TextAlign.center,
                                          style: TextStyle(
                                            decorationThickness: 0,
                                            fontSize: 15,
                                            fontWeight: FontWeight.normal,
                                            color: AppColors.app_blue,
                                          ),
                                        ),
                                      ),

                                      // SvgPicture.asset("/assets/images/NutsLoader.gif")
                                    ],
                                  ),
                                ),
                              ],
                            ],
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
              )
              : NoNetwork(context),
    );
  }

  // Future<void> saveBase64File(String base64Data, String filename, String mimeType) async {
  //   // Ask for permission
  //   if (await Permission.storage.request().isGranted) {
  //     final bytes = base64.decode(base64Data.split(',').last);
  //     final directory = await getExternalStorageDirectory(); // or getApplicationDocumentsDirectory()
  //     final path = "${directory!.path}/$filename";
  //     final file = File(path);
  //
  //     await file.writeAsBytes(bytes);
  //     print("File saved to: $path");
  //   } else {
  //     print("Storage permission denied.");
  //   }
  // }
  // Future<void> _handleDownload(
  //     String url,
  //     String contentDisposition,
  //     String mimeType,
  //     String suggestedFilename,
  //     InAppWebViewController controller,
  //     BuildContext context, // Add context for toast
  //     ) async {
  //   print("URL: $url");
  //   print("MimeType: $mimeType");
  //   print("SuggestedFilename: $suggestedFilename");
  //   print("ContentDisposition: $contentDisposition");
  //
  //   if (Platform.isAndroid) {
  //     if (await Permission.notification.request().isGranted) {
  //       try {
  //         final userAgent = 'Flutter InAppWebView';
  //         if (url.startsWith('blob:')) {
  //           print("Attempting to convert blob URL...");
  //           final blobContent = await _convertBlobToDataUrl(url, controller);
  //           if (blobContent != null) {
  //             print("Blob converted to data URL: ${blobContent.substring(0, 50)}..."); // Log first 50 chars
  //             await platform.invokeMethod('startDownload', {
  //               'url': blobContent,
  //               'userAgent': userAgent,
  //               'contentDisposition': contentDisposition,
  //               'mimeType': mimeType,
  //               'suggestedFilename': suggestedFilename,
  //               'isBase64': true,
  //             });
  //             ScaffoldMessenger.of(context).showSnackBar(
  //               SnackBar(content: Text("Download started: $suggestedFilename")),
  //             );
  //           } else {
  //             print("Failed to convert blob URL");
  //             ScaffoldMessenger.of(context).showSnackBar(
  //               SnackBar(content: Text("Failed to resolve blob URL")),
  //             );
  //           }
  //         } else {
  //           print("Handling non-blob URL");
  //           await platform.invokeMethod('startDownload', {
  //             'url': url,
  //             'userAgent': userAgent,
  //             'contentDisposition': contentDisposition,
  //             'mimeType': mimeType,
  //             'suggestedFilename': suggestedFilename,
  //             'isBase64': false,
  //           });
  //         }
  //       } catch (e, stackTrace) {
  //         print("Download Error: $e");
  //         print("StackTrace: $stackTrace");
  //         ScaffoldMessenger.of(context).showSnackBar(
  //           SnackBar(content: Text("Download failed: $e")),
  //         );
  //       }
  //     } else {
  //       print("Notification Permission Denied");
  //       ScaffoldMessenger.of(context).showSnackBar(
  //         SnackBar(content: Text("Notification Permission Denied")),
  //       );
  //     }
  //   } else if (Platform.isIOS) {
  //     _handleIOSDownload(url, suggestedFilename);
  //   }
  // }
  //
  // Future<String?> _convertBlobToDataUrl(String blobUrl, InAppWebViewController controller) async {
  //   try {
  //     final result = await controller.evaluateJavascript(
  //       source: """
  //       (async function() {
  //         try {
  //           const response = await fetch('$blobUrl');
  //           if (!response.ok) {
  //             console.error('Fetch failed with status: ' + response.status);
  //             return null;
  //           }
  //           const blob = await response.blob();
  //           return new Promise((resolve) => {
  //             const reader = new FileReader();
  //             reader.onloadend = () => resolve(reader.result);
  //             reader.onerror = () => resolve(null);
  //             reader.readAsDataURL(blob);
  //           });
  //         } catch (e) {
  //           console.error('Blob conversion error: ' + e.message);
  //           return null;
  //         }
  //       })();
  //       """,
  //     );
  //     if (result != null && result.toString().startsWith('data:')) {
  //       print("Blob conversion successful, data URL length: ${result.toString().length}");
  //       return result.toString();
  //     } else {
  //       print("Blob conversion failed, result: $result");
  //       return null;
  //     }
  //   } catch (e, stackTrace) {
  //     print("Blob conversion error: $e");
  //     print("StackTrace: $stackTrace");
  //     return null;
  //   }
  // }
  void handleBlobDownload(String blobUrl, String filename) async {
    final js = """
    (async function() {
      const blobUrl = "$blobUrl";
      const response = await fetch(blobUrl);
      const blob = await response.blob();
      const reader = new FileReader();
      reader.onloadend = function() {
        window.flutter_inappwebview.callHandler('downloadBlobHandler', reader.result, blob.type, "$filename");
      };
      reader.readAsDataURL(blob);
    })();
  """;

    _webViewController?.evaluateJavascript(source: js);
  }

  Future<void> _handleDownload(
    String url,
    String contentDisposition,
    String mimeType,
    String suggestedFilename,
  ) async {
    print("mimeType4: $mimeType");
    print("mimeType4: $suggestedFilename");
    // Request notification permission for Android 13+
    if (Platform.isIOS) {
      _handleIOSDownload(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,
            });
          } else if (Platform.isIOS) {
            _handleIOSDownload(url, suggestedFilename);
          }
        } catch (e) {
          print("Download Error $e");
        }
      } else {
        toast(context, "Notification Permission Denied");
      }
    }
  }

  Future<void> _handleIOSDownload(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
        toast(context, "File downloaded to $filePath");
      } 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,
      );
      toast(context, "Failed to download file: $e");
    }
  }

  Future<void> _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,
    );
  }
}

class SpinKitRing extends StatefulWidget {
  const SpinKitRing({
    super.key,
    required this.color,
    this.lineWidth = 7.0,
    this.size = 50.0,
    this.duration = const Duration(milliseconds: 1200),
    this.controller,
  });

  final Color color;
  final double size;
  final double lineWidth;
  final Duration duration;
  final AnimationController? controller;

  @override
  State<SpinKitRing> createState() => _SpinKitRingState();
}

class _SpinKitRingState extends State<SpinKitRing>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _animation1;
  late Animation<double> _animation2;
  late Animation<double> _animation3;

  @override
  void initState() {
    super.initState();

    _controller =
        (widget.controller ??
              AnimationController(vsync: this, duration: widget.duration))
          ..addListener(() {
            if (mounted) {
              setState(() {});
            }
          })
          ..repeat();
    _animation1 = Tween(begin: 0.0, end: 1.0).animate(
      CurvedAnimation(
        parent: _controller,
        curve: const Interval(0.0, 1.0, curve: Curves.linear),
      ),
    );
    _animation2 = Tween(begin: -2 / 3, end: 1 / 2).animate(
      CurvedAnimation(
        parent: _controller,
        curve: const Interval(0.5, 1.0, curve: Curves.linear),
      ),
    );
    _animation3 = Tween(begin: 0.25, end: 5 / 6).animate(
      CurvedAnimation(
        parent: _controller,
        curve: const Interval(0.0, 1.0, curve: SpinKitRingCurve()),
      ),
    );
  }

  @override
  void dispose() {
    if (widget.controller == null) {
      _controller.dispose();
    }
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Transform(
        transform:
            Matrix4.identity()..rotateZ((_animation1.value) * 5 * pi / 6),
        alignment: FractionalOffset.center,
        child: SizedBox.fromSize(
          size: Size.square(widget.size),
          child: CustomPaint(
            foregroundPainter: RingPainter(
              paintWidth: widget.lineWidth,
              trackColor: widget.color,
              progressPercent: _animation3.value,
              startAngle: pi * _animation2.value,
            ),
          ),
        ),
      ),
    );
  }
}

class RingPainter extends CustomPainter {
  RingPainter({
    required this.paintWidth,
    this.progressPercent,
    this.startAngle,
    required this.trackColor,
  }) : trackPaint =
           Paint()
             ..color = trackColor
             ..style = PaintingStyle.stroke
             ..strokeWidth = paintWidth
             ..strokeCap = StrokeCap.square;

  final double paintWidth;
  final Paint trackPaint;
  final Color trackColor;
  final double? progressPercent;
  final double? startAngle;

  @override
  void paint(Canvas canvas, Size size) {
    final center = Offset(size.width / 2, size.height / 2);
    final radius = (min(size.width, size.height) - paintWidth) / 2;
    canvas.drawArc(
      Rect.fromCircle(center: center, radius: radius),
      startAngle!,
      2 * pi * progressPercent!,
      false,
      trackPaint,
    );
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) => true;
}

class SpinKitRingCurve extends Curve {
  const SpinKitRingCurve();

  @override
  double transform(double t) => (t <= 0.5) ? 2 * t : 2 * (1 - t);
}
