// EN: Handler for CreateTherapistCommand.
// VI: Handler cho CreateTherapistCommand.

using System.Text.Json;
using BookingService.API.Application.DTOs;
using BookingService.Domain.AggregatesModel.TherapistAggregate;
using MediatR;

namespace BookingService.API.Application.Commands.Therapist;

/// <summary>
/// EN: Handler for creating new therapists.
/// VI: Handler để tạo chuyên viên mới.
/// </summary>
public class CreateTherapistCommandHandler : IRequestHandler<CreateTherapistCommand, TherapistDto>
{
    private readonly ITherapistRepository _therapistRepository;
    private readonly ILogger<CreateTherapistCommandHandler> _logger;

    public CreateTherapistCommandHandler(
        ITherapistRepository therapistRepository,
        ILogger<CreateTherapistCommandHandler> logger)
    {
        _therapistRepository = therapistRepository ?? throw new ArgumentNullException(nameof(therapistRepository));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    public async Task<TherapistDto> Handle(CreateTherapistCommand request, CancellationToken cancellationToken)
    {
        _logger.LogInformation(
            "Creating therapist {Name} for shop {ShopId} / Tạo chuyên viên {Name} cho shop {ShopId}",
            request.Name, request.ShopId);

        // EN: Serialize working hours to JSON for domain entity
        // VI: Serialize giờ làm việc sang JSON cho domain entity
        var workingHoursJson = JsonSerializer.Serialize(request.WorkingHours, new JsonSerializerOptions
        {
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase
        });

        // EN: Create therapist via domain aggregate
        // VI: Tạo chuyên viên qua domain aggregate
        var therapist = new Domain.AggregatesModel.TherapistAggregate.Therapist(
            request.ShopId,
            request.Name,
            request.Specialties,
            workingHoursJson
        );

        // EN: Save to repository
        // VI: Lưu vào repository
        _therapistRepository.Add(therapist);
        await _therapistRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

        _logger.LogInformation(
            "Created therapist {TherapistId} / Đã tạo chuyên viên {TherapistId}",
            therapist.Id);

        // EN: Return DTO
        // VI: Trả về DTO
        return new TherapistDto
        {
            Id = therapist.Id,
            ShopId = therapist.ShopId,
            Name = therapist.Name,
            Specialties = therapist.Specialties,
            WorkingHours = therapist.WorkingHours,
            IsActive = therapist.IsActive,
            CreatedAt = therapist.CreatedAt,
            UpdatedAt = therapist.UpdatedAt
        };
    }
}
