import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:live_activities/live_activities.dart';

class LiveActivitiesService {
  // Use a singleton pattern
  static final LiveActivitiesService _instance =
      LiveActivitiesService._internal();

  // LiveActivities plugin instance
  final LiveActivities _liveActivities = LiveActivities();
  bool _isInitialized = false;
  bool _isSupported = false;
  String? _appGroupId;
  String? _urlScheme;

  factory LiveActivitiesService() => _instance;
  LiveActivitiesService._internal();

  /// Initialize the Live Activities service with specific app group ID and URL scheme
  Future<bool> init(
      {required String appGroupId, required String urlScheme}) async {
    debugPrint(
        'LiveActivitiesService: Initializing with appGroupId: $appGroupId, urlScheme: $urlScheme');

    // Store directly in the instance
    _appGroupId = appGroupId;
    _urlScheme = urlScheme;

    // Initialize the plugin with the app group ID
    try {
      // Using the init method of the plugin with appGroupId
      await _liveActivities.init(appGroupId: appGroupId);
      debugPrint(
          'LiveActivitiesService: Initialized plugin with appGroupId: $appGroupId');
    } catch (e) {
      debugPrint('LiveActivitiesService: Error initializing plugin: $e');
    }

    final result = await initialize();

    // Debug verification
    debugPrint(
        'LiveActivitiesService: After init - appGroupId: $_appGroupId, initialized: $_isInitialized, supported: $_isSupported');

    return result;
  }

  /// Initialize the Live Activities service
  Future<bool> initialize() async {
    if (_isInitialized) {
      debugPrint(
          'LiveActivitiesService: Already initialized, supported: $_isSupported, appGroupId: $_appGroupId');
      return _isSupported;
    }

    // Live Activities are only supported on iOS 16.1+
    if (!Platform.isIOS) {
      debugPrint(
          'LiveActivitiesService: Platform is not iOS, Live Activities not supported');
      _isSupported = false;
      _isInitialized = true;
      return false;
    }

    try {
      // Request permissions explicitly
      final permissionGranted = await _requestLiveActivitiesPermission();
      if (!permissionGranted) {
        debugPrint('LiveActivitiesService: Permission not granted');
        _isSupported = false;
        _isInitialized = true;
        return false;
      }

      // Check if Live Activities are supported on this device
      _isSupported = await _liveActivities.areActivitiesEnabled();
      _isInitialized = true;

      debugPrint(
          'LiveActivitiesService: Initialized, supported: $_isSupported, appGroupId: $_appGroupId');
      return _isSupported;
    } catch (e) {
      debugPrint('LiveActivitiesService: Error initializing: $e');
      _isSupported = false;
      _isInitialized = true;
      return false;
    }
  }

  /// Request permission for Live Activities
  Future<bool> _requestLiveActivitiesPermission() async {
    try {
      // Check if permission is already granted
      bool alreadyGranted = await _liveActivities.areActivitiesEnabled();
      if (alreadyGranted) {
        debugPrint('LiveActivitiesService: Permission already granted');
        return true;
      }

      // iOS 16.1+ requires the user to explicitly enable Live Activities
      // There's no direct permission API, the user must enable it in Settings
      // We can only check if it's enabled, not request it directly
      debugPrint(
          'LiveActivitiesService: Checking Live Activities availability');
      final isEnabled = await _liveActivities.areActivitiesEnabled();

      if (!isEnabled) {
        debugPrint(
            'LiveActivitiesService: Live Activities not enabled. User needs to enable in Settings');
      }

      return isEnabled;
    } catch (e) {
      debugPrint('LiveActivitiesService: Error checking permission: $e');
      return false;
    }
  }

  /// Get appGroupId safely, ensuring it's available
  String? _getAppGroupId() {
    if (_appGroupId == null) {
      debugPrint(
          'LiveActivitiesService: Warning - appGroupId is null. Please call init() first.');
      debugPrint(
          'LiveActivitiesService: Current state: initialized=$_isInitialized, supported=$_isSupported');
    }
    return _appGroupId;
  }

  /// Helper method to create a search activity
  Future<String?> createSearchActivity({
    required String title,
    required String query,
    required String count,
  }) async {
    if (!_isInitialized) await initialize();
    if (!_isSupported) return null;

    try {
      // Use instance appGroupId
      final String? appGroupId = _getAppGroupId();

      // Verify appGroupId is set
      if (appGroupId == null) {
        throw Exception('appGroupId is null. Please call init() first.');
      }

      // Always reinitialize with the current app group ID to ensure it's set correctly
      await _liveActivities.init(appGroupId: appGroupId);
      debugPrint(
          'LiveActivitiesService: Ensuring plugin initialized with appGroupId: $appGroupId');

      debugPrint(
          'LiveActivitiesService: Creating activity with appGroupId: $appGroupId');

      // Create data for the activity
      final Map<String, dynamic> activityData = {
        'title': title,
        'query': query,
        'resultsCount': count,
        'timestamp': DateTime.now().toIso8601String(),
        'appGroup': appGroupId,
      };

      // Add urlScheme if available
      if (_urlScheme != null) {
        activityData['urlScheme'] = _urlScheme;
      }

      debugPrint('LiveActivitiesService: Activity data: $activityData');

      // Create the activity
      final activityId = await _liveActivities.createActivity(activityData);

      debugPrint(
          'LiveActivitiesService: Created activity with ID: $activityId');

      // Get current active activities count
      final activities = await _liveActivities.getAllActivitiesIds();
      debugPrint(
          'LiveActivitiesService: Active activities count: ${activities?.length ?? 0}');

      return activityId;
    } catch (e) {
      debugPrint('LiveActivitiesService: Error creating activity: $e');
      return null;
    }
  }

