// EN: Command to update shop settings (features, operating hours).
// VI: Command để cập nhật cài đặt shop (tính năng, giờ hoạt động).

using MediatR;
using MerchantService.Domain.AggregatesModel.ShopAggregate;
using MerchantService.Domain.Exceptions;

namespace MerchantService.API.Application.Commands.Shops;

/// <summary>
/// EN: Command to update shop settings.
/// VI: Command để cập nhật cài đặt shop.
/// </summary>
public record UpdateShopSettingsCommand : IRequest
{
    public Guid ShopId { get; init; }
    public UpdateShopFeaturesRequest? Features { get; init; }
    public string? OpenTime { get; init; }
    public string? CloseTime { get; init; }
    public List<string>? OpenDays { get; init; }
}

/// <summary>
/// EN: Request model for updating shop features.
/// VI: Model request để cập nhật tính năng shop.
/// </summary>
public record UpdateShopFeaturesRequest
{
    public bool HasInventory { get; init; }
    public bool HasBooking { get; init; }
    public bool HasTables { get; init; }
    public bool HasKitchen { get; init; }
    public bool HasShipping { get; init; }
    public bool HasDelivery { get; init; }
}

/// <summary>
/// EN: Handler for updating shop settings.
/// VI: Handler để cập nhật cài đặt shop.
/// </summary>
public class UpdateShopSettingsCommandHandler : IRequestHandler<UpdateShopSettingsCommand>
{
    private readonly IShopRepository _shopRepository;

    public UpdateShopSettingsCommandHandler(IShopRepository shopRepository)
    {
        _shopRepository = shopRepository;
    }

    public async Task Handle(UpdateShopSettingsCommand request, CancellationToken cancellationToken)
    {
        var shop = await _shopRepository.GetByIdAsync(request.ShopId, cancellationToken)
            ?? throw new DomainException($"Shop {request.ShopId} not found");

        // EN: Update features if provided
        // VI: Cập nhật tính năng nếu được cung cấp
        if (request.Features != null)
        {
            var features = new ShopFeatures
            {
                HasInventory = request.Features.HasInventory,
                HasBooking = request.Features.HasBooking,
                HasTables = request.Features.HasTables,
                HasKitchen = request.Features.HasKitchen,
                HasShipping = request.Features.HasShipping,
                HasDelivery = request.Features.HasDelivery
            };
            shop.UpdateFeatures(features);
        }

        // EN: Update operating hours if time fields are provided
        // VI: Cập nhật giờ hoạt động nếu các trường thời gian được cung cấp
        if (request.OpenTime != null || request.CloseTime != null || request.OpenDays != null)
        {
            var currentHours = shop.OperatingHours;
            var openTime = request.OpenTime != null
                ? TimeOnly.Parse(request.OpenTime)
                : currentHours?.OpenTime ?? new TimeOnly(8, 0);
            var closeTime = request.CloseTime != null
                ? TimeOnly.Parse(request.CloseTime)
                : currentHours?.CloseTime ?? new TimeOnly(22, 0);
            var openDays = request.OpenDays != null
                ? request.OpenDays.Select(d => Enum.Parse<DayOfWeek>(d, ignoreCase: true)).ToList()
                : currentHours?.OpenDays ?? Enum.GetValues<DayOfWeek>().ToList();

            var hours = new OperatingHours
            {
                OpenTime = openTime,
                CloseTime = closeTime,
                OpenDays = openDays
            };
            shop.UpdateOperatingHours(hours);
        }

        _shopRepository.Update(shop);
        await _shopRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);
    }
}
