using CMSMicroservice.Protobuf.Protos.UserAddress;
using CMSMicroservice.WebApi.Common.Services;
using CMSMicroservice.Application.UserAddressCQ.Commands.CreateNewUserAddress;
using CMSMicroservice.Application.UserAddressCQ.Commands.UpdateUserAddress;
using CMSMicroservice.Application.UserAddressCQ.Commands.DeleteUserAddress;
using CMSMicroservice.Application.UserAddressCQ.Queries.GetUserAddress;
using CMSMicroservice.Application.UserAddressCQ.Queries.GetAllUserAddressByFilter;
using CMSMicroservice.Application.UserAddressCQ.Commands.SetAddressAsDefault;
using CMSMicroservice.Application.UserAddressCQ.Queries.GetCustomerAddresses;
using CMSMicroservice.Application.UserAddressCQ.Commands.CreateCustomerAddress;
using CMSMicroservice.Application.UserAddressCQ.Commands.UpdateCustomerAddress;
using CMSMicroservice.Application.UserAddressCQ.Commands.DeleteCustomerAddress;
using CMSMicroservice.Application.UserAddressCQ.Commands.SetCustomerDefaultAddress;
using MediatR;

namespace CMSMicroservice.WebApi.Services;

public class UserAddressService : UserAddressContract.UserAddressContractBase
{
    private readonly IDispatchRequestToCQRS _dispatchRequestToCQRS;
    private readonly ISender _sender;

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

    #region Admin Methods

    public override async Task<CreateNewUserAddressResponse> CreateNewUserAddress(CreateNewUserAddressRequest request, ServerCallContext context)
    {
        return await _dispatchRequestToCQRS.Handle<CreateNewUserAddressRequest, CreateNewUserAddressCommand, CreateNewUserAddressResponse>(request, context);
    }
    public override async Task<Empty> UpdateUserAddress(UpdateUserAddressRequest request, ServerCallContext context)
    {
        return await _dispatchRequestToCQRS.Handle<UpdateUserAddressRequest, UpdateUserAddressCommand>(request, context);
    }
    public override async Task<Empty> DeleteUserAddress(DeleteUserAddressRequest request, ServerCallContext context)
    {
        return await _dispatchRequestToCQRS.Handle<DeleteUserAddressRequest, DeleteUserAddressCommand>(request, context);
    }
    public override async Task<GetUserAddressResponse> GetUserAddress(GetUserAddressRequest request, ServerCallContext context)
    {
        return await _dispatchRequestToCQRS.Handle<GetUserAddressRequest, GetUserAddressQuery, GetUserAddressResponse>(request, context);
    }
    public override async Task<GetAllUserAddressByFilterResponse> GetAllUserAddressByFilter(GetAllUserAddressByFilterRequest request, ServerCallContext context)
    {
        return await _dispatchRequestToCQRS.Handle<GetAllUserAddressByFilterRequest, GetAllUserAddressByFilterQuery, GetAllUserAddressByFilterResponse>(request, context);
    }
    public override async Task<Empty> SetAddressAsDefault(SetAddressAsDefaultRequest request, ServerCallContext context)
    {
        return await _dispatchRequestToCQRS.Handle<SetAddressAsDefaultRequest, SetAddressAsDefaultCommand>(request, context);
    }

    #endregion

    #region Customer Methods

    public override async Task<GetCustomerAddressesResponse> GetCustomerAddresses(GetCustomerAddressesRequest request, ServerCallContext context)
    {
        var query = new GetCustomerAddressesQuery();
        var result = await _sender.Send(query);

        var response = new GetCustomerAddressesResponse();

        foreach (var addr in result.Addresses)
        {
            response.Models.Add(new CMSMicroservice.Protobuf.Protos.UserAddress.CustomerAddressModel
            {
                Id = addr.Id,
                Title = addr.Title,
                Address = addr.Address,
                PostalCode = addr.PostalCode,
                IsDefault = addr.IsDefault,
                CityId = addr.CityId,
                CityName = addr.CityName,
                ProvinceName = addr.ProvinceName
            });
        }

        return response;
    }

    public override async Task<CreateCustomerAddressResponse> CreateCustomerAddress(CreateCustomerAddressRequest request, ServerCallContext context)
    {
        var command = new CreateCustomerAddressCommand
        {
            Title = request.Title,
            Address = request.Address,
            PostalCode = request.PostalCode,
            IsDefault = request.IsDefault,
            CityId = request.CityId
        };

        var result = await _sender.Send(command);

        return new CreateCustomerAddressResponse
        {
            Id = result.Id,
            Message = result.Message
        };
    }

    public override async Task<Empty> UpdateCustomerAddress(UpdateCustomerAddressRequest request, ServerCallContext context)
    {
        var command = new UpdateCustomerAddressCommand
        {
            Id = request.Id,
            Title = request.Title,
            Address = request.Address,
            PostalCode = request.PostalCode,
            IsDefault = request.IsDefault,
            CityId = request.CityId
        };

        await _sender.Send(command);

        return new Empty();
    }

    public override async Task<Empty> DeleteCustomerAddress(DeleteCustomerAddressRequest request, ServerCallContext context)
    {
        var command = new DeleteCustomerAddressCommand
        {
            Id = request.Id
        };

        await _sender.Send(command);

        return new Empty();
    }

    public override async Task<Empty> SetCustomerDefaultAddress(SetCustomerDefaultAddressRequest request, ServerCallContext context)
    {
        var command = new SetCustomerDefaultAddressCommand
        {
            Id = request.Id
        };

        await _sender.Send(command);

        return new Empty();
    }

    #endregion
}
