using Common; using Common.Constant; using Common.Http; using Common.Logic; using Esim.Apis.Singleton; using Database.Database; using log4net; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; namespace Esim.Apis.Business { public class ArticleBusinessImpl : IArticleBusiness { private static readonly log4net.ILog log = log4net.LogManager.GetLogger( typeof(ArticleBusinessImpl) ); private ModelContext dbContext; IConfiguration configuration; public ArticleBusinessImpl(ModelContext _dbContext, IConfiguration _configuration) { dbContext = _dbContext; configuration = _configuration; } private string GetParameter(string key) { return configuration.GetSection(key).Value ?? ""; } /// /// Load article categories with pagination /// public async Task ArticleCategory(HttpRequest httpRequest, ArticleCategoryReq request) { var url = httpRequest.Path; var json = JsonConvert.SerializeObject(request); log.Debug("URL: " + url + " => Request: " + json); try { string lang = CommonLogic.GetLanguage(httpRequest, request.lang); int pageNumber = request.pageNumber < 0 ? 0 : request.pageNumber; int pageSize = request.pageSize <= 0 ? 10 : request.pageSize; // Query categories var query = dbContext.ArticleCategories .Where(c => c.Status == true); // Filter by parent category if (request.parentId.HasValue) { query = query.Where(c => c.ParentId == request.parentId); } else { query = query.Where(c => c.ParentId == null); // Root categories } // Get total count for pagination int totalCount = query.Count(); int totalPages = (int)Math.Ceiling((double)totalCount / pageSize); // Apply pagination and ordering var categories = query .OrderBy(c => c.DisplayOrder) .ThenBy(c => c.Id) .Skip(pageNumber * pageSize) .Take(pageSize) .Select(c => new { c.Id, categoryName = lang == "en" ? (c.CategoryNameEn ?? c.CategoryName) : (c.CategoryNameLo ?? c.CategoryName), c.CategorySlug, description = lang == "en" ? (c.DescriptionEn ?? c.Description) : (c.DescriptionLo ?? c.Description), c.IconUrl, c.ParentId, c.DisplayOrder }) .ToList(); return DotnetLib.Http.HttpResponse.BuildResponse( log, url, json, CommonErrorCode.Success, ConfigManager.Instance.GetConfigWebValue("LOAD_SUCCESS", lang), new { items = categories, pagination = new { pageNumber, pageSize, totalCount, totalPages } } ); } catch (Exception exception) { log.Error("Exception: ", exception); } return DotnetLib.Http.HttpResponse.BuildResponse( log, url, json, CommonErrorCode.SystemError, ConfigManager.Instance.GetConfigWebValue("SYSTEM_FAILURE"), new { } ); } /// /// Load articles with pagination and filters /// public async Task ArticleLoad(HttpRequest httpRequest, ArticleLoadReq request) { var url = httpRequest.Path; var json = JsonConvert.SerializeObject(request); log.Debug("URL: " + url + " => Request: " + json); try { string lang = CommonLogic.GetLanguage(httpRequest, request.lang); int pageNumber = request.pageNumber < 0 ? 0 : request.pageNumber; int pageSize = request.pageSize <= 0 ? 10 : request.pageSize; // If slug is provided, return single article detail if (!string.IsNullOrEmpty(request.slug)) { var article = dbContext.Articles .Where(a => a.Slug == request.slug && a.Status == true) .Select(a => new { a.Id, title = lang == "en" ? (a.TitleEn ?? a.Title) : (a.TitleLo ?? a.Title), a.Slug, summary = lang == "en" ? (a.SummaryEn ?? a.Summary) : (a.SummaryLo ?? a.Summary), content = lang == "en" ? (a.ContentEn ?? a.Content) : (a.ContentLo ?? a.Content), a.ThumbnailUrl, a.CoverImageUrl, metaDescription = lang == "en" ? (a.MetaDescriptionEn ?? a.MetaDescription) : (a.MetaDescriptionLo ?? a.MetaDescription), a.MetaKeywords, a.CategoryId, a.ViewCount, a.IsFeatured, a.PublishedDate, a.CreatedDate }) .FirstOrDefault(); if (article == null) { return DotnetLib.Http.HttpResponse.BuildResponse( log, url, json, CommonErrorCode.Error, ConfigManager.Instance.GetConfigWebValue("ARTICLE_NOT_FOUND", lang), new { } ); } // Increment view count var articleEntity = dbContext.Articles.FirstOrDefault(a => a.Slug == request.slug); if (articleEntity != null) { articleEntity.ViewCount = (articleEntity.ViewCount ?? 0) + 1; await dbContext.SaveChangesAsync(); } return DotnetLib.Http.HttpResponse.BuildResponse( log, url, json, CommonErrorCode.Success, ConfigManager.Instance.GetConfigWebValue("LOAD_SUCCESS", lang), new { article } ); } // Query articles list var query = dbContext.Articles .Where(a => a.Status == true); // Filter by category if (request.categoryId.HasValue) { query = query.Where(a => a.CategoryId == request.categoryId); } // Filter by featured if (request.isFeatured.HasValue && request.isFeatured.Value) { query = query.Where(a => a.IsFeatured == true); } // Get total count for pagination int totalCount = query.Count(); int totalPages = (int)Math.Ceiling((double)totalCount / pageSize); // Apply pagination and ordering (pinned first, then by published date) var articles = query .OrderByDescending(a => a.IsPinned) .ThenByDescending(a => a.PublishedDate) .ThenByDescending(a => a.CreatedDate) .Skip(pageNumber * pageSize) .Take(pageSize) .Select(a => new { a.Id, title = lang == "en" ? (a.TitleEn ?? a.Title) : (a.TitleLo ?? a.Title), a.Slug, summary = lang == "en" ? (a.SummaryEn ?? a.Summary) : (a.SummaryLo ?? a.Summary), a.ThumbnailUrl, a.CategoryId, a.ViewCount, a.IsFeatured, a.IsPinned, a.PublishedDate }) .ToList(); return DotnetLib.Http.HttpResponse.BuildResponse( log, url, json, CommonErrorCode.Success, ConfigManager.Instance.GetConfigWebValue("LOAD_SUCCESS", lang), new { items = articles, pagination = new { pageNumber, pageSize, totalCount, totalPages } } ); } catch (Exception exception) { log.Error("Exception: ", exception); } return DotnetLib.Http.HttpResponse.BuildResponse( log, url, json, CommonErrorCode.SystemError, ConfigManager.Instance.GetConfigWebValue("SYSTEM_FAILURE"), new { } ); } } }