import 'dart:async';

import 'package:flutter/widgets.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';

import '../local/models/app_settings.dart';
import '../local/hive_boxes.dart';
import 'notification_inbox_service.dart';
import 'notification_service.dart';
import 'package:hive_flutter/hive_flutter.dart';

/// Phase-4 bridge for future FCM/APNs wiring.
///
/// This app currently ships without Firebase/APNs SDK setup in source control.
/// Once push SDK is configured, route incoming payloads to [ingestPayload].
class RemotePushService {
  RemotePushService._();
  static final RemotePushService instance = RemotePushService._();

  final NotificationInboxService _inbox = NotificationInboxService.instance;
  bool _initialized = false;

  Future<void> init() async {
    if (_initialized) return;
    try {
      await Firebase.initializeApp();
      final messaging = FirebaseMessaging.instance;
      await messaging.requestPermission(
        alert: true,
        badge: true,
        sound: true,
      );

      FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler);
      FirebaseMessaging.onMessage.listen((message) {
        unawaited(_handleMessage(message, isForeground: true));
      });
      FirebaseMessaging.onMessageOpenedApp.listen((message) {
        unawaited(_handleMessage(message, isForeground: false));
      });
      _initialized = true;
    } catch (_) {
      // Firebase may not be configured in all build variants yet.
    }
  }

  Future<void> ingestPayload(
    Map<String, dynamic> payload, {
    AppSettings? settings,
  }) async {
    if (settings != null && !settings.inboxEnabled) return;

    final id = (payload['id'] ?? payload['messageId'] ?? '').toString().trim();
    final title = (payload['title'] ?? '').toString().trim();
    final body = (payload['body'] ?? '').toString().trim();
    if (id.isEmpty || title.isEmpty || body.isEmpty) return;

    final type = (payload['type'] ?? 'content').toString().trim();
    final deeplink = (payload['deeplink'] ?? '').toString().trim();
    final expiresAt =
        DateTime.tryParse((payload['expiresAt'] ?? '').toString().trim());
    final isPinned = payload['isPinned'] == true;

    await _inbox.addItem(
      title: title,
      body: body,
      type: type.isEmpty ? 'content' : type,
      source: 'remote',
      deeplink: deeplink.isEmpty ? null : deeplink,
      dedupeKey: 'remote.push.$id',
      expiresAt: expiresAt,
      isPinned: isPinned,
      meta: <String, dynamic>{'remoteId': id},
    );
  }

  Future<void> _handleMessage(
    RemoteMessage message, {
    required bool isForeground,
  }) async {
    final payload = <String, dynamic>{
      'id': message.messageId ?? message.data['id'] ?? '',
      'title': message.notification?.title ?? message.data['title'] ?? '',
      'body': message.notification?.body ?? message.data['body'] ?? '',
      'type': message.data['type'] ?? 'content',
      'deeplink': message.data['deeplink'] ?? '',
      'expiresAt': message.data['expiresAt'] ?? '',
      'isPinned': message.data['isPinned'] == 'true',
    };

    final settings = Hive.box<AppSettings>(HiveBoxes.settings).get('default') ??
        AppSettings();
    await ingestPayload(payload, settings: settings);

    if (isForeground &&
        settings.alertsEnabled &&
        (payload['title'] as String).trim().isNotEmpty &&
        (payload['body'] as String).trim().isNotEmpty) {
      await NotificationService.instance.showNonPrayerAlert(
        settings: settings,
        id: NotificationService.instance
            .nonPrayerNotificationId('remote.${payload['id']}'),
        title: (payload['title'] as String).trim(),
        body: (payload['body'] as String).trim(),
        payloadType: 'remote',
        bypassDailyCap: true,
      );
    }
  }
}

@pragma('vm:entry-point')
Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  WidgetsFlutterBinding.ensureInitialized();
  await initHive();
  try {
    await Firebase.initializeApp();
  } catch (_) {}

  final payload = <String, dynamic>{
    'id': message.messageId ?? message.data['id'] ?? '',
    'title': message.notification?.title ?? message.data['title'] ?? '',
    'body': message.notification?.body ?? message.data['body'] ?? '',
    'type': message.data['type'] ?? 'content',
    'deeplink': message.data['deeplink'] ?? '',
    'expiresAt': message.data['expiresAt'] ?? '',
    'isPinned': message.data['isPinned'] == 'true',
  };
  final settings =
      Hive.box<AppSettings>(HiveBoxes.settings).get('default') ?? AppSettings();
  await RemotePushService.instance.ingestPayload(payload, settings: settings);
}
