import 'package:logging/logging.dart';

import 'package:pshared/service/authorization/service.dart';


class BasicService<T> {
  final String _objectType;
  final Logger _logger;
  final List<T> Function(Map<String, dynamic> json) fromJson;

  Logger get logger => _logger;

  BasicService({
    required String objectType,
    required this.fromJson,
  }) : _objectType = objectType, _logger = Logger('service.$objectType');

  Future<List<T>> list(String organizationRef, String parentRef) async {
    _logger.fine('Loading all objects');
    return _getObjects(
      AuthorizationService.getGETResponse(_objectType, '/list/$organizationRef/$parentRef'),
    );
  }

  Future<T> get(String objectRef) async {
    _logger.fine('Loading object $objectRef');
    final objects = await _getObjects(
      AuthorizationService.getGETResponse(_objectType, '/$objectRef'),
    );
    return objects.first;
  }

  Future<List<T>> create(String organizationRef, Map<String, dynamic> request) async {
    _logger.fine('Creating new object...');
    return _getObjects(
      AuthorizationService.getPOSTResponse(_objectType, '/$organizationRef', request),
    );
  }

  Future<List<T>> update(Map<String, dynamic> request) async {
    _logger.fine('Patching object...');
    return _getObjects(
      AuthorizationService.getPUTResponse(_objectType, '/', request,
      ),
    );
  }

  Future<List<T>> delete(String objecRef) async {
    _logger.fine('Deleting object $objecRef');
    return _getObjects(
      AuthorizationService.getDELETEResponse(_objectType, '/$objecRef', {}),
    );
  }

  Future<List<T>> _getObjects(Future<Map<String, dynamic>> future) async {
    try {
      final responseJson = await future;
      final objects = fromJson(responseJson);
      _logger.fine('Fetched ${objects.length} object(s)');
      return objects;
    } catch (e, stackTrace) {
      _logger.severe('Failed to fetch objects', e, stackTrace);
      rethrow;
    }
  }
}
