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

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

namespace BookingService.API.Application.Commands.Therapist;

/// <summary>
/// EN: Handler for updating therapist details.
/// VI: Handler để cập nhật thông tin chuyên viên.
/// </summary>
public class UpdateTherapistCommandHandler : IRequestHandler<UpdateTherapistCommand, TherapistDto>
{
    private readonly ITherapistRepository _therapistRepository;
    private readonly ILogger<UpdateTherapistCommandHandler> _logger;

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

    public async Task<TherapistDto> Handle(UpdateTherapistCommand request, CancellationToken cancellationToken)
    {
        _logger.LogInformation(
            "Updating therapist {TherapistId} / Cập nhật chuyên viên {TherapistId}",
            request.TherapistId);

        // EN: Load therapist from repository
        // VI: Load chuyên viên từ repository
        var therapist = await _therapistRepository.GetByIdAsync(request.TherapistId, cancellationToken);
        if (therapist == null)
        {
            throw new DomainException($"Therapist {request.TherapistId} not found / Không tìm thấy chuyên viên {request.TherapistId}");
        }

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

        // EN: Update via domain behavior method
        // VI: Cập nhật qua phương thức hành vi domain
        therapist.Update(request.Name, request.Specialties, workingHoursJson);

        // EN: Save changes
        // VI: Lưu thay đổi
        _therapistRepository.Update(therapist);
        await _therapistRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

        _logger.LogInformation(
            "Updated therapist {TherapistId} / Đã cập nhật chuyên viên {TherapistId}",
            therapist.Id);

        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
        };
    }
}
