using LibraryApp.Domain.Entities; using LibraryApp.Domain.Repositories; namespace LibraryApp.Domain.Services; public class LendingService { private readonly ILendRecordRepository _lendRecords; public LendingService(ILendRecordRepository lendRecords) { _lendRecords = lendRecords; } public async Task> LendBookAsync(BookInstance bookInstance, Member member) { if (bookInstance.Status != BookInstanceStatus.OnShelf) return Result.Failure($"Book is not available for lending. Current status: {bookInstance.Status}."); var code = await GenerateUniqueLendCodeAsync(); bookInstance.MarkAsLent(); var record = new LendRecord(bookInstance.Id, member.Id, code); return Result.Success(record); } public Task ReturnBookAsync(BookInstance bookInstance, LendRecord lendRecord) { if (bookInstance.Status != BookInstanceStatus.Lent) return Task.FromResult(Result.Failure($"Book is not currently lent out. Current status: {bookInstance.Status}.")); bookInstance.ReturnToShelf(); lendRecord.MarkAsReturned(); return Task.FromResult(Result.Success()); } private async Task GenerateUniqueLendCodeAsync() { const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; var random = Random.Shared; while (true) { var code = new string(Enumerable.Range(0, 6).Select(_ => chars[random.Next(chars.Length)]).ToArray()); var lendCode = new LendCode(code); if (!await _lendRecords.ExistsWithCodeAsync(lendCode)) return lendCode; } } }