using MediatR;
using FacebookService.API.Application.Dtos;
using FacebookService.Domain.AggregatesModel.CustomerAggregate;

namespace FacebookService.API.Application.Queries;

/// <summary>
/// EN: Handler for GetCustomerByIdQuery.
/// VI: Handler cho GetCustomerByIdQuery.
/// </summary>
public class GetCustomerByIdQueryHandler : IRequestHandler<GetCustomerByIdQuery, CustomerDto?>
{
    private readonly ICustomerRepository _customerRepository;

    public GetCustomerByIdQueryHandler(ICustomerRepository customerRepository)
    {
        _customerRepository = customerRepository ?? throw new ArgumentNullException(nameof(customerRepository));
    }

    public async Task<CustomerDto?> Handle(
        GetCustomerByIdQuery request,
        CancellationToken cancellationToken)
    {
        var customer = await _customerRepository.GetByIdAsync(request.CustomerId, cancellationToken);

        if (customer is null)
        {
            return null;
        }

        return MapToDto(customer);
    }

    private static CustomerDto MapToDto(Customer customer)
    {
        return new CustomerDto(
            customer.Id,
            customer.FacebookUserId,
            customer.Name,
            customer.Email,
            customer.Phone,
            customer.ProfilePicUrl,
            customer.Locale,
            customer.Timezone,
            customer.Tags,
            customer.CustomFields,
            customer.FirstSeenAt,
            customer.LastInteractionAt
        );
    }
}

/// <summary>
/// EN: Handler for GetCustomerByFacebookIdQuery.
/// VI: Handler cho GetCustomerByFacebookIdQuery.
/// </summary>
public class GetCustomerByFacebookIdQueryHandler : IRequestHandler<GetCustomerByFacebookIdQuery, CustomerDto?>
{
    private readonly ICustomerRepository _customerRepository;

    public GetCustomerByFacebookIdQueryHandler(ICustomerRepository customerRepository)
    {
        _customerRepository = customerRepository ?? throw new ArgumentNullException(nameof(customerRepository));
    }

    public async Task<CustomerDto?> Handle(
        GetCustomerByFacebookIdQuery request,
        CancellationToken cancellationToken)
    {
        var customer = await _customerRepository.GetByFacebookUserIdAsync(request.FacebookUserId, cancellationToken);

        if (customer is null)
        {
            return null;
        }

        return new CustomerDto(
            customer.Id,
            customer.FacebookUserId,
            customer.Name,
            customer.Email,
            customer.Phone,
            customer.ProfilePicUrl,
            customer.Locale,
            customer.Timezone,
            customer.Tags,
            customer.CustomFields,
            customer.FirstSeenAt,
            customer.LastInteractionAt
        );
    }
}
