using Common; using Common.Constant; using Common.Http; using Common.Logic; using Esim.Apis.DTO.Content; using Esim.Apis.Singleton; using Database.Database; using log4net; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; namespace Esim.Apis.Business { public class ContentBusinessImpl : IContentBusiness { private static readonly log4net.ILog log = log4net.LogManager.GetLogger( typeof(ContentBusinessImpl) ); private ModelContext dbContext; IConfiguration configuration; public ContentBusinessImpl(ModelContext _dbContext, IConfiguration _configuration) { dbContext = _dbContext; configuration = _configuration; } public async Task BannerLoad(HttpRequest httpRequest, BannerLoadReq 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; var query = dbContext.Banners .Where(b => b.Status == true) .Where(b => b.StartDate == null || b.StartDate <= DateTime.Now) .Where(b => b.EndDate == null || b.EndDate >= DateTime.Now); if (!string.IsNullOrEmpty(request.position)) { query = query.Where(b => b.Position == request.position); } int totalCount = query.Count(); int totalPages = (int)Math.Ceiling((double)totalCount / pageSize); var banners = query .OrderBy(b => b.DisplayOrder) .ThenByDescending(b => b.CreatedDate) .Skip(pageNumber * pageSize) .Take(pageSize) .Select(b => new { b.Id, title = lang == "en" ? (b.TitleEn ?? b.Title) : (b.TitleLo ?? b.Title), subtitle = lang == "en" ? (b.SubtitleEn ?? b.Subtitle) : (b.SubtitleLo ?? b.Subtitle), b.ImageUrl, b.ImageMobileUrl, b.LinkUrl, b.LinkTarget, b.Position, b.DisplayOrder }) .ToList(); return ApiResponseHelper.BuildResponse( log, url, json, CommonErrorCode.Success, ConfigManager.Instance.GetConfigWebValue("LOAD_SUCCESS", lang), new { banners = banners, pagination = new { pageNumber, pageSize, totalCount, totalPages } } ); } catch (Exception ex) { log.Error("Exception: ", ex); } return ApiResponseHelper.BuildResponse( log, url, json, CommonErrorCode.SystemError, ConfigManager.Instance.GetConfigWebValue("SYSTEM_FAILURE"), new { } ); } public async Task CustomerReviewLoad(HttpRequest httpRequest, CustomerReviewLoadReq 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; var query = dbContext.CustomerReviews .Where(r => r.Status == true); if (request.isFeatured.HasValue && request.isFeatured.Value) { query = query.Where(r => r.IsFeatured == true); } int totalCount = query.Count(); int totalPages = (int)Math.Ceiling((double)totalCount / pageSize); var reviews = query .OrderBy(r => r.DisplayOrder) .ThenByDescending(r => r.CreatedDate) .Skip(pageNumber * pageSize) .Take(pageSize) .Select(r => new { r.Id, r.CustomerName, r.AvatarUrl, r.Rating, reviewContent = lang == "en" ? (r.ReviewContentEn ?? r.ReviewContent) : (r.ReviewContentLo ?? r.ReviewContent), destination = lang == "en" ? (r.DestinationEn ?? r.Destination) : (r.DestinationLo ?? r.Destination), r.IsFeatured, r.CreatedDate }) .ToList(); return ApiResponseHelper.BuildResponse( log, url, json, CommonErrorCode.Success, ConfigManager.Instance.GetConfigWebValue("LOAD_SUCCESS", lang), new { reviews = reviews, pagination = new { pageNumber, pageSize, totalCount, totalPages } } ); } catch (Exception ex) { log.Error("Exception: ", ex); } return ApiResponseHelper.BuildResponse( log, url, json, CommonErrorCode.SystemError, ConfigManager.Instance.GetConfigWebValue("SYSTEM_FAILURE"), new { } ); } public async Task CustomerReviewCreate(HttpRequest httpRequest, CustomerReviewCreateReq request) { var url = httpRequest.Path; var json = JsonConvert.SerializeObject(request); log.Debug("URL: " + url + " => Request: " + json); try { string lang = CommonLogic.GetLanguage(httpRequest, request.lang); // Validate required fields if (string.IsNullOrEmpty(request.customerName) || string.IsNullOrEmpty(request.reviewContent)) { return ApiResponseHelper.BuildResponse( log, url, json, CommonErrorCode.RequiredFieldMissing, ConfigManager.Instance.GetConfigWebValue("REQUIRED_FIELD_MISSING", lang), new { } ); } // Create new review (pending approval) var review = new CustomerReview { CustomerName = request.customerName, ReviewContent = request.reviewContent, Destination = request.destination, Rating = request.rating > 0 ? request.rating : 1, Status = false, // Pending approval IsFeatured = false, CreatedDate = DateTime.Now }; dbContext.CustomerReviews.Add(review); await dbContext.SaveChangesAsync(); return ApiResponseHelper.BuildResponse( log, url, json, CommonErrorCode.Success, ConfigManager.Instance.GetConfigWebValue("REVIEW_SUBMITTED", lang), new { reviewId = review.Id } ); } catch (Exception ex) { log.Error("Exception: ", ex); } return ApiResponseHelper.BuildResponse( log, url, json, CommonErrorCode.SystemError, ConfigManager.Instance.GetConfigWebValue("SYSTEM_FAILURE"), new { } ); } public async Task FaqCategoryLoad(HttpRequest httpRequest, FaqCategoryLoadReq 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; var query = dbContext.FaqCategories .Where(c => c.Status == true); int totalCount = query.Count(); int totalPages = (int)Math.Ceiling((double)totalCount / pageSize); 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.DisplayOrder }) .ToList(); return ApiResponseHelper.BuildResponse( log, url, json, CommonErrorCode.Success, ConfigManager.Instance.GetConfigWebValue("LOAD_SUCCESS", lang), new { categories = categories, pagination = new { pageNumber, pageSize, totalCount, totalPages } } ); } catch (Exception ex) { log.Error("Exception: ", ex); } return ApiResponseHelper.BuildResponse( log, url, json, CommonErrorCode.SystemError, ConfigManager.Instance.GetConfigWebValue("SYSTEM_FAILURE"), new { } ); } public async Task FaqLoad(HttpRequest httpRequest, FaqLoadReq 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; var query = dbContext.Faqs .Where(f => f.Status == true); if (request.categoryId.HasValue) { query = query.Where(f => f.CategoryId == request.categoryId); } if (request.isFeatured.HasValue && request.isFeatured.Value) { query = query.Where(f => f.IsFeatured == true); } int totalCount = query.Count(); int totalPages = (int)Math.Ceiling((double)totalCount / pageSize); var faqs = query .OrderBy(f => f.DisplayOrder) .ThenByDescending(f => f.ViewCount) .Skip(pageNumber * pageSize) .Take(pageSize) .Select(f => new { f.Id, question = lang == "en" ? (f.QuestionEn ?? f.Question) : (f.QuestionLo ?? f.Question), answer = lang == "en" ? (f.AnswerEn ?? f.Answer) : (f.AnswerLo ?? f.Answer), f.CategoryId, f.ViewCount, f.IsFeatured }) .ToList(); return ApiResponseHelper.BuildResponse( log, url, json, CommonErrorCode.Success, ConfigManager.Instance.GetConfigWebValue("LOAD_SUCCESS", lang), new { faqs = faqs, pagination = new { pageNumber, pageSize, totalCount, totalPages } } ); } catch (Exception ex) { log.Error("Exception: ", ex); } return ApiResponseHelper.BuildResponse( log, url, json, CommonErrorCode.SystemError, ConfigManager.Instance.GetConfigWebValue("SYSTEM_FAILURE"), new { } ); } /// /// Load device eSIM compatibility list /// public async Task DeviceCompatibilityLoad(HttpRequest httpRequest, DeviceCompatibilityReq 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 ? 50 : request.pageSize; // Base query - only active devices var query = dbContext.DeviceEsimCompatibilities .Where(d => d.Status == true && d.SupportsEsim == true); // Filter by brand if (!string.IsNullOrEmpty(request.brand)) { query = query.Where(d => d.Brand == request.brand); } // Filter by category if (!string.IsNullOrEmpty(request.category)) { query = query.Where(d => d.Category == request.category); } // Filter by popular flag if (request.isPopular.HasValue && request.isPopular.Value) { query = query.Where(d => d.IsPopular == true); } // Search by keyword in model name (all language variants) if (!string.IsNullOrEmpty(request.searchKeyword)) { var keyword = request.searchKeyword.ToLower(); query = query.Where(d => d.ModelName.ToLower().Contains(keyword) || (d.ModelNameEn != null && d.ModelNameEn.ToLower().Contains(keyword)) || (d.ModelNameLo != null && d.ModelNameLo.ToLower().Contains(keyword)) ); } // Get total count for pagination int totalCount = query.Count(); int totalPages = (int)Math.Ceiling((double)totalCount / pageSize); // Apply pagination and ordering var devices = query .OrderBy(d => d.DisplayOrder) .ThenBy(d => d.Brand) .ThenBy(d => d.ModelName) .Skip(pageNumber * pageSize) .Take(pageSize) .Select(d => new { d.Id, d.Brand, modelName = lang == "en" ? (d.ModelNameEn ?? d.ModelName) : (d.ModelNameLo ?? d.ModelName), d.Category, notes = lang == "en" ? (d.NotesEn ?? d.Notes) : (d.NotesLo ?? d.Notes), supportsEsim = d.SupportsEsim ?? true, isPopular = d.IsPopular ?? false, displayOrder = d.DisplayOrder ?? 999 }) .ToList(); return ApiResponseHelper.BuildResponse( log, url, json, CommonErrorCode.Success, ConfigManager.Instance.GetConfigWebValue("LOAD_SUCCESS", lang), new { devices = devices, pagination = new { pageNumber, pageSize, totalCount, totalPages } } ); } catch (Exception exception) { log.Error("Exception: ", exception); } return ApiResponseHelper.BuildResponse( log, url, json, CommonErrorCode.SystemError, ConfigManager.Instance.GetConfigWebValue("SYSTEM_FAILURE"), new { } ); } /// /// Get list of device brands and categories (for filters/tabs) /// public async Task GetDeviceBrandsAndCategories(HttpRequest httpRequest) { var url = httpRequest.Path; log.Debug("URL: " + url); try { // Get distinct brands with device count var brands = dbContext.DeviceEsimCompatibilities .Where(d => d.Status == true && d.SupportsEsim == true) .GroupBy(d => d.Brand) .Select(g => new { brand = g.Key, deviceCount = g.Count(), popularCount = g.Count(d => d.IsPopular == true) }) .OrderBy(b => b.brand) .ToList(); // Get distinct categories with device count var categories = dbContext.DeviceEsimCompatibilities .Where(d => d.Status == true && d.SupportsEsim == true) .GroupBy(d => d.Category) .Select(g => new { category = g.Key, deviceCount = g.Count() }) .OrderBy(c => c.category) .ToList(); return ApiResponseHelper.BuildResponse( log, url, "", CommonErrorCode.Success, ConfigManager.Instance.GetConfigWebValue("LOAD_SUCCESS"), new { brands = brands, categories = categories } ); } catch (Exception exception) { log.Error("Exception: ", exception); } return ApiResponseHelper.BuildResponse( log, url, "", CommonErrorCode.SystemError, ConfigManager.Instance.GetConfigWebValue("SYSTEM_FAILURE"), new { } ); } } }