using CMSMicroservice.Protobuf.Protos.Category;
using CMSMicroservice.WebApi.Common.Services;
using CMSMicroservice.Application.CategoryCQ.Commands.CreateNewCategory;
using CMSMicroservice.Application.CategoryCQ.Commands.UpdateCategory;
using CMSMicroservice.Application.CategoryCQ.Commands.DeleteCategory;
using CMSMicroservice.Application.CategoryCQ.Queries.GetCategory;
using CMSMicroservice.Application.CategoryCQ.Queries.GetAllCategoryByFilter;
using MediatR;
using AppModels = CMSMicroservice.Application.Common.Models;

namespace CMSMicroservice.WebApi.Services;
public class CategoryService : CategoryContract.CategoryContractBase
{
    private readonly IDispatchRequestToCQRS _dispatchRequestToCQRS;
    private readonly ISender _sender;

    public CategoryService(IDispatchRequestToCQRS dispatchRequestToCQRS, ISender sender)
    {
        _dispatchRequestToCQRS = dispatchRequestToCQRS;
        _sender = sender;
    }
    public override async Task<CreateNewCategoryResponse> CreateNewCategory(CreateNewCategoryRequest request, ServerCallContext context)
    {
        return await _dispatchRequestToCQRS.Handle<CreateNewCategoryRequest, CreateNewCategoryCommand, CreateNewCategoryResponse>(request, context);
    }
    public override async Task<Empty> UpdateCategory(UpdateCategoryRequest request, ServerCallContext context)
    {
        return await _dispatchRequestToCQRS.Handle<UpdateCategoryRequest, UpdateCategoryCommand>(request, context);
    }
    public override async Task<Empty> DeleteCategory(DeleteCategoryRequest request, ServerCallContext context)
    {
        return await _dispatchRequestToCQRS.Handle<DeleteCategoryRequest, DeleteCategoryCommand>(request, context);
    }
    public override async Task<GetCategoryResponse> GetCategory(GetCategoryRequest request, ServerCallContext context)
    {
        return await _dispatchRequestToCQRS.Handle<GetCategoryRequest, GetCategoryQuery, GetCategoryResponse>(request, context);
    }
    public override async Task<GetAllCategoryByFilterResponse> GetAllCategoryByFilter(GetAllCategoryByFilterRequest request, ServerCallContext context)
    {
        return await _dispatchRequestToCQRS.Handle<GetAllCategoryByFilterRequest, GetAllCategoryByFilterQuery, GetAllCategoryByFilterResponse>(request, context);
    }
    
    // ============= Customer-specific Methods =============
    
    public override async Task<GetAllCategoriesResponse> GetAllCategories(GetAllCategoriesRequest request, ServerCallContext context)
    {
        // Reuse existing GetAllCategoryByFilter query but with customer-specific response
        return await _dispatchRequestToCQRS.Handle<GetAllCategoriesRequest, GetAllCategoryByFilterQuery, GetAllCategoriesResponse>(request, context);
    }

    public override async Task<GetAllCategoriesForCustomerResponse> GetAllCategoriesForCustomer(GetAllCategoriesForCustomerRequest request, ServerCallContext context)
    {
        // Use GetAllCategoryByFilter to get all active categories
        var query = new GetAllCategoryByFilterQuery
        {
            Filter = new CMSMicroservice.Application.CategoryCQ.Queries.GetAllCategoryByFilter.GetAllCategoryByFilterFilter
            {
                IsActive = true // Only active categories for customers
            },
            PaginationState = new AppModels.PaginationState
            {
                PageNumber = request.PageNumber > 0 ? request.PageNumber : 1,
                PageSize = request.PageSize > 0 ? request.PageSize : 100 // Default to large page size to get all
            },
            SortBy = "SortOrder" // Sort by display order
        };

        var result = await _sender.Send(query, context.CancellationToken);

        var response = new GetAllCategoriesForCustomerResponse
        {
            MetaData = new CMSMicroservice.Protobuf.Protos.MetaData
            {
                CurrentPage = result.MetaData.CurrentPage,
                PageSize = result.MetaData.PageSize,
                TotalCount = result.MetaData.TotalCount,
                TotalPage = result.MetaData.TotalPage,
                HasNext = result.MetaData.HasNext,
                HasPrevious = result.MetaData.HasPrevious
            }
        };

        foreach (var cat in result.Models)
        {
            response.Models.Add(new GetAllCategoryFilterResponseModel
            {
                Id = cat.Id,
                Name = cat.Name,
                Title = cat.Title,
                Description = cat.Description ?? string.Empty,
                ImagePath = cat.ImagePath ?? string.Empty,
                ParentId = cat.ParentId ?? 0,
                IsActive = cat.IsActive,
                SortOrder = cat.SortOrder
            });
        }

        return response;
    }

    #region [ARCHIVED] GetCategoryByIdForCustomer — تکراری: GetCategory (admin) + GetAllCategoriesForCustomer کافی است
    [Obsolete("ARCHIVED: Use GetCategory or GetAllCategoriesForCustomer instead")]
    public override async Task<GetCategoryByIdForCustomerResponse> GetCategoryByIdForCustomer(GetCategoryByIdForCustomerRequest request, ServerCallContext context)
    {
        // [ARCHIVED] duplicate — GetCategory + GetAllCategoriesForCustomer cover this
        var query = new GetCategoryQuery { Id = request.Id };
        var result = await _sender.Send(query, context.CancellationToken);
        
        return new GetCategoryByIdForCustomerResponse
        {
            Category = new GetAllCategoryFilterResponseModel
            {
                Id = result.Id,
                Name = result.Name,
                Title = result.Title,
                Description = result.Description ?? string.Empty,
                ImagePath = result.ImagePath ?? string.Empty,
                ParentId = result.ParentId ?? 0,
                IsActive = result.IsActive,
                SortOrder = result.SortOrder
            }
        };
    }
    #endregion
}
