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

import 'package:lanebow/models/participant_model.dart';
import 'package:lanebow/services/event_service.dart';
import 'package:lanebow/screens/club/participant_form_screen.dart';
import '../../utils/event_bus_test_utils.dart';
import 'package:lanebow/utils/test_utils.dart';

// 공통 StubEventService 사용
import '../../utils/stub_event_service.dart';
import '../../utils/dummy_test_data.dart';

void main() {
  late EventService stubEventService;

  setUp(() async {
    // EventBus 테스트 환경 초기화 (플래키 방지)
    TestUtils.setTestMode(true);
    await EventBusTestUtils.setUp('participant_form_screen_test');
    stubEventService = StubEventService();
  });

  tearDown(() async {
    await EventBusTestUtils.tearDown();
  });

  // 로컬 더미 생성기 제거: DummyTestData 공용 유틸 사용

  // 위젯 빌더
  Widget createParticipantForm({
    required String eventId,
    Participant? participant,
  }) {
    return MaterialApp(
      home: ChangeNotifierProvider<EventService>.value(
        value: stubEventService,
        child: ParticipantFormScreen(
          eventId: eventId,
          participant: participant,
        ),
      ),
    );
  }

  group('ParticipantFormScreen 위젯 테스트', () {
    testWidgets('새 참가자 추가 모드: 필수값 입력 후 저장 플로우', (tester) async {
      await tester.pumpWidget(createParticipantForm(eventId: 'event1'));
      await tester.pumpAndSettle();

      // 이름 입력 (필수)
      final nameField = find.widgetWithText(TextFormField, '이름 *');
      expect(nameField, findsOneWidget);
      await tester.enterText(nameField, '홍길동');

      // 저장 아이콘 버튼 탭
      await tester.tap(find.byIcon(Icons.save));
      await tester.pump(const Duration(milliseconds: 300));
      await tester.pump(const Duration(seconds: 1));

      // then: 화면이 pop 되었는지 확인 (성공 시 Navigator.pop(true) 호출)
      expect(find.byType(ParticipantFormScreen), findsNothing);
    });

    testWidgets('참가자 수정 모드: 수정 후 저장 플로우', (tester) async {
      // given
      final existing = DummyTestData.participants(eventId: 'event1', count: 1, status: '확인됨').first;

      await tester.pumpWidget(createParticipantForm(eventId: 'event1', participant: existing));
      await tester.pumpAndSettle();

      // 제목이 수정 모드로 표시되는지 확인
      expect(find.text('참가자 수정'), findsWidgets);

      // 이름 변경
      final nameField = find.widgetWithText(TextFormField, '이름 *');
      expect(nameField, findsOneWidget);
      await tester.enterText(nameField, '수정된이름');

      // 저장
      await tester.tap(find.byIcon(Icons.save));
      await tester.pump(const Duration(milliseconds: 300));
      await tester.pump(const Duration(seconds: 1));

      // then: 화면이 pop 되었는지 확인
      expect(find.byType(ParticipantFormScreen), findsNothing);
    });

    testWidgets('실패 케이스(추가): 스낵바 에러 노출, 로딩 해제, pop 미호출', (tester) async {
      // given
      (stubEventService as StubEventService).throwOnAddParticipant = true;

      await tester.pumpWidget(createParticipantForm(eventId: 'event1'));
      await tester.pumpAndSettle();

      // 이름 입력
      final nameField = find.widgetWithText(TextFormField, '이름 *');
      expect(nameField, findsOneWidget);
      await tester.enterText(nameField, '실패사례');

      // when: 저장 클릭
      await tester.tap(find.byIcon(Icons.save));
      await tester.pump(const Duration(milliseconds: 300));
      await tester.pump(const Duration(seconds: 1));

      // then: 화면이 여전히 존재 (pop 미호출)
      expect(find.byType(ParticipantFormScreen), findsOneWidget);
      // 에러 스낵바 노출
      expect(find.textContaining('참가자 저장에 실패했습니다'), findsOneWidget);
    });

    testWidgets('실패 케이스(수정): 스낵바 에러 노출, 로딩 해제, pop 미호출', (tester) async {
      // given
      (stubEventService as StubEventService).throwOnUpdateParticipant = true;
      final existing = DummyTestData.participants(eventId: 'event1', count: 1, status: '확인됨').first;

      await tester.pumpWidget(createParticipantForm(eventId: 'event1', participant: existing));
      await tester.pumpAndSettle();

      // 이름 변경
      final nameField = find.widgetWithText(TextFormField, '이름 *');
      expect(nameField, findsOneWidget);
      await tester.enterText(nameField, '변경실패');

      // when: 저장 클릭
      await tester.tap(find.byIcon(Icons.save));
      await tester.pump(const Duration(milliseconds: 300));
      await tester.pump(const Duration(seconds: 1));

      // then
      expect(find.byType(ParticipantFormScreen), findsOneWidget);
      expect(find.textContaining('참가자 저장에 실패했습니다'), findsOneWidget);
    });
  });
}
