import 'package:flutter_test/flutter_test.dart';
import 'package:marianum_mobile/push/chat_thread_store.dart';
import 'package:marianum_mobile/push/push_actions.dart';

void main() {
  group('PushActions.actionFailureBody', () {
    test('includes the undelivered text and the reason', () {
      expect(
        PushActions.actionFailureBody(lostText: 'Hallo du', detail: 'HTTP 401'),
        'Deine Nachricht: „Hallo du“\nGrund: HTTP 401',
      );
    });

    test('omits the text line when there is none', () {
      expect(
        PushActions.actionFailureBody(detail: 'HTTP 404'),
        'Grund: HTTP 404',
      );
      expect(
        PushActions.actionFailureBody(lostText: '', detail: 'HTTP 404'),
        'Grund: HTTP 404',
      );
    });
  });

  group('PushActions.finishReply', () {
    const token = 'chat1';
    final thread = [
      const ThreadMessage(nid: 1, sender: 'Max', text: 'Hi', timestampMs: 1),
      const ThreadMessage(nid: 2, sender: 'Max', text: 'Da?', timestampMs: 2),
    ];

    test(
      'successful reply removes the notification via chat cleanup',
      () async {
        var cleanups = 0;
        var renders = 0;
        var cancels = 0;
        await PushActions.finishReply(
          chatToken: token,
          sent: true,
          cleanupChat: (t) async {
            expect(t, token);
            cleanups++;
          },
          loadThread: (_) async => thread,
          renderSilent: (_, _) async => renders++,
          cancelNotification: (_) async => cancels++,
        );
        expect(cleanups, 1);
        expect(renders, 0);
        expect(cancels, 0);
      },
    );

    test('failed reply re-renders the unchanged thread exactly once', () async {
      var cleanups = 0;
      var renders = 0;
      List<ThreadMessage>? rendered;
      await PushActions.finishReply(
        chatToken: token,
        sent: false,
        cleanupChat: (_) async => cleanups++,
        loadThread: (_) async => thread,
        renderSilent: (t, messages) async {
          expect(t, token);
          renders++;
          rendered = messages;
        },
        cancelNotification: (_) async => fail('must not cancel'),
      );
      expect(cleanups, 0);
      expect(renders, 1);
      // History unchanged — same messages, no self entry appended.
      expect(rendered!.map((m) => m.nid), [1, 2]);
    });

    test(
      'failed reply with empty history cancels to stop the spinner',
      () async {
        var cancels = 0;
        await PushActions.finishReply(
          chatToken: token,
          sent: false,
          cleanupChat: (_) async => fail('must not cleanup'),
          loadThread: (_) async => const [],
          renderSilent: (_, _) async => fail('nothing to render'),
          cancelNotification: (_) async => cancels++,
        );
        expect(cancels, 1);
      },
    );
  });
}
