namespace TaxBaik.Application.Services; using System.Text.RegularExpressions; using TaxBaik.Application.DTOs; using TaxBaik.Domain.Entities; using TaxBaik.Domain.Interfaces; public class BlogService(IBlogPostRepository repository) { public async Task GetBySlugAsync(string slug, CancellationToken ct = default) => await repository.GetBySlugAsync(slug, ct); public async Task<(IEnumerable, int)> GetPublishedPagedAsync( int page, int pageSize, int? categoryId = null, CancellationToken ct = default) => await repository.GetPublishedPagedAsync(page, pageSize, categoryId, ct); public async Task> GetAllAsync(CancellationToken ct = default) => await repository.GetAllForAdminAsync(ct); public async Task> GetAllForAdminAsync(CancellationToken ct = default) => await repository.GetAllForAdminAsync(ct); public async Task CreateAsync(BlogPost post, CancellationToken ct = default) { post.Slug = GenerateSlug(post.Title); post.IsPublished = false; return await repository.CreateAsync(post, ct); } public async Task CreateAsync(CreateBlogPostDto dto, CancellationToken ct = default) { var post = new BlogPost { Title = dto.Title, Content = dto.Content, CategoryId = dto.CategoryId, Tags = dto.Tags, SeoTitle = dto.SeoTitle, SeoDescription = dto.SeoDescription, ThumbnailUrl = dto.ThumbnailUrl, IsPublished = dto.IsPublished, AuthorId = dto.AuthorId, CreatedAt = DateTime.UtcNow }; var id = await CreateAsync(post, ct); post.Id = id; return post; } public async Task UpdateAsync(BlogPost post, CancellationToken ct = default) => await repository.UpdateAsync(post, ct); public async Task UpdateAsync(int id, CreateBlogPostDto dto, CancellationToken ct = default) { var post = await repository.GetByIdAsync(id, ct); if (post == null) return null; post.Title = dto.Title; post.Content = dto.Content; post.CategoryId = dto.CategoryId; post.Tags = dto.Tags; post.SeoTitle = dto.SeoTitle; post.SeoDescription = dto.SeoDescription; post.ThumbnailUrl = dto.ThumbnailUrl; post.IsPublished = dto.IsPublished; await UpdateAsync(post, ct); return post; } public async Task DeleteAsync(int id, CancellationToken ct = default) => await repository.DeleteAsync(id, ct); public async Task IncrementViewCountAsync(int id, CancellationToken ct = default) => await repository.IncrementViewCountAsync(id, ct); private static string GenerateSlug(string title) { var slug = Regex.Replace(title.ToLowerInvariant(), @"[^\w\s-]", ""); slug = Regex.Replace(slug, @"\s+", "-"); slug = Regex.Replace(slug, @"-+", "-").Trim('-'); return slug.Length > 100 ? slug[..100] : slug; } }