import 'package:bolao_mobile/core/api/api_client.dart';
import 'package:bolao_mobile/core/sessao/sessao_store.dart';
import 'package:bolao_mobile/features/boloes/data/boloes_repository.dart';
import 'package:bolao_mobile/features/boloes/data/rascunho_store.dart';
import 'package:bolao_mobile/features/boloes/presentation/rodada_page.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:shared_preferences/shared_preferences.dart';

/// `PP-6 FE-1`: o jogo reaberto tem que aparecer na lista com o **novo prazo** e
/// o **palpite anterior preenchido**. É o que evita o participante achar que
/// perdeu o palpite quando o jogo é remarcado.
class _StoreFalso extends RascunhoStore {
  @override
  Future<List<PalpiteRascunho>> ler(String poolId, int matchday) async =>
      const [];

  @override
  Future<void> salvar(
    String poolId,
    int matchday,
    List<PalpiteRascunho> palpites,
  ) async {}
}

class _RepoFalso extends BoloesRepository {
  _RepoFalso() : super(ApiClient(SessaoStore()));

  /// Começa fechado, com palpite salvo. Depois de `reabrir()`, volta com data
  /// nova — é o que o servidor devolve após a sincronização detectar o adiamento.
  bool reaberto = false;

  @override
  Future<Rodada> rodada(String poolId, int matchday) async => Rodada(
    serverTime: DateTime.utc(2026, 8, 6, 12),
    jogos: [
      JogoDaRodada(
        matchId: 'm1',
        homeTeam: 'Flamengo',
        awayTeam: 'Vasco',
        kickoffAt: reaberto
            ? DateTime.utc(2026, 9, 10, 21)
            : DateTime.utc(2026, 8, 6, 10),
        deadlineOpen: reaberto,
        palpiteCasa: 2,
        palpiteFora: 1,
      ),
    ],
  );
}

Widget _app(_RepoFalso repo) => ProviderScope(
  overrides: [
    boloesRepositoryProvider.overrideWithValue(repo),
    rascunhoStoreProvider.overrideWithValue(_StoreFalso()),
  ],
  child: const MaterialApp(home: RodadaPage(poolId: 'p1', matchday: 20)),
);

void main() {
  setUp(() => SharedPreferences.setMockInitialValues({}));

  group('PP-6 FE-1 — jogo reaberto na lista', () {
    testWidgets('antes do adiamento, fechado com o palpite visível', (t) async {
      await t.pumpWidget(_app(_RepoFalso()));
      await t.pumpAndSettle();

      expect(find.text('prazo fechado'), findsOneWidget);
      final campo = t.widget<TextFormField>(find.byType(TextFormField).at(0));
      expect(campo.initialValue, '2');
      expect(campo.enabled, isFalse);
    });

    testWidgets('depois de reabrir, novo prazo e palpite anterior editável', (
      t,
    ) async {
      final repo = _RepoFalso();
      await t.pumpWidget(_app(repo));
      await t.pumpAndSettle();

      // O servidor passa a devolver o jogo com data nova.
      repo.reaberto = true;
      await t.drag(find.byType(ListView), const Offset(0, 300));
      await t.pumpAndSettle();

      // Novo prazo com contagem, campo editável, e o palpite que já existia.
      expect(find.textContaining('fecha em'), findsOneWidget);
      expect(find.text('prazo fechado'), findsNothing);
      final campo = t.widget<TextFormField>(find.byType(TextFormField).at(0));
      expect(campo.enabled, isTrue);
      expect(campo.initialValue, '2');
      // Horário local do novo apito visível: o participante precisa saber
      // **quando** é o jogo novo, não só que reabriu.
      expect(find.textContaining('10/09'), findsOneWidget);
    });
  });
}