  /// Update an existing search activity
  Future<bool> updateSearchActivity({
    required String activityId,
    required String title,
    required String query,
    required String count,
  }) async {
    if (!_isInitialized) await initialize();
    if (!_isSupported) return false;

    try {
      // Use instance appGroupId
      final String? appGroupId = _getAppGroupId();

      // Verify appGroupId is set
      if (appGroupId == null) {
        throw Exception('appGroupId is null. Please call init() first.');
      }

      // Always reinitialize with the current app group ID to ensure it's set correctly
      await _liveActivities.init(appGroupId: appGroupId);
      debugPrint(
          'LiveActivitiesService: Ensuring plugin initialized with appGroupId: $appGroupId');

      // Create updated data for the activity
      final Map<String, dynamic> activityData = {
        'title': title,
        'query': query,
        'resultsCount': count,
        'timestamp': DateTime.now().toIso8601String(),
        'appGroup': appGroupId,
      };

      // Add urlScheme if available
      if (_urlScheme != null) {
        activityData['urlScheme'] = _urlScheme;
      }

      // Update the activity
      final success =
          await _liveActivities.updateActivity(activityId, activityData);

      debugPrint(
          'LiveActivitiesService: Updated activity $activityId: $success');
      return success ?? false;
    } catch (e) {
      debugPrint('LiveActivitiesService: Error updating activity: $e');
      return false;
    }
  }

  /// End an existing search activity
  Future<bool> endSearchActivity(String activityId) async {
    if (!_isInitialized) await initialize();
    if (!_isSupported) return false;

    try {
      // Get the appGroupId
      final String? appGroupId = _getAppGroupId();

      // Verify appGroupId is set
      if (appGroupId == null) {
        throw Exception('appGroupId is null. Please call init() first.');
      }

      // Always reinitialize with the current app group ID to ensure it's set correctly
      await _liveActivities.init(appGroupId: appGroupId);
      debugPrint(
          'LiveActivitiesService: Ensuring plugin initialized with appGroupId: $appGroupId');

      debugPrint('LiveActivitiesService: Ending activity $activityId');

      // End the activity
      final success = await _liveActivities.endActivity(activityId);

      debugPrint('LiveActivitiesService: Ended activity $activityId: $success');
      return success ?? false;
    } catch (e) {
      debugPrint('LiveActivitiesService: Error ending activity: $e');
      return false;
    }
  }

  /// Get all active activities
  Future<List<String>?> getActiveActivities() async {
    if (!_isInitialized) await initialize();
    if (!_isSupported) return null;

    try {
      // Get the appGroupId
      final String? appGroupId = _getAppGroupId();

      // Verify appGroupId is set
      if (appGroupId == null) {
        throw Exception('appGroupId is null. Please call init() first.');
      }

      // Always reinitialize with the current app group ID to ensure it's set correctly
      await _liveActivities.init(appGroupId: appGroupId);
      debugPrint(
          'LiveActivitiesService: Ensuring plugin initialized with appGroupId: $appGroupId');

      final activities = await _liveActivities.getAllActivitiesIds();
      debugPrint(
          'LiveActivitiesService: Found ${activities?.length ?? 0} active activities');
      return activities;
    } catch (e) {
      debugPrint('LiveActivitiesService: Error getting active activities: $e');
      return null;
    }
  }

  /// End all active activities
  Future<bool> endAllActivities() async {
    if (!_isInitialized) await initialize();
    if (!_isSupported) return false;

    try {
      // Get the appGroupId
      final String? appGroupId = _getAppGroupId();

      // Verify appGroupId is set
      if (appGroupId == null) {
        throw Exception('appGroupId is null. Please call init() first.');
      }

      // Always reinitialize with the current app group ID to ensure it's set correctly
      await _liveActivities.init(appGroupId: appGroupId);
      debugPrint(
          'LiveActivitiesService: Ensuring plugin initialized with appGroupId: $appGroupId');

      // First try using the native plugin method if available
      final success = await _liveActivities.endAllActivities();
      if (success == true) {
        debugPrint(
            'LiveActivitiesService: Ended all activities using plugin method');
        return true;
      }

      // Fallback to manual method if plugin doesn't support endAllActivities
      final activities = await getActiveActivities();
      if (activities == null || activities.isEmpty) {
        debugPrint('LiveActivitiesService: No active activities to end');
        return true;
      }

      bool allEnded = true;
      for (final activityId in activities) {
        final ended = await endSearchActivity(activityId);
        if (!ended) {
          allEnded = false;
          debugPrint(
              'LiveActivitiesService: Failed to end activity $activityId');
        }
      }

      debugPrint(
          'LiveActivitiesService: Ended ${activities.length} activities manually');
      return allEnded;
    } catch (e) {
      debugPrint('LiveActivitiesService: Error ending all activities: $e');
      return false;
    }
  }

  /// Request notification permission if needed
  Future<bool> requestNotificationPermission() async {
    if (!Platform.isIOS) return false;

    try {
      debugPrint('LiveActivitiesService: Requesting notification permission');
      // The LiveActivities plugin doesn't have a direct method to request notification permission
      // This is usually handled by the main app's notification system
      return true;
    } catch (e) {
      debugPrint(
          'LiveActivitiesService: Error requesting notification permission: $e');
      return false;
    }
  }

  /// Check if Live Activities are supported on this device
  bool get isSupported => _isSupported;

  /// Check if Live Activities are initialized
  bool get isInitialized => _isInitialized;

  /// Get the current appGroupId
  String? get appGroupId => _appGroupId;
}
