import 'dart:io';

import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:matrix/matrix.dart';
import 'package:shared_preferences/shared_preferences.dart';

// Self-hosted Sygnal instance on the Pi — must be configured with the
// Firebase service account for the 'chat-pyramid' Firebase project.
// push.element.io only supports Element's own apps and will actively reject
// chat.pyramid.pyramid pushkeys, causing the homeserver to auto-remove the pusher.
const _kGatewayUrl = 'https://push.steggi-matrix.work/_matrix/push/v1/notify';
const _kAppId = 'chat.pyramid.pyramid';

// ── Foreground-Setup & Pusher-Registrierung ───────────────────────────────────

Future<String> fcmDiagnostics(Client matrixClient) async {
  if (!Platform.isAndroid) return 'Kein Android';
  final buf = StringBuffer();
  try {
    await Firebase.initializeApp();
    buf.writeln('✓ Firebase initialisiert');
  } catch (e) {
    buf.writeln('✗ Firebase-Init: $e');
    return buf.toString();
  }
  try {
    final settings = await FirebaseMessaging.instance.requestPermission();
    buf.writeln('✓ Berechtigung: ${settings.authorizationStatus.name}');
  } catch (e) {
    buf.writeln('✗ Berechtigung: $e');
  }
  try {
    final token = await FirebaseMessaging.instance.getToken();
    if (token != null) {
      buf.writeln('✓ FCM-Token: ${token.substring(0, 20)}…');
    } else {
      buf.writeln('✗ FCM-Token: null');
    }
  } catch (e) {
    buf.writeln('✗ FCM-Token: $e');
  }
  try {
    final pushers = await matrixClient.getPushers() ?? [];
    final fcmPushers = pushers.where((p) => p.appId == _kAppId).toList();
    if (fcmPushers.isEmpty) {
      buf.writeln('✗ Pusher: keiner bei Synapse registriert!');
    } else {
      buf.writeln('✓ Pusher: ${fcmPushers.length} registriert');
    }
  } catch (e) {
    buf.writeln('✗ Pusher-Abfrage: $e');
  }
  return buf.toString();
}

Future<void> initFcm(Client matrixClient) async {
  if (!Platform.isAndroid) return;

  try {
    await Firebase.initializeApp();
  } catch (_) {
    // Bereits initialisiert (main.dart) oder google-services.json fehlt – weiter
  }

  // Background messages are handled by handleBackgroundMessage (background_push.dart)
  // via FlutterFirebaseMessagingService. It decrypts E2EE events using the Matrix
  // SDK and shows notifications via flutter_local_notifications with
  // showsUserInterface:false so no Activity opens when the user replies.

  // Notification-Berechtigung anfordern (Android 13+)
  await FirebaseMessaging.instance.requestPermission();

  // Foreground-Notifications unterdrücken — App zeigt selbst Nachrichten
  await FirebaseMessaging.instance
      .setForegroundNotificationPresentationOptions(
    alert: false,
    badge: false,
    sound: false,
  );

  // Re-register pusher if token was refreshed while the app was killed.
  final prefs = await SharedPreferences.getInstance();
  final pendingToken = prefs.getString('flutter.fcm_pending_token');
  if (pendingToken != null && matrixClient.isLogged()) {
    await _registerPusher(matrixClient, pendingToken);
    await prefs.remove('flutter.fcm_pending_token');
  }

  final token = pendingToken ?? await _getToken();
  if (token != null && matrixClient.isLogged()) {
    await _registerPusher(matrixClient, token);
    // Save homeserver + token for PushService.kt (Kotlin native notification handler)
    await _saveNotifCredentials(matrixClient);
  }

  // Bei Token-Refresh: Pusher + gespeicherte Credentials aktualisieren
  FirebaseMessaging.instance.onTokenRefresh.listen((newToken) async {
    if (matrixClient.isLogged()) {
      await _registerPusher(matrixClient, newToken);
      await _saveNotifCredentials(matrixClient);
    }
  });
}

Future<void> _saveNotifCredentials(Client client) async {
  try {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString('notif_homeserver', client.homeserver.toString());
    await prefs.setString('notif_access_token', client.accessToken ?? '');
  } catch (_) {}
}

Future<String?> _getToken() async {
  try {
    return await FirebaseMessaging.instance.getToken();
  } catch (_) {
    return null;
  }
}

Future<void> _registerPusher(Client client, String fcmToken) async {
  try {
    await client.postPusher(
      Pusher(
        pushkey: fcmToken,
        kind: 'http',
        appId: _kAppId,
        appDisplayName: 'Pyramid',
        deviceDisplayName: client.deviceName ?? 'Android',
        lang: 'de',
        data: PusherData(
          url: Uri.parse(_kGatewayUrl),
          format: 'event_id_only',
        ),
      ),
      append: true,
    );
  } catch (e) {
    debugPrint('[FCM] Pusher-Registrierung fehlgeschlagen: $e');
  }
}

/// Tries to register the FCM pusher and returns a human-readable result string.
Future<String> retryPusherRegistration(Client client) async {
  if (!Platform.isAndroid) return 'Kein Android';
  final buf = StringBuffer();
  try {
    String? token;
    try {
      token = await FirebaseMessaging.instance.getToken();
    } catch (e) {
      return '✗ FCM-Token: $e';
    }
    if (token == null) {
      return '✗ FCM-Token: null (Google Play Services Problem?)';
    }
    buf.writeln('✓ FCM-Token: ${token.substring(0, 20)}…');
    buf.writeln('  Gateway: $_kGatewayUrl');
    await client.postPusher(
      Pusher(
        pushkey: token,
        kind: 'http',
        appId: _kAppId,
        appDisplayName: 'Pyramid',
        deviceDisplayName: client.deviceName ?? 'Android',
        lang: 'de',
        data: PusherData(
          url: Uri.parse(_kGatewayUrl),
          format: 'event_id_only',
        ),
      ),
      append: true,
    );
    buf.writeln('✓ Pusher registriert');
    await _saveNotifCredentials(client);
    buf.writeln('✓ Credentials gespeichert');
  } catch (e) {
    buf.writeln('✗ Fehler: $e');
  }
  return buf.toString().trim();
}
