import 'dart:async';

import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

import '../push/push_message_handler.dart';
import '../routing/app_routes.dart';
import '../state/app/modules/chat/bloc/chat_bloc.dart';
import '../widget/debug/debug_tile.dart';
import '../widget/debug/json_viewer.dart';
import '../widget/info_dialog.dart';
import 'notification_tasks.dart';

/// Bridges FCM lifecycle callbacks to the push pipeline. Background messages are
/// handled directly by [PushMessageHandler.onBackgroundMessage]; this class
/// covers the foreground and app-opened paths where a [BuildContext] is
/// available.
class NotificationController {
  static Future<void> onForegroundMessageHandler(
    RemoteMessage message,
    BuildContext context,
  ) async {
    final chatBloc = context.read<ChatBloc>();
    // hasOpenChat, not currentToken: currentToken sticks around after
    // leaveChat so didPopNext can re-claim a stacked chat.
    final openChatToken = chatBloc.hasOpenChat
        ? (chatBloc.state.data?.currentToken ?? '')
        : null;

    await PushMessageHandler().handle(
      message,
      foreground: true,
      openChatToken: openChatToken,
    );
    await NotificationTasks.refreshBadge();
    if (!context.mounted) return;
    NotificationTasks.updateProviders(context);
  }

  static Future<void> onAppOpenedByNotification(
    RemoteMessage message,
    BuildContext context,
  ) async {
    final newsletterId = _extractNewsletterId(message);
    if (newsletterId != null) {
      AppRoutes.openNewsletterById(
        context,
        id: newsletterId,
        title: message.notification?.title,
      );
    } else {
      NotificationTasks.navigateToTalk(
        context,
        chatToken: _extractChatToken(message),
      );
    }
    NotificationTasks.updateProviders(context);
    unawaited(NotificationTasks.refreshBadge());

    DebugTile(context).run(() {
      InfoDialog.show(
        context,
        'Dieser Bericht wird angezeigt, da du den Entwicklermodus aktiviert hast und die App über eine Benachrichtigung geöffnet wurde.\n\n'
        '${JsonViewer.format(message.data)}',
        copyable: true,
        title: 'Notification report',
      );
    });
  }

  static String? _extractChatToken(RemoteMessage message) {
    for (final key in const ['chatToken', 'token', 'roomToken']) {
      final value = message.data[key];
      if (value is String && value.isNotEmpty) return value;
    }
    return null;
  }

  static String? _extractNewsletterId(RemoteMessage message) {
    final value = message.data['newsletterId'];
    return value is String && value.isNotEmpty ? value : null;
  }
}
