import '../../../../core/constants/api_endpoints.dart';
import '../../../../core/errors/exceptions.dart';
import '../../../../core/network/api_client.dart';
import '../../../../core/network/api_response.dart';
import '../models/user_model.dart';

/// Abstract interface for users remote data source
abstract class UsersRemoteDataSource {
  /// Fetch all users from the API
  Future<List<UserModel>> getUsers();

  /// Get current logged-in user
  Future<UserModel> getCurrentUser();
}

/// Implementation of UsersRemoteDataSource using ApiClient
class UsersRemoteDataSourceImpl implements UsersRemoteDataSource {
  final ApiClient apiClient;

  UsersRemoteDataSourceImpl(this.apiClient);

  @override
  Future<List<UserModel>> getUsers() async {
    try {
      // Make API call to get all users
      final response = await apiClient.get(ApiEndpoints.users);

      // Parse the API response using ApiResponse wrapper
      final apiResponse = ApiResponse.fromJson(
        response.data as Map<String, dynamic>,
        (json) => (json as List)
            .map((e) => UserModel.fromJson(e as Map<String, dynamic>))
            .toList(),
      );

      // Check if the API call was successful
      if (apiResponse.isSuccess && apiResponse.value != null) {
        return apiResponse.value!;
      } else {
        // Throw exception with error message from API
        throw ServerException(
          apiResponse.errors.isNotEmpty
              ? apiResponse.errors.first
              : 'Failed to get users',
        );
      }
    } catch (e) {
      // Re-throw ServerException as-is
      if (e is ServerException) {
        rethrow;
      }
      // Re-throw NetworkException as-is
      if (e is NetworkException) {
        rethrow;
      }
      // Wrap other exceptions in ServerException
      throw ServerException('Failed to get users: ${e.toString()}');
    }
  }

  @override
  Future<UserModel> getCurrentUser() async {
    try {
      // Make API call to get current user
      final response = await apiClient.get(ApiEndpoints.getCurrentUser);

      // Parse the API response using ApiResponse wrapper
      final apiResponse = ApiResponse.fromJson(
        response.data as Map<String, dynamic>,
        (json) => UserModel.fromJson(json as Map<String, dynamic>),
      );

      // Check if the API call was successful
      if (apiResponse.isSuccess && apiResponse.value != null) {
        return apiResponse.value!;
      } else {
        // Throw exception with error message from API
        throw ServerException(
          apiResponse.errors.isNotEmpty
              ? apiResponse.errors.first
              : 'Failed to get current user',
        );
      }
    } catch (e) {
      // Re-throw ServerException as-is
      if (e is ServerException) {
        rethrow;
      }
      // Re-throw NetworkException as-is
      if (e is NetworkException) {
        rethrow;
      }
      // Wrap other exceptions in ServerException
      throw ServerException('Failed to get current user: ${e.toString()}');
    }
  }
}
