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

/// Tests Notification Adapter Contract behavior for the Scheduler Notifications package.
library;

import 'package:scheduler_notifications/notifications.dart';
import 'package:test/test.dart';

/// Test harness for [NotificationAdapter] contract checks.
final class NotificationAdapterContractHarness {
  /// Creates a harness around one adapter instance.
  const NotificationAdapterContractHarness({
    required this.adapter,
    required this.scheduledRequests,
    required this.cancelledIds,
    this.dispose,
  });

  /// Adapter under test.
  final NotificationAdapter adapter;

  /// Snapshot of requests delivered through [adapter].
  final List<NotificationRequest> Function() scheduledRequests;

  /// Snapshot of ids cancelled through [adapter].
  final List<String> Function() cancelledIds;

  /// Optional cleanup callback.
  final Future<void> Function()? dispose;
}

/// Runs shared notification adapter behavior checks.
void runNotificationAdapterContractTests(
  String name,
  NotificationAdapterContractHarness Function() createHarness,
) {
  group('$name notification adapter contract', () {
    test('schedules normalized notification requests', () async {
      final harness = createHarness();
      final dispose = harness.dispose;
      if (dispose != null) {
        addTearDown(dispose);
      }

      await harness.adapter.schedule(_request(' reminder-1 '));

      expect(harness.scheduledRequests().map((request) => request.id), [
        'reminder-1',
      ]);
      expect(harness.scheduledRequests().single.scheduledDateTimeUtc.isUtc,
          isTrue);
    });

    test('cancels normalized ids', () async {
      final harness = createHarness();
      final dispose = harness.dispose;
      if (dispose != null) {
        addTearDown(dispose);
      }

      await harness.adapter.cancel(' reminder-1 ');

      expect(harness.cancelledIds(), ['reminder-1']);
    });
  });
}

/// Top-level helper that performs the `_request` operation for this file.
/// Keeping the helper private makes the surrounding flow easier to read while preventing unrelated libraries from depending on implementation detail.
NotificationRequest _request(String id) {
  return NotificationRequest(
    id: id,
    title: 'Start task',
    body: 'Time to begin.',
    scheduledDateTimeUtc: DateTime.utc(2026, 1, 1, 9),
    payloadJson: '{"taskId":"task-1"}',
  );
}
