import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:flutter_foreground_task/flutter_foreground_task.dart';
import 'package:get/get.dart';

import 'package:shared_preferences/shared_preferences.dart';

import 'package:nearle/providers/deliverylog/deliverylog_provider.dart';
import 'package:nearle/views/helpers/constants/apiconstants.dart';
import 'package:nearle/background/foreground_service.dart' as fg;
import 'package:geolocator/geolocator.dart';

/// Controller for managing active delivery logs
/// Now delegates to the background service for actual logging
class LogController extends GetxController {
  final CreateDeliveryLogProvider _logProvider = CreateDeliveryLogProvider();

  static const String _offlineLogKey = 'offline_delivery_logs';
  bool _isFlushing = false;

  /// Start the delivery log streaming service (via foreground service)
  Future<void> startLogging() async {
    debugPrint('[ACTIVE_DELIVERY_LOG] Requesting start logging...');

    // Attempt to flush offline logs on start
    flushOfflineLogs();

    // Only show foreground notification when rider is actually on duty
    try {
      final prefs = await SharedPreferences.getInstance();
      final int onduty = prefs.getInt('onduty') ?? 0;
      if (onduty != 1) {
        debugPrint(
          '[ACTIVE_DELIVERY_LOG] Skipping startLogging because onduty=$onduty',
        );
        return;
      }
    } catch (_) {
      // If prefs fail, continue with best-effort start
    }

    if (Platform.isAndroid) {
      if (await FlutterForegroundTask.isRunningService) {
        debugPrint('[ACTIVE_DELIVERY_LOG] Foreground service already running');
        return;
      }

      debugPrint(
        '[ACTIVE_DELIVERY_LOG] Starting foreground service for delivery logs',
      );

      FlutterForegroundTask.init(
        androidNotificationOptions: AndroidNotificationOptions(
          channelId: 'nearle_bg_service',
          channelName: 'Background Service',
          channelDescription:
              'Keeps Nearle online updates running in background.',
          channelImportance: NotificationChannelImportance.LOW,
          priority: NotificationPriority.LOW,
        ),
        iosNotificationOptions: const IOSNotificationOptions(
          showNotification: true,
          playSound: false,
        ),
        foregroundTaskOptions: ForegroundTaskOptions(
          interval: 30000, // 30 seconds
          isOnceEvent: false,
          autoRunOnBoot: false,
          allowWakeLock: true,
          allowWifiLock: true,
        ),
      );

      // Check permissions before starting service to prevent Android 14 crash
      final permission = await Geolocator.checkPermission();
      if (permission == LocationPermission.denied ||
          permission == LocationPermission.deniedForever) {
        debugPrint(
          '[ACTIVE_DELIVERY_LOG] Location permission missing, skipping service start',
        );
        return;
      }

      try {
        await FlutterForegroundTask.startService(
          notificationTitle: 'Nearle is running',
          notificationText: 'You are Currently on Duty !',
          callback: fg.riderLogCallback,
        );
      } catch (e) {
        debugPrint('[ACTIVE_DELIVERY_LOG] Failed to start service: $e');
      }
    } else {
      debugPrint(
        '[ACTIVE_DELIVERY_LOG] iOS/Web not fully supported for background service yet',
      );
    }
  }

  /// Stop the delivery log streaming service
  /// Note: This might stop rider logs too if they share the service.
  /// Usually we only stop if the user goes off-duty or logs out.
  void stopLogging() {
    debugPrint(
      '[ACTIVE_DELIVERY_LOG] Stop logging requested (no-op to preserve rider logs)',
    );
    // We do not stop the service here because it might be running for Rider Logs.
    // The service should be stopped by RiderLogController when going off-duty.
  }

  // ---------------- Offline Queue Logic (Foreground Helper) ----------------

  /// Call this on app start or network restoration
  Future<void> flushOfflineLogs() async {
    if (_isFlushing) return;
    _isFlushing = true;
    try {
      final prefs = await SharedPreferences.getInstance();
      final List<String> queue = prefs.getStringList(_offlineLogKey) ?? [];
      if (queue.isEmpty) return;

      debugPrint(
        '[ACTIVE_DELIVERY_LOG][OFFLINE] Flushing ${queue.length} offline logs...',
      );

      final List<String> remaining = [];
      bool anySuccess = false;

      // Determine API endpoint
      final url = ApiConstants.mainRoute == 'live'
          ? ApiConstants.createDeliveryLogLive
          : ApiConstants.createDeliveryLogDev;

      for (final itemStr in queue) {
        try {
          final Map<String, dynamic> item = jsonDecode(itemStr);
          final String orderId = item['orderId'] ?? '';
          final Map<String, dynamic> payload = Map<String, dynamic>.from(
            item['payload'] ?? {},
          );

          if (payload.isEmpty) continue;

          debugPrint(
            '[ACTIVE_DELIVERY_LOG][OFFLINE] Retrying for orderId: $orderId',
          );

          final result = await _logProvider
              .createDeliveryLog(url, payload)
              .timeout(const Duration(seconds: 8));

          if (result != null) {
            debugPrint(
              '[ACTIVE_DELIVERY_LOG][OFFLINE] Success for orderId: $orderId',
            );
            anySuccess = true;
          } else {
            remaining.add(itemStr);
          }
        } catch (e) {
          debugPrint(
            '[ACTIVE_DELIVERY_LOG][OFFLINE] Error processing item: $e',
          );
          remaining.add(itemStr);
        }
      }

      if (anySuccess || remaining.length != queue.length) {
        await prefs.setStringList(_offlineLogKey, remaining);
        debugPrint(
          '[ACTIVE_DELIVERY_LOG][OFFLINE] Flush complete. Remaining: ${remaining.length}',
        );
      }
    } catch (e) {
      debugPrint('[ACTIVE_DELIVERY_LOG][OFFLINE] Flush error: $e');
    } finally {
      _isFlushing = false;
    }
  }
}
