/// Repository pour la gestion des utilisateurs admin (API /api/admin/users)
library admin_user_repository;

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

abstract class AdminUserRepository {
  Future<AdminUserSearchResult> search({int page = 0, int size = 20, String? search});
  Future<AdminUserModel?> getById(String id);
  Future<List<AdminRoleModel>> getRealmRoles();
  Future<List<AdminRoleModel>> getUserRoles(String userId);
  Future<void> setUserRoles(String userId, List<String> roleNames);
  /// Associe un utilisateur (email) à une organisation (réservé SUPER_ADMIN).
  Future<void> associerOrganisation({required String email, required String organisationId});
}

class AdminUserSearchResult {
  final List<AdminUserModel> users;
  final int totalCount;
  final int currentPage;
  final int pageSize;
  final int totalPages;

  AdminUserSearchResult({
    required this.users,
    required this.totalCount,
    required this.currentPage,
    required this.pageSize,
    required this.totalPages,
  });
}

@LazySingleton(as: AdminUserRepository)
class AdminUserRepositoryImpl implements AdminUserRepository {
  final ApiClient _apiClient;
  static const String _base = '/api/admin/users';

  AdminUserRepositoryImpl(this._apiClient);

  @override
  Future<AdminUserSearchResult> search({int page = 0, int size = 20, String? search}) async {
    final query = <String, dynamic>{'page': page, 'size': size};
    if (search != null && search.isNotEmpty) query['search'] = search;
    final response = await _apiClient.get(_base, queryParameters: query);
    if (response.statusCode != 200) throw Exception('Erreur ${response.statusCode}');
    final data = response.data as Map<String, dynamic>;
    final list = data['users'] as List<dynamic>? ?? [];
    return AdminUserSearchResult(
      users: list.map((e) => AdminUserModel.fromJson(e as Map<String, dynamic>)).toList(),
      totalCount: (data['totalCount'] as num?)?.toInt() ?? 0,
      currentPage: (data['currentPage'] as num?)?.toInt() ?? 0,
      pageSize: (data['pageSize'] as num?)?.toInt() ?? size,
      totalPages: (data['totalPages'] as num?)?.toInt() ?? 0,
    );
  }

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

  @override
  Future<List<AdminRoleModel>> getRealmRoles() async {
    final response = await _apiClient.get('$_base/roles');
    if (response.statusCode != 200) return [];
    final list = response.data as List<dynamic>? ?? [];
    return list.map((e) => AdminRoleModel.fromJson(e as Map<String, dynamic>)).toList();
  }

  @override
  Future<List<AdminRoleModel>> getUserRoles(String userId) async {
    final response = await _apiClient.get('$_base/$userId/roles');
    if (response.statusCode != 200) return [];
    final list = response.data as List<dynamic>? ?? [];
    return list.map((e) => AdminRoleModel.fromJson(e as Map<String, dynamic>)).toList();
  }

  @override
  Future<void> setUserRoles(String userId, List<String> roleNames) async {
    final response = await _apiClient.put('$_base/$userId/roles', data: roleNames);
    if (response.statusCode != 200) throw Exception('Erreur ${response.statusCode}');
  }

  @override
  Future<void> associerOrganisation({required String email, required String organisationId}) async {
    const path = '/api/admin/associer-organisation';
    final response = await _apiClient.post(
      path,
      data: {'email': email, 'organisationId': organisationId},
    );
    if (response.statusCode != 200) {
      final msg = response.data is Map && response.data['message'] != null
          ? response.data['message'] as String
          : 'Erreur ${response.statusCode}';
      throw Exception(msg);
    }
  }
}
