// SPDX-FileCopyrightText: 2026 FocusFlow contributors
// SPDX-License-Identifier: AGPL-3.0-only

part of '../../desktop_notification_adapter_io.dart';

/// Notification adapter that delegates to a desktop backend.
final class DesktopNotificationAdapter implements NotificationAdapter {
  /// Creates an adapter backed by [backend].
  DesktopNotificationAdapter({required DesktopNotificationBackend backend})
      : _backend = backend;

  /// Private state stored as `_backend` for this implementation.
  /// The field is intentionally scoped to this library so only the owning type can change the related scheduler or UI behavior.
  final DesktopNotificationBackend _backend;

  /// Creates the best available desktop adapter for the current platform.
  factory DesktopNotificationAdapter.defaultInstance({
    DesktopNotificationPlatform? platform,
    DesktopProcessRunner? processRunner,
    DesktopNotificationLogSink? logSink,
  }) {
    logger.info(() => 'Creating desktop notification adapter. '
        'requestedPlatform=${platform?.name} hasCustomRunner=${processRunner != null} '
        'hasCustomLogSink=${logSink != null}');
    return DesktopNotificationAdapter(
      backend: createDefaultDesktopNotificationBackend(
        platform: platform,
        processRunner: processRunner,
        logSink: logSink,
      ),
    );
  }

  /// Returns the derived `feedback` value for this object.
  /// Keeping this as an accessor gives callers a stable read surface while the owning type controls how the value is calculated.
  @override
  Stream<NotificationFeedback> get feedback => const Stream.empty();

  /// Runs the `schedule` operation and completes after its asynchronous work finishes.
  /// Callers should await the returned future so repository writes, UI refreshes, and failure handling happen in a predictable order.
  @override
  Future<void> schedule(NotificationRequest request) {
    logger.debug(() => 'Desktop notification schedule requested. '
        'notificationId=${request.id} '
        'scheduledDateTimeUtc=${request.scheduledDateTimeUtc.toIso8601String()} '
        'backendSupported=${_backend.isSupported}');
    return _backend.deliver(request);
  }

  /// Runs the `cancel` operation and completes after its asynchronous work finishes.
  /// Callers should await the returned future so repository writes, UI refreshes, and failure handling happen in a predictable order.
  @override
  Future<void> cancel(String id) {
    final trimmed = id.trim();
    logger.debug(() => 'Desktop notification cancel requested. '
        'notificationId=$trimmed backendSupported=${_backend.isSupported}');
    return _backend.cancel(trimmed);
  }
}
