import 'dart:async';
import 'dart:developer';

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

import '../../../push/push_registration.dart';
import '../../../state/app/modules/capabilities/bloc/capabilities_cubit.dart';
import '../../../state/app/modules/settings/bloc/settings_cubit.dart';
import '../../../widget/confirm_dialog.dart';

/// Shows the one-time notification-permission flow on the first Talk visit.
///
/// The OS prompt is deliberately kept out of the cold-start path (younger users
/// decline it reflexively before ever seeing why they'd want it). Instead, the
/// first time Talk is opened we explain the request, then trigger the OS prompt,
/// and — if declined — offer a shortcut to the system settings.
///
/// Runs at most once per install (guarded by `talkPermissionPromptShown`).
Future<void> maybePromptTalkNotifications(BuildContext context) async {
  final settings = context.read<SettingsCubit>();
  final notificationSettings = settings.val().notificationSettings;

  // Already handled once, or the user opted out of push entirely.
  if (notificationSettings.talkPermissionPromptShown) return;
  if (!notificationSettings.enabled) return;

  // Capabilities may still be loading on a fresh cold start; retry on the next
  // Talk visit instead of burning the one-shot flag.
  if (!context.read<CapabilitiesCubit>().canReceivePushNotifications) return;

  // Existing users who already granted the permission: register silently and
  // mark the prompt as handled without showing any dialog.
  if (await PushRegistration.isOsPermissionGranted()) {
    settings.val(write: true).notificationSettings.talkPermissionPromptShown =
        true;
    unawaited(PushRegistration().register());
    return;
  }

  if (!context.mounted) return;

  ConfirmDialog(
    icon: Icons.notifications_active_outlined,
    title: 'Benachrichtigungen aktivieren',
    content:
        'Damit du keine neuen Nachrichten im Talk verpasst, fragen wir dich '
        'gleich nach der Erlaubnis für Benachrichtigungen. Bitte akzeptiere '
        'sie, um Push-Nachrichten zu erhalten.',
    confirmButton: 'Weiter',
    cancelButton: null,
    onConfirm: () => unawaited(_requestPermission(context, settings)),
  ).asDialog(context);
}

Future<void> _requestPermission(
  BuildContext context,
  SettingsCubit settings,
) async {
  final granted = await PushRegistration.requestOsPermission();

  // Mark handled regardless of the outcome — the user can re-enable later via
  // the system settings; we don't want to prompt again on the next Talk visit.
  settings.val(write: true).notificationSettings.talkPermissionPromptShown =
      true;

  if (granted) {
    unawaited(PushRegistration().register());
    return;
  }

  log('Push: notification permission declined on first Talk visit');

  if (!context.mounted) return;

  ConfirmDialog(
    icon: Icons.notifications_off_outlined,
    title: 'Benachrichtigungen deaktiviert',
    content:
        'Ohne die Berechtigung erhältst du keine Benachrichtigungen bei neuen '
        'Talk-Nachrichten. Du kannst sie jederzeit in den Systemeinstellungen '
        'deines Geräts nachträglich aktivieren.',
    confirmButton: 'Einstellungen öffnen',
    cancelButton: 'Später',
    onConfirm: () =>
        AppSettings.openAppSettings(type: AppSettingsType.notification),
  ).asDialog(context);
}
