import '../domain/domain.dart';

abstract interface class UserRepository {
  Future<UserAccount?> findByEmail(String email);

  Future<UserAccount?> findById(String id);

  Future<void> insert(UserAccount user);

  Future<void> updatePasswordHash({
    required String userId,
    required String passwordHash,
    required DateTime updatedAt,
  });
}

abstract interface class AuthSessionRepository {
  Future<void> insert(AuthSession session);

  Future<AuthSession?> findByTokenHash(String tokenHash);

  Future<void> revoke({required String sessionId, required DateTime revokedAt});
}

enum SyncWriteStatus { accepted, ignoredOlder }

final class SyncWriteResult {
  const SyncWriteResult({required this.status, required this.resource});

  final SyncWriteStatus status;
  final SyncedResource resource;
}

abstract interface class SyncedResourceRepository {
  Future<SyncWriteResult> upsertWithLww(SyncedResource resource);

  Future<List<SyncedResource>> findAllForUserSince({
    required String ownerUserId,
    DateTime? since,
  });
}

final class ShareInboxItem {
  const ShareInboxItem({required this.share, required this.recipient});

  final Share share;
  final ShareRecipient recipient;
}

abstract interface class ShareRepository {
  Future<void> insertShare({
    required Share share,
    required List<ShareRecipient> recipients,
  });

  Future<List<ShareInboxItem>> listInbox(String recipientUserId);

  Future<Share?> findShareById(String shareId);

  Future<ShareRecipient?> findRecipient({
    required String shareId,
    required String recipientUserId,
  });

  Future<void> updateRecipientStatus({
    required String recipientId,
    required ShareRecipientStatus status,
    required DateTime respondedAt,
  });

  Future<void> revokeShare({
    required String shareId,
    required DateTime revokedAt,
  });
}

abstract interface class PasswordHasher {
  Future<String> hash(String password);

  Future<bool> verify({required String password, required String passwordHash});
}

abstract interface class OpaqueTokenService {
  String generateToken();

  String hashToken(String token);
}

abstract interface class Clock {
  DateTime now();
}

abstract interface class IdGenerator {
  String newId();
}
