import 'package:lanebow/services/event_service.dart';
import 'package:lanebow/models/participant_model.dart';
import 'package:lanebow/models/score_model.dart';
import 'package:lanebow/models/event_model.dart';
import 'package:lanebow/models/team_model.dart';

/// 테스트 공통 StubEventService
/// - 네트워크/인증 의존성을 제거
/// - 각 메서드별 실패 시뮬레이션 플래그 제공
class StubEventService extends EventService {
  bool throwOnAddParticipant = false;
  bool throwOnUpdateParticipant = false;
  bool throwOnAddScore = false;
  bool throwOnUpdateScore = false;
  bool throwOnCloneEvent = false;
  bool throwOnCreateEvent = false;

  // Observability for tests
  bool lastCloneCalled = false;
  String? lastClonedEventId;
  Map<String, dynamic>? lastCreatedEventData;

  // Seeded events for tests
  List<Event> _seededEvents = <Event>[];
  set seededEvents(List<Event> events) => _seededEvents = List<Event>.from(events);

  @override
  List<Event> get events => List<Event>.from(_seededEvents);

  @override
  Future<Participant> addParticipant(String eventId, Map<String, dynamic> data) async {
    if (throwOnAddParticipant) {
      throw Exception('의도한 실패(addParticipant)');
    }
    return Participant(
      id: 'stub_p',
      memberId: (data['memberId'] ?? 'stub_member').toString(),
      name: (data['name'] ?? '이름없음').toString(),
      eventId: eventId,
    );
  }

  @override
  Future<Event> cloneEvent(String eventId, {String? newName}) async {
    if (throwOnCloneEvent) {
      throw Exception('의도한 실패(cloneEvent)');
    }
    lastCloneCalled = true;
    lastClonedEventId = eventId;
    final now = DateTime.now();
    final e = Event(
      id: 'cloned_$eventId',
      clubId: 'club1',
      title: (newName ?? '복사본'),
      startDate: now,
      status: 'draft',
      isActive: true,
    );
    // 목록 변경 알림만 수행
    notifyListeners();
    return e;
  }

  @override
  Future<Event> createEvent(Map<String, dynamic> eventData) async {
    if (throwOnCreateEvent) {
      throw Exception('의도한 실패(createEvent)');
    }
    lastCreatedEventData = Map<String, dynamic>.from(eventData);
    final now = DateTime.now();
    final e = Event(
      id: 'new_event',
      clubId: (eventData['clubId'] ?? 'club1') as String,
      title: (eventData['title'] ?? '제목없음') as String,
      description: eventData['description'] as String?,
      location: eventData['location'] as String?,
      startDate: DateTime.tryParse(eventData['startDate'] as String? ?? '') ?? now,
      endDate: (eventData['endDate'] != null) ? DateTime.tryParse(eventData['endDate'] as String) : null,
      status: (eventData['status'] ?? 'draft') as String,
      publicHash: eventData['publicHash'] as String?,
      accessPassword: eventData['accessPassword'] as String?,
      gameCount: eventData['gameCount'] as int?,
      participantFee: (eventData['participantFee'] as num?)?.toDouble(),
      maxParticipants: eventData['maxParticipants'] as int?,
      isActive: true,
    );
    notifyListeners();
    return e;
  }

  @override
  Future<Participant> updateParticipant(String eventId, String participantId, Map<String, dynamic> data) async {
    if (throwOnUpdateParticipant) {
      throw Exception('의도한 실패(updateParticipant)');
    }
    return Participant(
      id: participantId,
      memberId: (data['memberId'] ?? 'stub_member').toString(),
      name: (data['name'] ?? '이름없음').toString(),
      eventId: eventId,
    );
  }

  @override
  Future<Score> addScore(String eventId, Map<String, dynamic> scoreData) async {
    if (throwOnAddScore) {
      throw Exception('의도한 실패(addScore)');
    }
    return Score(
      id: 'stub_score',
      memberId: (scoreData['memberId'] ?? 'member1').toString(),
      eventId: eventId,
      clubId: 'club1',
      frames: (scoreData['frames'] as List?)?.cast<int>() ?? const [],
      totalScore: (scoreData['totalScore'] as int?) ?? 0,
      handicap: scoreData['handicap'] as int?,
      date: DateTime.now(),
      notes: scoreData['notes'] as String?,
    );
  }

  @override
  Future<Score> updateScore(String eventId, String scoreId, Map<String, dynamic> scoreData) async {
    if (throwOnUpdateScore) {
      throw Exception('의도한 실패(updateScore)');
    }
    return Score(
      id: scoreId,
      memberId: (scoreData['memberId'] ?? 'member1').toString(),
      eventId: eventId,
      clubId: 'club1',
      frames: (scoreData['frames'] as List?)?.cast<int>() ?? const [],
      totalScore: (scoreData['totalScore'] as int?) ?? 0,
      handicap: scoreData['handicap'] as int?,
      date: DateTime.now(),
      notes: scoreData['notes'] as String?,
    );
  }

  // --- Stubbed fetch methods to avoid network in widget tests ---
  @override
  Future<void> fetchClubEvents() async {
    // simulate quick load without network
    notifyListeners();
  }
  @override
  Future<List<Participant>> fetchEventParticipants(String eventId) async {
    return <Participant>[];
  }

  @override
  Future<List<Score>> fetchEventScores(String eventId) async {
    return <Score>[];
  }

  @override
  Future<List<Team>> fetchEventTeams(String eventId) async {
    return <Team>[];
  }

  @override
  Future<Event> fetchEventById(String eventId) async {
    return Event(
      id: eventId,
      clubId: 'club1',
      title: '원본',
      startDate: DateTime.now(),
      status: 'active',
      isActive: true,
    );
  }
}
