/// Repository pour les demandes d'aide (solidarité)
/// Interface avec l'API /api/demandes-aide
/// Note: le backend doit exposer DemandeAideResource pour que les appels fonctionnent.
library demande_aide_repository;

import 'package:injectable/injectable.dart';
import 'package:unionflow_mobile_apps/core/network/api_client.dart';
import '../models/demande_aide_model.dart';

abstract class DemandeAideRepository {
  /// Demandes du membre connecté (GET /api/demandes-aide/mes)
  Future<List<DemandeAideModel>> getMesDemandes({int page = 0, int size = 50});
  Future<List<DemandeAideModel>> getAll({int page = 0, int size = 20});
  Future<DemandeAideModel?> getById(String id);
  Future<DemandeAideModel> create(DemandeAideModel demande);
  Future<DemandeAideModel> update(String id, DemandeAideModel demande);
  Future<DemandeAideModel> approuver(String id);
  Future<DemandeAideModel> rejeter(String id, {String? motif});
  Future<List<DemandeAideModel>> search({
    String? statut,
    String? type,
    String? urgence,
    int page = 0,
    int size = 20,
  });
}

@LazySingleton(as: DemandeAideRepository)
class DemandeAideRepositoryImpl implements DemandeAideRepository {
  final ApiClient _apiClient;
  static const String _base = '/api/demandes-aide';

  DemandeAideRepositoryImpl(this._apiClient);

  @override
  Future<List<DemandeAideModel>> getMesDemandes({int page = 0, int size = 50}) async {
    final response = await _apiClient.get(
      '$_base/mes',
      queryParameters: {'page': page, 'size': size},
    );
    if (response.statusCode == 200) {
      final List<dynamic> data = response.data is List ? response.data : [];
      return data.map((e) => DemandeAideModel.fromJson(e as Map<String, dynamic>)).toList();
    }
    throw Exception('Erreur ${response.statusCode}');
  }

  @override
  Future<List<DemandeAideModel>> getAll({int page = 0, int size = 20}) async {
    final response = await _apiClient.get(
      _base,
      queryParameters: {'page': page, 'size': size},
    );
    if (response.statusCode == 200) {
      final List<dynamic> data = response.data is List ? response.data : (response.data as Map)['content'] as List? ?? [];
      return data
          .map((e) => DemandeAideModel.fromJson(e as Map<String, dynamic>))
          .toList();
    }
    throw Exception('Erreur ${response.statusCode}');
  }

  @override
  Future<DemandeAideModel?> getById(String id) async {
    final response = await _apiClient.get('$_base/$id');
    if (response.statusCode == 200) {
      return DemandeAideModel.fromJson(response.data as Map<String, dynamic>);
    }
    if (response.statusCode == 404) return null;
    throw Exception('Erreur ${response.statusCode}');
  }

  @override
  Future<DemandeAideModel> create(DemandeAideModel demande) async {
    final response = await _apiClient.post(_base, data: demande.toJson());
    if (response.statusCode == 201 || response.statusCode == 200) {
      return DemandeAideModel.fromJson(response.data as Map<String, dynamic>);
    }
    throw Exception('Erreur création: ${response.statusCode}');
  }

  @override
  Future<DemandeAideModel> update(String id, DemandeAideModel demande) async {
    final response = await _apiClient.put('$_base/$id', data: demande.toJson());
    if (response.statusCode == 200) {
      return DemandeAideModel.fromJson(response.data as Map<String, dynamic>);
    }
    throw Exception('Erreur mise à jour: ${response.statusCode}');
  }

  @override
  Future<DemandeAideModel> approuver(String id) async {
    final response = await _apiClient.put('$_base/$id/approuver');
    if (response.statusCode == 200) {
      return DemandeAideModel.fromJson(response.data as Map<String, dynamic>);
    }
    throw Exception('Erreur approbation: ${response.statusCode}');
  }

  @override
  Future<DemandeAideModel> rejeter(String id, {String? motif}) async {
    final response = await _apiClient.put(
      '$_base/$id/rejeter',
      data: motif != null && motif.isNotEmpty ? {'motif': motif} : null,
    );
    if (response.statusCode == 200) {
      return DemandeAideModel.fromJson(response.data as Map<String, dynamic>);
    }
    throw Exception('Erreur rejet: ${response.statusCode}');
  }

  @override
  Future<List<DemandeAideModel>> search({
    String? statut,
    String? type,
    String? urgence,
    int page = 0,
    int size = 20,
  }) async {
    final q = <String, dynamic>{'page': page, 'size': size};
    if (statut != null) q['statut'] = statut;
    if (type != null) q['type'] = type;
    if (urgence != null) q['urgence'] = urgence;
    final response = await _apiClient.get('$_base/search', queryParameters: q);
    if (response.statusCode == 200) {
      final List<dynamic> data = response.data is List ? response.data : (response.data as Map)['content'] as List? ?? [];
      return data
          .map((e) => DemandeAideModel.fromJson(e as Map<String, dynamic>))
          .toList();
    }
    throw Exception('Erreur ${response.statusCode}');
  }
}
