import 'dart:ui';

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

import 'package:userfront/features/dashboard/domain/dashboard_providers.dart';
import 'package:userfront/features/dashboard/domain/models.dart';
import 'package:userfront/i18n.dart';

AuditLogEntry _log(String id) {
  return AuditLogEntry.fromJson({
    'event_id': id,
    'timestamp': '2026-02-06T00:00:00Z',
    'status': 'success',
    'session_id': 's-$id',
  });
}

Future<void> _drainMicrotasks() async {
  for (var i = 0; i < 5; i++) {
    await Future<void>.delayed(Duration.zero);
  }
}

void main() {
  TestWidgetsFlutterBinding.ensureInitialized();
  final dispatcher = TestWidgetsFlutterBinding.instance.platformDispatcher;
  dispatcher.localeTestValue = const Locale('ko');
  dispatcher.localesTestValue = const [Locale('ko')];

  tearDownAll(() {
    dispatcher.clearLocaleTestValue();
    dispatcher.clearLocalesTestValue();
  });

  test('AuthTimelineNotifier는 초기 페이지를 로드한다', () async {
    final cursors = <String?>[];
    final container = ProviderContainer(
      overrides: [
        authTimelineFetcherProvider.overrideWithValue(({String? cursor}) async {
          cursors.add(cursor);
          return AuditPage(items: [_log('1')], nextCursor: 'next');
        }),
      ],
    );

    container.read(authTimelineProvider.notifier);

    await _drainMicrotasks();

    final state = container.read(authTimelineProvider);
    expect(state.items.length, 1);
    expect(state.nextCursor, 'next');
    expect(cursors, [null]);
    container.dispose();
  });

  test('AuthTimelineNotifier는 다음 커서를 사용해 추가 로드한다', () async {
    final cursors = <String?>[];
    final container = ProviderContainer(
      overrides: [
        authTimelineFetcherProvider.overrideWithValue(({String? cursor}) async {
          cursors.add(cursor);
          if (cursor == null) {
            return AuditPage(items: [_log('1')], nextCursor: 'next');
          }
          return AuditPage(items: [_log('2')], nextCursor: '');
        }),
      ],
    );

    final notifier = container.read(authTimelineProvider.notifier);
    await _drainMicrotasks();
    await notifier.loadMore();

    final state = container.read(authTimelineProvider);
    expect(state.items.map((e) => e.eventId).toList(), ['1', '2']);
    expect(cursors, [null, 'next']);
    container.dispose();
  });

  test('AuthTimelineNotifier는 커서가 없으면 추가 로드를 하지 않는다', () async {
    var callCount = 0;
    final container = ProviderContainer(
      overrides: [
        authTimelineFetcherProvider.overrideWithValue(({String? cursor}) async {
          callCount += 1;
          return AuditPage(items: [_log('1')], nextCursor: '');
        }),
      ],
    );

    final notifier = container.read(authTimelineProvider.notifier);
    await _drainMicrotasks();
    await notifier.loadMore();

    expect(callCount, 1);
    expect(container.read(authTimelineProvider).items.length, 1);
    container.dispose();
  });

  test('AuthTimelineNotifier는 실패 시 오류 메시지를 보관한다', () async {
    final container = ProviderContainer(
      overrides: [
        authTimelineFetcherProvider.overrideWithValue(({String? cursor}) async {
          throw Exception('fail');
        }),
      ],
    );

    container.read(authTimelineProvider.notifier);

    await _drainMicrotasks();

    final state = container.read(authTimelineProvider);
    expect(state.items.isEmpty, true);
    expect(
      state.error,
      tr(
        'msg.userfront.dashboard.timeline.load_error',
        fallback: '접속이력을 불러오지 못했습니다.',
      ),
    );
    container.dispose();
  });
}
