using System.Linq; using CMSMicroservice.Protobuf.Protos.SitePage; using CMSMicroservice.WebApi.Common.Services; using CMSMicroservice.Application.SitePageCQ.Commands.CreateSitePage; using CMSMicroservice.Application.SitePageCQ.Commands.DeleteSitePage; using CMSMicroservice.Application.SitePageCQ.Commands.UpdateSitePage; using CMSMicroservice.Application.SitePageCQ.Commands.CreateSitePageSection; using CMSMicroservice.Application.SitePageCQ.Commands.UpdateSitePageSection; using CMSMicroservice.Application.SitePageCQ.Commands.DeleteSitePageSection; using CMSMicroservice.Application.SitePageCQ.Commands.ReorderSitePageSections; using CMSMicroservice.Application.SitePageCQ.Queries.GetSitePage; using CMSMicroservice.Application.SitePageCQ.Queries.GetSitePageByKey; using CMSMicroservice.Application.SitePageCQ.Queries.GetAllSitePages; using Google.Protobuf.WellKnownTypes; using Grpc.Core; using MediatR; namespace CMSMicroservice.WebApi.Services; public class SitePageService : SitePageContract.SitePageContractBase { private readonly ISender _sender; private readonly IDispatchRequestToCQRS _dispatchRequestToCQRS; public SitePageService(ISender sender, IDispatchRequestToCQRS dispatchRequestToCQRS) { _sender = sender; _dispatchRequestToCQRS = dispatchRequestToCQRS; } public override async Task GetSitePage(GetSitePageRequest request, ServerCallContext context) { var query = new GetSitePageQuery { Id = request.Id }; var result = await _sender.Send(query, context.CancellationToken); return MapToResponse(result); } public override async Task GetSitePageByKey(GetSitePageByKeyRequest request, ServerCallContext context) { var query = new GetSitePageByKeyQuery { PageKey = request.PageKey }; var result = await _sender.Send(query, context.CancellationToken); return MapToResponse(result); } public override async Task UpdateSitePage(UpdateSitePageRequest request, ServerCallContext context) { var command = new UpdateSitePageCommand { Id = request.Id, Title = request.Title, MetaDescription = request.MetaDescription, HeroTitle = request.HeroTitle, HeroSubtitle = request.HeroSubtitle, HeroImagePath = request.HeroImagePath, IsActive = request.IsActive, ImageFileBytes = request.ImageFile?.File?.ToByteArray(), ImageFileMime = request.ImageFile?.Mime, ImageFileName = request.ImageFile?.FileName }; await _sender.Send(command, context.CancellationToken); return new Empty(); } public override async Task CreateSitePage(CreateSitePageRequest request, ServerCallContext context) { var command = new CreateSitePageCommand { PageKey = request.PageKey, Title = request.Title, MetaDescription = request.MetaDescription, HeroTitle = request.HeroTitle, HeroSubtitle = request.HeroSubtitle, IsActive = request.IsActive, ImageFileBytes = request.ImageFile?.File?.ToByteArray(), ImageFileMime = request.ImageFile?.Mime, ImageFileName = request.ImageFile?.FileName }; var id = await _sender.Send(command, context.CancellationToken); return new CreateSitePageResponse { Id = id }; } public override async Task DeleteSitePage(DeleteSitePageRequest request, ServerCallContext context) { var command = new DeleteSitePageCommand { Id = request.Id }; await _sender.Send(command, context.CancellationToken); return new Empty(); } public override async Task GetAllSitePages(GetAllSitePagesRequest request, ServerCallContext context) { var query = new GetAllSitePagesQuery(); var result = await _sender.Send(query, context.CancellationToken); var response = new GetAllSitePagesResponse(); foreach (var item in result) { response.Pages.Add(new SitePageSummary { Id = item.Id, PageKey = item.PageKey ?? string.Empty, Title = item.Title ?? string.Empty, IsActive = item.IsActive, SectionCount = item.SectionCount, LastModified = item.LastModified.HasValue ? Timestamp.FromDateTime(DateTime.SpecifyKind(item.LastModified.Value, DateTimeKind.Utc)) : null }); } return response; } public override async Task CreateSitePageSection(CreateSitePageSectionRequest request, ServerCallContext context) { var command = new CreateSitePageSectionCommand { SitePageId = request.SitePageId, SectionKey = request.SectionKey, Title = request.Title, Subtitle = request.Subtitle, HtmlContent = request.HtmlContent, IconName = request.IconName, ImagePath = request.ImagePath, IsActive = true, ExtraData = request.ExtraData, ImageFileBytes = request.ImageFile?.File?.ToByteArray(), ImageFileMime = request.ImageFile?.Mime, ImageFileName = request.ImageFile?.FileName }; var result = await _sender.Send(command, context.CancellationToken); return new CreateSitePageSectionResponse { Id = result }; } public override async Task UpdateSitePageSection(UpdateSitePageSectionRequest request, ServerCallContext context) { var command = new UpdateSitePageSectionCommand { Id = request.Id, SectionKey = request.SectionKey, Title = request.Title, Subtitle = request.Subtitle, HtmlContent = request.HtmlContent, IconName = request.IconName, ImagePath = request.ImagePath, SortOrder = request.SortOrder, IsActive = request.IsActive, ExtraData = request.ExtraData, ImageFileBytes = request.ImageFile?.File?.ToByteArray(), ImageFileMime = request.ImageFile?.Mime, ImageFileName = request.ImageFile?.FileName }; await _sender.Send(command, context.CancellationToken); return new Empty(); } public override async Task DeleteSitePageSection(DeleteSitePageSectionRequest request, ServerCallContext context) { return await _dispatchRequestToCQRS.Handle(request, context); } public override async Task ReorderSitePageSections(ReorderSitePageSectionsRequest request, ServerCallContext context) { var command = new ReorderSitePageSectionsCommand { Items = request.Items.Select(x => new Application.SitePageCQ.Commands.ReorderSitePageSections.SectionSortItem { Id = x.Id, SortOrder = x.SortOrder }).ToList() }; await _sender.Send(command, context.CancellationToken); return new Empty(); } // ── Private Mapping Helpers ── private static GetSitePageResponse MapToResponse(SitePageDto dto) { var response = new GetSitePageResponse { Id = dto.Id, PageKey = dto.PageKey ?? string.Empty, Title = dto.Title ?? string.Empty, MetaDescription = dto.MetaDescription, HeroTitle = dto.HeroTitle, HeroSubtitle = dto.HeroSubtitle, HeroImagePath = dto.HeroImagePath, IsActive = dto.IsActive }; if (dto.Sections != null) { foreach (var s in dto.Sections) { response.Sections.Add(new SitePageSectionItem { Id = s.Id, SectionKey = s.SectionKey ?? string.Empty, Title = s.Title ?? string.Empty, Subtitle = s.Subtitle, HtmlContent = s.HtmlContent, IconName = s.IconName, ImagePath = s.ImagePath, SortOrder = s.SortOrder, IsActive = s.IsActive, ExtraData = s.ExtraData }); } } return response; } }