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

import 'package:lanebow/screens/club/event_details_screen.dart';
import 'package:lanebow/services/event_service.dart';
import 'package:lanebow/services/member_service.dart';
import 'package:lanebow/models/participant_model.dart';
import 'package:lanebow/models/member_model.dart';
import '../../utils/dummy_test_data.dart';

class CapturingEventService extends EventService {
  Map<String, dynamic>? lastPayload;
  String? lastEventId;
  @override
  Future<Participant> addParticipant(String eventId, Map<String, dynamic> participantData) async {
    lastEventId = eventId;
    lastPayload = Map<String, dynamic>.from(participantData);
    return Participant(id: 'p1', eventId: eventId, memberId: participantData['memberId']?.toString() ?? 'm1');
  }
}

class FakeMemberService extends MemberService {
  final List<Member> membersData;
  FakeMemberService(this.membersData);
  @override
  List<Member> get members => membersData;
  @override
  bool get isLoading => false;
  @override
  String? get lastError => null;
  @override
  Future<void> fetchClubMembers() async {}
  @override
  void initialize(String token) {}
  @override
  Future<void> setClubId(String clubId) async {}
}

void main() {
  setUp(() {
    EventDetailsScreen.testMode = true; // 초기 로딩 스킵
  });

  testWidgets('FAB 선택 시트가 노출되고 두 옵션이 보인다', (tester) async {
    final event = DummyTestData.event(id: 'e1', clubId: 'c1');

    await tester.pumpWidget(
      MultiProvider(
        providers: [
          ChangeNotifierProvider<EventService>(create: (_) => EventService()),
          ChangeNotifierProvider<MemberService>(create: (_) => FakeMemberService([])),
        ],
        child: MaterialApp(home: EventDetailsScreen(event: event)),
      ),
    );

    await tester.pumpAndSettle();

    // 테스트 훅으로 선택 시트 직접 오픈
    final state = tester.state(find.byType(EventDetailsScreen));
    (state as dynamic).openAddChooserForTest();
    await tester.pumpAndSettle();

    expect(find.byKey(const Key('add_existing_member')), findsOneWidget);
    expect(find.byKey(const Key('add_guest')), findsOneWidget);
  });

  testWidgets('기존 회원 추가 선택→모달에서 선택값이 payload에 반영된다', (tester) async {
    final event = DummyTestData.event(id: 'e1', clubId: 'c1');
    final members = [
      DummyTestData.member(id: 'm1', name: '김하나'),
      DummyTestData.member(id: 'm2', name: '박둘'),
    ];
    final capturing = CapturingEventService();

    await tester.pumpWidget(
      MultiProvider(
        providers: [
          ChangeNotifierProvider<EventService>.value(value: capturing),
          ChangeNotifierProvider<MemberService>.value(value: FakeMemberService(members)),
        ],
        child: MaterialApp(home: EventDetailsScreen(event: event)),
      ),
    );

    await tester.pumpAndSettle();

    // 선택 시트 오픈
    final state = tester.state(find.byType(EventDetailsScreen));
    (state as dynamic).openAddChooserForTest();
    await tester.pumpAndSettle();

    // 기존 회원 추가 선택
    await tester.tap(find.byKey(const Key('add_existing_member')));
    await tester.pumpAndSettle();

    // 회원 선택
    await tester.tap(find.byKey(const Key('quick_add_member_dropdown')));
    await tester.pumpAndSettle();
    await tester.tap(find.text('박둘').last);
    await tester.pumpAndSettle();

    // 상태 선택: 참가확정
    await tester.tap(find.byKey(const Key('quick_add_status_dropdown')));
    await tester.pumpAndSettle();
    await tester.tap(find.text('참가확정').last);
    await tester.pumpAndSettle();

    // 결제 선택: 납부완료
    await tester.tap(find.byKey(const Key('quick_add_payment_dropdown')));
    await tester.pumpAndSettle();
    await tester.tap(find.text('납부완료').last);
    await tester.pumpAndSettle();

    // 추가 실행
    await tester.tap(find.text('추가'));
    await tester.pumpAndSettle();

    expect(capturing.lastEventId, 'e1');
    expect(capturing.lastPayload, isNotNull);
    expect(capturing.lastPayload!['memberId'], 'm2');
    expect(capturing.lastPayload!['status'], 'confirmed');
    expect(capturing.lastPayload!['paymentStatus'], 'paid');
  });

  testWidgets('게스트 추가 선택→게스트 모달이 열린다', (tester) async {
    final event = DummyTestData.event(id: 'e1', clubId: 'c1');

    await tester.pumpWidget(
      MultiProvider(
        providers: [
          ChangeNotifierProvider<EventService>(create: (_) => EventService()),
          ChangeNotifierProvider<MemberService>(create: (_) => FakeMemberService([])),
        ],
        child: MaterialApp(home: EventDetailsScreen(event: event)),
      ),
    );

    await tester.pumpAndSettle();

    // 시트 오픈
    final state = tester.state(find.byType(EventDetailsScreen));
    (state as dynamic).openAddChooserForTest();
    await tester.pumpAndSettle();

    // 게스트 추가 선택 → 게스트 모달 필드 중 하나가 보여야 함
    await tester.tap(find.byKey(const Key('add_guest')));
    await tester.pumpAndSettle();

    // 게스트 모달의 성별 드롭다운 키 존재 확인
    expect(find.byKey(const Key('event_details_guest_gender_dropdown')), findsOneWidget);
  });
}
