import 'package:comwell_key_app/database/comwell_db.dart';
import 'package:comwell_key_app/domain/models/notification_permission.dart';
import 'package:comwell_key_app/services/api.dart';
import 'package:comwell_key_app/utils/json.dart';
import 'package:comwell_key_app/utils/locator.dart';
import 'package:permission_handler/permission_handler.dart';

class NotificationsRepository {
  final Api _api;
  final ComwellDatabase _comwellDatabase;

  const NotificationsRepository(this._api, this._comwellDatabase);

  Future<void> updatePreferences(List<NotificationPermission> notificationPermissions) async {
    return _api.updateNotificationPreferences(notificationPermissions);
  }

  Future<List<NotificationPermission>> fetchNotificationPermissions() async {
    final notificationPermissions = await _comwellDatabase.notificationPermissionDAO
        .getNotificationPermissions();
    if (notificationPermissions.isEmpty) {
      final response = await _api.getNotificationPermissions();
      final data = response.data as Json;
      final notificationPermissions = (data['codes'] as List<dynamic>)
          .map((json) => NotificationPermission.fromJson(json as Json))
          .toList();

      final notificationPermissionsWithDescription = _addDescriptionsToPermissions(
        notificationPermissions,
      );

      await _comwellDatabase.notificationPermissionDAO.saveNotificationPermission(
        notificationPermissionsWithDescription,
      );
      return notificationPermissionsWithDescription;
    }
    return _addDescriptionsToPermissions(notificationPermissions);
  }

  Future<bool> isPushNotificationPermissionGranted() async {
    return Permission.notification.isGranted;
  }

  Future<bool> requestPushNotificationPermission() async {
    await Permission.notification.request();
    return isPushNotificationPermissionGranted();
  }

  Future<dynamic> updateNotificationPreferences(
    List<NotificationPermission> notificationPermissions,
  ) async {
    await locator<ComwellDatabase>().notificationPermissionDAO.saveNotificationPermission(
      notificationPermissions,
    );

    return _api.updateNotificationPreferences(notificationPermissions);
  }

  List<NotificationPermission> _addDescriptionsToPermissions(
    List<NotificationPermission> permissions,
  ) {
    return permissions.map((permission) {
      final enumValue = NotificationPermissionType.values.firstWhere(
        (type) => type.code == permission.code,
      );
      return permission.copyWith(
        notificationPermissionDescription: enumValue,
      );
    }).toList();
  }
}