/// Repository pour la gestion des sauvegardes
/// Interface avec l'API backend BackupResource
library backup_repository;

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

abstract class BackupRepository {
  Future<List<BackupModel>> getAll();
  Future<BackupModel> getById(String id);
  Future<BackupModel> create(String name, {String? description});
  Future<void> restore(String backupId, {bool createRestorePoint = true});
  Future<void> delete(String id);
  Future<BackupConfigModel> getConfig();
  Future<BackupConfigModel> updateConfig(Map<String, dynamic> config);
  Future<BackupModel> createRestorePoint();
}

@LazySingleton(as: BackupRepository)
class BackupRepositoryImpl implements BackupRepository {
  final ApiClient _apiClient;
  static const String _base = '/api/backups';

  BackupRepositoryImpl(this._apiClient);

  List<BackupModel> _parseListResponse(dynamic data) {
    if (data is List) {
      return data
          .map((e) => BackupModel.fromJson(e as Map<String, dynamic>))
          .toList();
    }
    if (data is Map && data.containsKey('content')) {
      final content = data['content'] as List<dynamic>? ?? [];
      return content
          .map((e) => BackupModel.fromJson(e as Map<String, dynamic>))
          .toList();
    }
    return [];
  }

  @override
  Future<List<BackupModel>> getAll() async {
    final response = await _apiClient.get(_base);
    if (response.statusCode == 200) {
      return _parseListResponse(response.data);
    }
    throw Exception('Erreur ${response.statusCode}');
  }

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

  @override
  Future<BackupModel> create(String name, {String? description}) async {
    final response = await _apiClient.post(
      _base,
      data: {
        'name': name,
        'description': description,
        'type': 'MANUAL',
        'includeDatabase': true,
        'includeFiles': true,
        'includeConfiguration': true,
      },
    );
    if (response.statusCode == 201 || response.statusCode == 200) {
      return BackupModel.fromJson(response.data as Map<String, dynamic>);
    }
    throw Exception('Erreur ${response.statusCode}');
  }

  @override
  Future<void> restore(String backupId, {bool createRestorePoint = true}) async {
    final response = await _apiClient.post(
      '$_base/restore',
      data: {
        'backupId': backupId,
        'restoreDatabase': true,
        'restoreFiles': true,
        'restoreConfiguration': true,
        'createRestorePoint': createRestorePoint,
      },
    );
    if (response.statusCode != 200) {
      throw Exception('Erreur ${response.statusCode}');
    }
  }

  @override
  Future<void> delete(String id) async {
    final response = await _apiClient.delete('$_base/$id');
    if (response.statusCode != 200) {
      throw Exception('Erreur ${response.statusCode}');
    }
  }

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

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

  @override
  Future<BackupModel> createRestorePoint() async {
    final response = await _apiClient.post('$_base/restore-point');
    if (response.statusCode == 201 || response.statusCode == 200) {
      return BackupModel.fromJson(response.data as Map<String, dynamic>);
    }
    throw Exception('Erreur ${response.statusCode}');
  }
}
