import 'package:blind_master/BlindMasterResources/secure_transmissions.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';

/// Bridge to the native iOS APNs registration in `ios/Runner/AppDelegate.swift`.
/// The Swift side captures the device token in
/// `didRegisterForRemoteNotificationsWithDeviceToken`, hex-encodes it, and
/// pushes it back here over the `blindmaster/apns` MethodChannel. We then POST
/// it to `/register_apns_token` so the server can target this device.
///
/// Mirrors the LockInBroMobile NotificationService flow — Android has no APNs
/// equivalent and the backend only supports APNs, so this is a no-op there.
class ApnsService {
  static const _channel = MethodChannel('blindmaster/apns');
  static bool _handlerInstalled = false;

  /// Wire the channel handler once at startup so a token delivered before the
  /// first `register()` call (or after, asynchronously) is still uploaded.
  static void install() {
    if (_handlerInstalled) return;
    if (defaultTargetPlatform != TargetPlatform.iOS &&
        defaultTargetPlatform != TargetPlatform.macOS) {
      return;
    }
    _handlerInstalled = true;
    _channel.setMethodCallHandler((call) async {
      if (call.method == 'onToken') {
        final token = call.arguments as String?;
        if (token == null || token.isEmpty) return;
        debugPrint('APNS: token received');
        try {
          await securePost({'token': token}, 'register_apns_token');
        } catch (e) {
          debugPrint('APNS: token upload failed: $e');
        }
      }
    });
  }

  /// Request notification permission and upload the cached token if APNs has
  /// already produced one. Safe to call repeatedly (login + session-restore) —
  /// the server upserts.
  static Future<void> register() async {
    if (defaultTargetPlatform != TargetPlatform.iOS &&
        defaultTargetPlatform != TargetPlatform.macOS) {
      return;
    }
    install();
    try {
      final granted =
          await _channel.invokeMethod<bool>('requestPermission') ?? false;
      if (!granted) {
        debugPrint('APNS: notifications denied — enable in Settings');
        return;
      }
      final token = await _channel.invokeMethod<String?>('getToken');
      if (token == null || token.isEmpty) {
        debugPrint('APNS: token not ready yet — onToken handler will catch it');
        return;
      }
      await securePost({'token': token}, 'register_apns_token');
    } catch (e) {
      debugPrint('APNS registration failed: $e');
    }
  }
}
