import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_test/flutter_test.dart';

import 'package:minstrel/api/endpoints/likes.dart';
import 'package:minstrel/likes/like_button.dart';
import 'package:minstrel/likes/likes_provider.dart';
import 'package:minstrel/theme/theme_data.dart';

class _ThrowingLikesApi implements LikesApi {
  bool throwOnNext = false;

  @override
  Future<void> like(LikeKind kind, String id) async {
    if (throwOnNext) throw StateError('boom');
  }

  @override
  Future<void> unlike(LikeKind kind, String id) async {
    if (throwOnNext) throw StateError('boom');
  }

  @override
  Future<({Set<String> artists, Set<String> albums, Set<String> tracks})>
      ids() async =>
          (artists: <String>{}, albums: <String>{}, tracks: <String>{});
}

void main() {
  testWidgets('tap toggles icon optimistically; rollback on error',
      (tester) async {
    final api = _ThrowingLikesApi();
    final container = ProviderContainer(overrides: [
      likesApiProvider.overrideWith((ref) async => api),
    ]);
    addTearDown(container.dispose);

    await tester.pumpWidget(UncontrolledProviderScope(
      container: container,
      child: MaterialApp(
        theme: buildThemeData(),
        home: const Scaffold(
          body: LikeButton(kind: LikeKind.album, id: 'al-1'),
        ),
      ),
    ));
    await tester.pumpAndSettle();

    // First tap = like; succeeds → icon flips to favorite.
    await tester.tap(find.byType(IconButton));
    await tester.pump();
    expect(find.byIcon(Icons.favorite), findsOneWidget);

    // Force the next mutation to fail; rollback restores prior state.
    api.throwOnNext = true;
    final notifier = container.read(likedIdsProvider.notifier);
    try {
      await notifier.toggle(LikeKind.album, 'al-1');
    } catch (_) {/* expected */}
    await tester.pump();
    expect(find.byIcon(Icons.favorite), findsOneWidget); // rolled back
  });
}
