using MediatR;
using FacebookService.Domain.AggregatesModel.CustomerAggregate;

namespace FacebookService.API.Application.Commands;

/// <summary>
/// EN: Handler for CreateCustomerCommand.
/// VI: Handler cho CreateCustomerCommand.
/// </summary>
public class CreateCustomerCommandHandler : IRequestHandler<CreateCustomerCommand, CreateCustomerCommandResult>
{
    private readonly ICustomerRepository _customerRepository;
    private readonly ILogger<CreateCustomerCommandHandler> _logger;

    public CreateCustomerCommandHandler(
        ICustomerRepository customerRepository,
        ILogger<CreateCustomerCommandHandler> logger)
    {
        _customerRepository = customerRepository ?? throw new ArgumentNullException(nameof(customerRepository));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    public async Task<CreateCustomerCommandResult> Handle(
        CreateCustomerCommand request,
        CancellationToken cancellationToken)
    {
        _logger.LogInformation(
            "Processing CreateCustomerCommand for FacebookUserId: {FacebookUserId}",
            request.FacebookUserId);

        // EN: Check if customer already exists / VI: Kiểm tra customer đã tồn tại chưa
        var existingCustomer = await _customerRepository.GetByFacebookUserIdAsync(
            request.FacebookUserId, cancellationToken);

        if (existingCustomer is not null)
        {
            _logger.LogInformation(
                "Customer already exists with ID: {CustomerId}, updating profile",
                existingCustomer.Id);

            // EN: Update existing customer profile / VI: Cập nhật profile customer sẵn có
            existingCustomer.UpdateProfile(
                request.Name,
                request.Email,
                request.Phone,
                request.ProfilePicUrl,
                request.Locale,
                request.Timezone);

            _customerRepository.Update(existingCustomer);
            await _customerRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

            return new CreateCustomerCommandResult(existingCustomer.Id, IsNew: false);
        }

        // EN: Create new customer / VI: Tạo customer mới
        var customer = new Customer(request.FacebookUserId, request.Name);

        // EN: Update profile with optional fields / VI: Cập nhật profile với fields tùy chọn
        customer.UpdateProfile(
            request.Name,
            request.Email,
            request.Phone,
            request.ProfilePicUrl,
            request.Locale,
            request.Timezone);

        _customerRepository.Add(customer);

        // EN: Save changes (dispatches domain events) / VI: Lưu thay đổi (dispatch domain events)
        await _customerRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

        _logger.LogInformation(
            "Customer created successfully with ID: {CustomerId}",
            customer.Id);

        return new CreateCustomerCommandResult(customer.Id, IsNew: true);
    }
}
