using CMSMicroservice.Protobuf.Protos.DiscountCategory;

namespace BackOffice.Services.DiscountCategory;

public class DiscountCategoryService : IDiscountCategoryService
{
    private readonly DiscountCategoryContract.DiscountCategoryContractClient _client;

    public DiscountCategoryService(DiscountCategoryContract.DiscountCategoryContractClient client)
    {
        _client = client;
    }

    public async Task<List<DiscountCategoryDto>> GetCategoriesAsync(long? parentCategoryId = null, bool? isActive = null)
    {
        var request = new GetDiscountCategoriesRequest();

        if (parentCategoryId.HasValue)
            request.ParentCategoryId = parentCategoryId.Value;
        if (isActive.HasValue)
            request.IsActive = isActive.Value;

        var response = await _client.GetDiscountCategoriesAsync(request);

        return MapCategories(response.Categories);
    }

    public async Task<DiscountCategoryDto?> GetByIdAsync(long id)
    {
        // Note: Proto doesn't have GetById yet, so we'll get all and filter
        var categories = await GetCategoriesAsync();
        return FindCategoryById(categories, id);
    }

    public async Task<long> CreateAsync(CreateDiscountCategoryDto dto)
    {
        var request = new CreateDiscountCategoryRequest
        {
            Name = dto.Name,
            Title = dto.Title,
            SortOrder = dto.SortOrder,
            IsActive = dto.IsActive
        };

        if (!string.IsNullOrEmpty(dto.Description))
            request.Description = dto.Description;
        if (!string.IsNullOrEmpty(dto.ImagePath))
            request.ImagePath = dto.ImagePath;
        if (dto.ParentCategoryId.HasValue)
            request.ParentCategoryId = dto.ParentCategoryId.Value;

        var response = await _client.CreateDiscountCategoryAsync(request);
        return response.CategoryId;
    }

    public async Task UpdateAsync(long id, UpdateDiscountCategoryDto dto)
    {
        var request = new UpdateDiscountCategoryRequest
        {
            CategoryId = id,
            Name = dto.Name,
            Title = dto.Title,
            SortOrder = dto.SortOrder,
            IsActive = dto.IsActive
        };

        if (!string.IsNullOrEmpty(dto.Description))
            request.Description = dto.Description;
        if (!string.IsNullOrEmpty(dto.ImagePath))
            request.ImagePath = dto.ImagePath;
        if (dto.ParentCategoryId.HasValue)
            request.ParentCategoryId = dto.ParentCategoryId.Value;

        await _client.UpdateDiscountCategoryAsync(request);
    }

    public async Task DeleteAsync(long id)
    {
        var request = new DeleteDiscountCategoryRequest { CategoryId = id };
        await _client.DeleteDiscountCategoryAsync(request);
    }

    private List<DiscountCategoryDto> MapCategories(IEnumerable<CMSMicroservice.Protobuf.Protos.DiscountCategory.DiscountCategoryDto> protoCategories)
    {
        return protoCategories.Select(c => new DiscountCategoryDto
        {
            Id = c.Id,
            Name = c.Name,
            Title = c.Title,
            Description = c.Description,
            ImagePath = c.ImagePath,
            ParentCategoryId = c.ParentCategoryId,
            SortOrder = c.SortOrder,
            IsActive = c.IsActive,
            ProductCount = c.ProductCount,
            Children = c.Children.Count > 0 ? MapCategories(c.Children) : new()
        }).ToList();
    }

    private DiscountCategoryDto? FindCategoryById(List<DiscountCategoryDto> categories, long id)
    {
        foreach (var category in categories)
        {
            if (category.Id == id)
                return category;

            var found = FindCategoryById(category.Children.ToList(), id);
            if (found != null)
                return found;
        }

        return null;
    }
}
