using System.Collections.Generic;
using System.Linq;
using CMSMicroservice.Protobuf.Protos.DiscountProduct;
using CMSMicroservice.WebApi.Common.Services;
using CMSMicroservice.Application.DiscountShopCQ.Commands.CreateDiscountProduct;
using CMSMicroservice.Application.DiscountShopCQ.Commands.UpdateDiscountProduct;
using CMSMicroservice.Application.DiscountShopCQ.Commands.DeleteDiscountProduct;
using CMSMicroservice.Application.DiscountShopCQ.Commands.AddDiscountProductImage;
using CMSMicroservice.Application.DiscountShopCQ.Commands.UpdateDiscountProductImage;
using CMSMicroservice.Application.DiscountShopCQ.Commands.DeleteDiscountProductImage;
using CMSMicroservice.Application.DiscountShopCQ.Commands.ReorderDiscountProductImages;
using CMSMicroservice.Application.DiscountShopCQ.Queries.GetDiscountProductById;
using CMSMicroservice.Application.DiscountShopCQ.Queries.GetDiscountProducts;
using CMSMicroservice.Application.DiscountShopCQ.Queries.GetDiscountProductImages;
using MediatR;
using Mapster;

namespace CMSMicroservice.WebApi.Services;

public class DiscountProductService : DiscountProductContract.DiscountProductContractBase
{
    private readonly IDispatchRequestToCQRS _dispatchRequestToCQRS;
    private readonly ISender _sender;

    public DiscountProductService(IDispatchRequestToCQRS dispatchRequestToCQRS, ISender sender)
    {
        _dispatchRequestToCQRS = dispatchRequestToCQRS;
        _sender = sender;
    }

    public override async Task<CreateDiscountProductResponse> CreateDiscountProduct(CreateDiscountProductRequest request, ServerCallContext context)
    {
        var command = new CreateDiscountProductCommand
        {
            Title = request.Title,
            ShortInfomation = request.ShortInfomation,
            FullInformation = request.FullInformation,
            Price = request.Price,
            MaxDiscountPercent = request.MaxDiscountPercent,
            ImagePath = request.ImagePath,
            ThumbnailPath = request.ThumbnailPath,
            SortOrder = request.SortOrder,
            IsActive = request.IsActive,
            CategoryIds = request.CategoryIds?.ToList() ?? new List<long>(),
            // Map binary image data
            ImageFileBytes = request.ImageFile?.File?.ToByteArray(),
            ImageFileMime = request.ImageFile?.Mime,
            ImageFileName = request.ImageFile?.FileName,
            ThumbnailFileBytes = request.ThumbnailFile?.File?.ToByteArray(),
            ThumbnailFileMime = request.ThumbnailFile?.Mime,
            ThumbnailFileName = request.ThumbnailFile?.FileName
        };

        var productId = await _sender.Send(command, context.CancellationToken);
        return new CreateDiscountProductResponse { ProductId = productId };
    }

    public override async Task<Empty> UpdateDiscountProduct(UpdateDiscountProductRequest request, ServerCallContext context)
    {
        var command = new UpdateDiscountProductCommand
        {
            ProductId = request.ProductId,
            Title = request.Title,
            ShortInfomation = request.ShortInfomation,
            FullInformation = request.FullInformation,
            Price = request.Price,
            MaxDiscountPercent = request.MaxDiscountPercent,
            ImagePath = request.ImagePath,
            ThumbnailPath = request.ThumbnailPath,
            SortOrder = request.SortOrder,
            IsActive = request.IsActive,
            CategoryIds = request.CategoryIds?.ToList() ?? new List<long>(),
            // Map binary image data
            ImageFileBytes = request.ImageFile?.File?.ToByteArray(),
            ImageFileMime = request.ImageFile?.Mime,
            ImageFileName = request.ImageFile?.FileName,
            ThumbnailFileBytes = request.ThumbnailFile?.File?.ToByteArray(),
            ThumbnailFileMime = request.ThumbnailFile?.Mime,
            ThumbnailFileName = request.ThumbnailFile?.FileName
        };

        await _sender.Send(command, context.CancellationToken);
        return new Empty();
    }

    public override async Task<Empty> DeleteDiscountProduct(DeleteDiscountProductRequest request, ServerCallContext context)
    {
        return await _dispatchRequestToCQRS.Handle<DeleteDiscountProductRequest, DeleteDiscountProductCommand>(request, context);
    }

    public override async Task<GetDiscountProductByIdResponse> GetDiscountProductById(GetDiscountProductByIdRequest request, ServerCallContext context)
    {
        return await _dispatchRequestToCQRS.Handle<GetDiscountProductByIdRequest, GetDiscountProductByIdQuery, GetDiscountProductByIdResponse>(request, context);
    }

    public override async Task<GetDiscountProductsResponse> GetDiscountProducts(GetDiscountProductsRequest request, ServerCallContext context)
    {
        return await _dispatchRequestToCQRS.Handle<GetDiscountProductsRequest, GetDiscountProductsQuery, GetDiscountProductsResponse>(request, context);
    }

    // Product Image Gallery Operations
    public override async Task<AddDiscountProductImageResponse> AddDiscountProductImage(AddDiscountProductImageRequest request, ServerCallContext context)
    {
        return await _dispatchRequestToCQRS.Handle<AddDiscountProductImageRequest, AddDiscountProductImageCommand, AddDiscountProductImageResponse>(request, context);
    }

    public override async Task<Empty> UpdateDiscountProductImage(UpdateDiscountProductImageRequest request, ServerCallContext context)
    {
        return await _dispatchRequestToCQRS.Handle<UpdateDiscountProductImageRequest, UpdateDiscountProductImageCommand>(request, context);
    }

    public override async Task<Empty> DeleteDiscountProductImage(DeleteDiscountProductImageRequest request, ServerCallContext context)
    {
        return await _dispatchRequestToCQRS.Handle<DeleteDiscountProductImageRequest, DeleteDiscountProductImageCommand>(request, context);
    }

    public override async Task<Empty> ReorderDiscountProductImages(ReorderDiscountProductImagesRequest request, ServerCallContext context)
    {
        return await _dispatchRequestToCQRS.Handle<ReorderDiscountProductImagesRequest, ReorderDiscountProductImagesCommand>(request, context);
    }

    public override async Task<GetDiscountProductImagesResponse> GetDiscountProductImages(GetDiscountProductImagesRequest request, ServerCallContext context)
    {
        var query = request.Adapt<GetDiscountProductImagesQuery>();
        var images = await _sender.Send(query, context.CancellationToken);

        var response = new GetDiscountProductImagesResponse();
        response.Images.AddRange(images.Select(i => i.Adapt<CMSMicroservice.Protobuf.Protos.DiscountProduct.DiscountProductImageDto>()));
        return response;
    }
}
