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

}