import 'package:riverpod_annotation/riverpod_annotation.dart';

import '../../../core/api/api_client.dart';
import '../domain/join_request.dart';
import '../domain/team.dart';

part 'teams_repository.g.dart';

class TeamsRepository {
  TeamsRepository(this._api);

  final ApiClient _api;

  Future<List<Team>> fetchTeams({bool adminAll = false}) async {
    final params = adminAll ? <String, String>{'all': '1'} : null;
    final data = await _api.get('/teams/index.php', params: params);
    final list = (data['teams'] as List?) ?? [];
    return list.whereType<Map<String, dynamic>>().map(Team.fromJson).toList();
  }

  Future<Team?> getTeam(String id) async {
    try {
      final data = await _api.get('/teams/detail.php', params: {'id': id});
      return Team.fromJson(data);
    } on ApiException catch (e) {
      if (e.statusCode == 404) return null;
      rethrow;
    }
  }

  Future<String> createTeam(Team team) async {
    final data = await _api.post('/teams/index.php', team.toJson());
    return data['id'] as String;
  }

  Future<Team> updateTeam(Team team) async {
    final data = await _api.put(
      '/teams/detail.php',
      team.toJson(),
      params: {'id': team.id},
    );
    return Team.fromJson(data);
  }

  Future<void> updateTeamStatus(String teamId, String status) async {
    await _api.put('/teams/detail.php', {'status': status}, params: {'id': teamId});
  }

  Future<void> deleteTeam(String id) async {
    await _api.delete('/teams/detail.php', params: {'id': id});
  }

  Future<String> submitJoinRequest({
    required String teamId,
    required String teamName,
    required String playerId,
    required String playerName,
    required String playerEmail,
  }) async {
    final data = await _api.post('/teams/join_requests.php', {
      'team_id': teamId,
      'team_name': teamName,
      'player_name': playerName,
      'player_email': playerEmail,
    });
    return data['id'] as String;
  }

  Future<List<JoinRequest>> fetchJoinRequestsForTeam(String teamId) async {
    final data = await _api.get(
      '/teams/join_requests.php',
      params: {'team_id': teamId},
    );
    final list = (data['requests'] as List?) ?? [];
    return list.whereType<Map<String, dynamic>>().map(JoinRequest.fromJson).toList();
  }

  Future<List<JoinRequest>> fetchJoinRequestsForPlayer(String playerId) async {
    final data = await _api.get(
      '/teams/join_requests.php',
      params: {'player_id': playerId},
    );
    final list = (data['requests'] as List?) ?? [];
    return list.whereType<Map<String, dynamic>>().map(JoinRequest.fromJson).toList();
  }

  Future<void> updateJoinRequestStatus(String requestId, String status) async {
    await _api.put(
      '/teams/join_requests.php',
      {'id': requestId, 'status': status},
      params: {'id': requestId},
    );
  }

  Stream<List<Team>> watchTeams() async* {
    yield await fetchTeams();
    await for (final _ in Stream<void>.periodic(const Duration(seconds: 30))) {
      yield await fetchTeams();
    }
  }

  Stream<List<Team>> adminWatchAllTeams() async* {
    yield await fetchTeams(adminAll: true);
    await for (final _ in Stream<void>.periodic(const Duration(seconds: 30))) {
      yield await fetchTeams(adminAll: true);
    }
  }

  Stream<List<JoinRequest>> watchJoinRequestsForTeam(String teamId) async* {
    yield await fetchJoinRequestsForTeam(teamId);
    await for (final _ in Stream<void>.periodic(const Duration(seconds: 30))) {
      yield await fetchJoinRequestsForTeam(teamId);
    }
  }

  Stream<List<JoinRequest>> watchJoinRequestsForPlayer(String playerId) async* {
    yield await fetchJoinRequestsForPlayer(playerId);
    await for (final _ in Stream<void>.periodic(const Duration(seconds: 30))) {
      yield await fetchJoinRequestsForPlayer(playerId);
    }
  }
}

@Riverpod(keepAlive: true)
TeamsRepository teamsRepository(TeamsRepositoryRef ref) {
  return TeamsRepository(ref.watch(apiClientProvider));
}

@riverpod
Stream<List<Team>> teamsStream(TeamsStreamRef ref) {
  return ref.watch(teamsRepositoryProvider).watchTeams();
}
