import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:smplayer/core/contracts/library.dart';
import 'package:smplayer/features/aggregated/aggregated_grouping.dart';
import 'package:smplayer/features/history/widgets/history_source_picker.dart';

void main() {
  testWidgets('shows each server independent playback progress', (
    tester,
  ) async {
    final now = DateTime(2026, 7, 11, 12);
    final partiallyWatchedSource = _entrySource(
      serverId: 'alpha',
      serverName: 'Alpha',
      itemId: 'alpha-movie',
      playbackPositionTicks: 600000000,
      runtimeTicks: 1200000000,
      lastPlayedDate: now.subtract(const Duration(hours: 1)),
    );
    final completedSource = _entrySource(
      serverId: 'beta',
      serverName: 'Beta',
      itemId: 'beta-movie',
      played: true,
      runtimeTicks: 1200000000,
      lastPlayedDate: now.subtract(const Duration(hours: 2)),
    );
    final unknownProgressSource = _entrySource(
      serverId: 'gamma',
      serverName: 'Gamma',
      itemId: 'gamma-movie',
    );
    final entry = AggregatedEntry(
      item: partiallyWatchedSource.item,
      source: partiallyWatchedSource.source,
      sources: [partiallyWatchedSource, completedSource, unknownProgressSource],
    );
    AggregatedEntrySource? selectedSource;

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: HistorySourcePickerContent(
            entry: entry,
            now: now,
            onSourceSelected: (source) => selectedSource = source,
          ),
        ),
      ),
    );

    expect(find.text('最近播放'), findsOneWidget);
    expect(find.text('已看 50% · 剩余 1 分钟 · 1 小时前'), findsOneWidget);
    expect(find.text('已看完 · 2 小时前'), findsOneWidget);
    expect(find.text('进度未知 · 未记录播放时间'), findsOneWidget);

    final progressIndicators = tester.widgetList<LinearProgressIndicator>(
      find.byType(LinearProgressIndicator),
    );
    expect(progressIndicators.map((indicator) => indicator.value), [0.5, 1, 0]);

    await tester.tap(find.text('Beta'));
    await tester.pump();

    expect(selectedSource, same(completedSource));
  });

  testWidgets('adaptive picker lets the user choose another server', (
    tester,
  ) async {
    tester.view.physicalSize = const Size(480, 800);
    tester.view.devicePixelRatio = 1;
    addTearDown(tester.view.resetPhysicalSize);
    addTearDown(tester.view.resetDevicePixelRatio);

    final now = DateTime(2026, 7, 11, 12);
    final alphaSource = _entrySource(
      serverId: 'alpha',
      serverName: 'Alpha',
      itemId: 'alpha-movie',
      playbackPositionTicks: 600000000,
      runtimeTicks: 1200000000,
      lastPlayedDate: now.subtract(const Duration(hours: 1)),
    );
    final betaSource = _entrySource(
      serverId: 'beta',
      serverName: 'Beta',
      itemId: 'beta-movie',
      playbackPositionTicks: 300000000,
      runtimeTicks: 1200000000,
      lastPlayedDate: now.subtract(const Duration(hours: 2)),
    );
    final entry = AggregatedEntry(
      item: alphaSource.item,
      source: alphaSource.source,
      sources: [alphaSource, betaSource],
    );
    AggregatedEntrySource? selectedSource;

    await tester.pumpWidget(
      ProviderScope(
        child: MaterialApp(
          home: Scaffold(
            body: Builder(
              builder: (context) => TextButton(
                onPressed: () async {
                  selectedSource = await showHistorySourcePicker(
                    context,
                    entry: entry,
                    now: now,
                  );
                },
                child: const Text('打开服务器选择'),
              ),
            ),
          ),
        ),
      ),
    );

    await tester.tap(find.text('打开服务器选择'));
    await tester.pumpAndSettle();

    expect(find.text('选择服务器'), findsOneWidget);
    expect(find.text('Alpha'), findsOneWidget);
    expect(find.text('Beta'), findsOneWidget);

    await tester.tap(find.text('Beta'));
    await tester.pumpAndSettle();

    expect(selectedSource, same(betaSource));
    expect(find.text('选择服务器'), findsNothing);
  });
}

AggregatedEntrySource _entrySource({
  required String serverId,
  required String serverName,
  required String itemId,
  int? playbackPositionTicks,
  int? runtimeTicks,
  bool? played,
  DateTime? lastPlayedDate,
}) {
  final item = EmbyRawItem(
    Id: itemId,
    Name: 'Movie',
    Type: 'Movie',
    RunTimeTicks: runtimeTicks,
    UserData: playbackPositionTicks != null || played != null
        ? EmbyRawUserData(
            PlaybackPositionTicks: playbackPositionTicks,
            Played: played,
          )
        : null,
    extra: {
      if (lastPlayedDate != null)
        'UserData': {'LastPlayedDate': lastPlayedDate},
    },
  );
  final serverResult = GlobalSearchServerResult(
    serverId: serverId,
    serverName: serverName,
    serverUrl: 'https://$serverId.example',
    token: 'token-$serverId',
    userId: 'user-$serverId',
    items: [item],
  );
  return AggregatedEntrySource(item: item, source: serverResult);
}
