using System.ComponentModel.DataAnnotations; using Journal.Core.Dtos; using Journal.Core.Models; using Journal.Core.Repositories; namespace Journal.Core.Services.Fragments; public class FragmentService(IFragmentRepository repo) : IFragmentService { private readonly IFragmentRepository _repo = repo ?? throw new ArgumentNullException(nameof(repo)); private static FragmentDto Map(Fragment f) => new( f.Id, f.Type, f.Description, f.Time, f.Tags != null ? [.. f.Tags] : [] ); public async Task CreateAsync(CreateFragmentDto dto) { ArgumentNullException.ThrowIfNull(dto); var ctx = new ValidationContext(dto); Validator.ValidateObject(dto, ctx, validateAllProperties: true); var f = new Fragment(dto.Type, dto.Description); if (dto.Tags != null) f.Tags = [.. dto.Tags.Where(t => !string.IsNullOrWhiteSpace(t)).Select(t => t!.Trim())]; await _repo.AddAsync(f); return Map(f); } public async Task UpdateAsync(Guid id, UpdateFragmentDto dto) { ArgumentNullException.ThrowIfNull(dto); if (dto.Type != null && string.IsNullOrWhiteSpace(dto.Type)) throw new ValidationException("Type cannot be empty"); if (dto.Description != null && string.IsNullOrWhiteSpace(dto.Description)) throw new ValidationException("Description cannot be empty"); var type = dto.Type?.Trim(); var description = dto.Description?.Trim(); var tags = dto.Tags?.Where(t => !string.IsNullOrWhiteSpace(t)).Select(t => t!.Trim()).ToList(); return await _repo.UpdateAsync(id, type, description, tags, dto.Time); } public Task RemoveAsync(Guid id) => _repo.RemoveAsync(id); public async Task> SearchAsync(string? type = null, string? tag = null, DateTimeOffset? timeAfter = null) { var items = await _repo.SearchAsync(type, tag, timeAfter); return [.. items.Select(Map)]; } public async Task> GetByTagAsync(string tag) { var items = await _repo.GetByTagAsync(tag); return [.. items.Select(Map)]; } public async Task> GetByTypeAsync(string type) { var items = await _repo.GetByTypeAsync(type); return [.. items.Select(Map)]; } public async Task> GetAllAsync() { var items = await _repo.GetAllAsync(); return [.. items.Select(Map)]; } public async Task GetByIdAsync(Guid id) { var f = await _repo.GetByIdAsync(id); return f is null ? null : Map(f); } }