namespace BackOffice.Services.Blog;

public class BlogPostService : IBlogPostService
{
    private readonly CMSMicroservice.Protobuf.Protos.BlogPost.BlogPostContract.BlogPostContractClient _client;

    public BlogPostService(CMSMicroservice.Protobuf.Protos.BlogPost.BlogPostContract.BlogPostContractClient client)
    {
        _client = client;
    }

    public async Task<BlogPostListResultDto> GetAllAsync(BlogPostFilterDto filter)
    {
        var request = new CMSMicroservice.Protobuf.Protos.BlogPost.GetAllBlogPostsRequest
        {
            PaginationState = new CMSMicroservice.Protobuf.Protos.PaginationState
            {
                PageNumber = filter.PageNumber,
                PageSize = filter.PageSize
            },
            Filter = new CMSMicroservice.Protobuf.Protos.BlogPost.GetAllBlogPostsFilter()
        };

        if (!string.IsNullOrWhiteSpace(filter.SearchTerm))
        {
            request.Filter.SearchTerm = filter.SearchTerm;
        }

        if (filter.Status.HasValue)
        {
            request.Filter.Status = filter.Status.Value;
        }

        if (filter.CategoryId.HasValue)
        {
            request.Filter.CategoryId = filter.CategoryId.Value;
        }

        if (filter.IsFeatured.HasValue)
        {
            request.Filter.IsFeatured = filter.IsFeatured.Value;
        }

        var response = await _client.GetAllBlogPostsAsync(request);

        var result = new BlogPostListResultDto
        {
            TotalCount = response.MetaData != null ? (int)response.MetaData.TotalCount : response.Models.Count
        };

        foreach (var m in response.Models)
        {
            var item = new BlogPostListItemDto
            {
                Id = m.Id,
                Title = m.Title,
                Slug = m.Slug,
                Summary = m.Summary,
                FeaturedImageThumbnailPath = m.FeaturedImageThumbnailPath,
                Status = m.Status,
                StatusName = m.StatusName,
                PublishedAt = m.PublishedAt?.ToDateTime(),
                ViewCount = m.ViewCount,
                IsFeatured = m.IsFeatured,
                Created = m.Created?.ToDateTime() ?? DateTime.MinValue
            };

            foreach (var c in m.Categories)
            {
                item.Categories.Add(new BlogPostCategoryInfoDto
                {
                    Id = c.Id,
                    Title = c.Title,
                    Slug = c.Slug
                });
            }

            result.Items.Add(item);
        }

        return result;
    }

    public async Task<BlogPostDetailsDto?> GetByIdAsync(long id)
    {
        var response = await _client.GetBlogPostAsync(
            new CMSMicroservice.Protobuf.Protos.BlogPost.GetBlogPostRequest { Id = id });

        if (response == null || response.Id <= 0) return null;

        var dto = new BlogPostDetailsDto
        {
            Id = response.Id,
            Title = response.Title,
            Slug = response.Slug,
            Summary = response.Summary,
            HtmlContent = response.HtmlContent,
            FeaturedImagePath = response.FeaturedImagePath,
            FeaturedImageThumbnailPath = response.FeaturedImageThumbnailPath,
            Status = response.Status,
            StatusName = response.StatusName,
            PublishedAt = response.PublishedAt?.ToDateTime(),
            ViewCount = response.ViewCount,
            AuthorUserId = response.AuthorUserId,
            IsFeatured = response.IsFeatured,
            SortOrder = response.SortOrder,
            Created = response.Created?.ToDateTime() ?? DateTime.MinValue,
            LastModified = response.LastModified?.ToDateTime() ?? DateTime.MinValue
        };

        foreach (var c in response.Categories)
        {
            dto.Categories.Add(new BlogPostCategoryInfoDto
            {
                Id = c.Id,
                Title = c.Title,
                Slug = c.Slug
            });
        }

        foreach (var t in response.Tags)
        {
            dto.Tags.Add(new BlogPostTagInfoDto
            {
                Id = t.Id,
                Title = t.Title,
                Name = t.Name
            });
        }

        return dto;
    }

    public async Task<long> CreateAsync(BlogPostEditDto dto)
    {
        var request = new CMSMicroservice.Protobuf.Protos.BlogPost.CreateBlogPostRequest
        {
            Title = dto.Title,
            Slug = dto.Slug,
            Summary = dto.Summary ?? string.Empty,
            HtmlContent = dto.HtmlContent,
            FeaturedImagePath = dto.FeaturedImagePath ?? string.Empty,
            FeaturedImageThumbnailPath = dto.FeaturedImageThumbnailPath ?? string.Empty,
            IsFeatured = dto.IsFeatured,
            SortOrder = dto.SortOrder
        };

        request.CategoryIds.AddRange(dto.CategoryIds);
        request.TagIds.AddRange(dto.TagIds);

        if (dto.ImageFile != null && !string.IsNullOrEmpty(dto.ImageMime) && !string.IsNullOrEmpty(dto.ImageFileName))
        {
            request.ImageFile = new CMSMicroservice.Protobuf.Protos.BlogPost.BlogImageFileModel
            {
                File = Google.Protobuf.ByteString.CopyFrom(dto.ImageFile),
                Mime = dto.ImageMime,
                FileName = dto.ImageFileName
            };
        }

        var response = await _client.CreateBlogPostAsync(request);
        return response.Id;
    }

    public async Task UpdateAsync(long id, BlogPostEditDto dto)
    {
        var request = new CMSMicroservice.Protobuf.Protos.BlogPost.UpdateBlogPostRequest
        {
            Id = id,
            Title = dto.Title,
            Slug = dto.Slug,
            Summary = dto.Summary ?? string.Empty,
            HtmlContent = dto.HtmlContent,
            FeaturedImagePath = dto.FeaturedImagePath ?? string.Empty,
            FeaturedImageThumbnailPath = dto.FeaturedImageThumbnailPath ?? string.Empty,
            IsFeatured = dto.IsFeatured,
            SortOrder = dto.SortOrder
        };

        request.CategoryIds.AddRange(dto.CategoryIds);
        request.TagIds.AddRange(dto.TagIds);

        if (dto.ImageFile != null && !string.IsNullOrEmpty(dto.ImageMime) && !string.IsNullOrEmpty(dto.ImageFileName))
        {
            request.ImageFile = new CMSMicroservice.Protobuf.Protos.BlogPost.BlogImageFileModel
            {
                File = Google.Protobuf.ByteString.CopyFrom(dto.ImageFile),
                Mime = dto.ImageMime,
                FileName = dto.ImageFileName
            };
        }

        await _client.UpdateBlogPostAsync(request);
    }

    public async Task DeleteAsync(long id)
    {
        await _client.DeleteBlogPostAsync(
            new CMSMicroservice.Protobuf.Protos.BlogPost.DeleteBlogPostRequest { Id = id });
    }

    public async Task<PublishResultDto> PublishAsync(long id)
    {
        var response = await _client.PublishBlogPostAsync(
            new CMSMicroservice.Protobuf.Protos.BlogPost.PublishBlogPostRequest { Id = id });

        return new PublishResultDto
        {
            Success = response.Success,
            Message = response.Message,
            PublishedAt = response.PublishedAt?.ToDateTime()
        };
    }

    public async Task<ArchiveResultDto> ArchiveAsync(long id)
    {
        var response = await _client.ArchiveBlogPostAsync(
            new CMSMicroservice.Protobuf.Protos.BlogPost.ArchiveBlogPostRequest { Id = id });

        return new ArchiveResultDto
        {
            Success = response.Success,
            Message = response.Message
        };
    }
}
