using MediatR;
using Microsoft.Extensions.Logging;
using TakeoutSaaS.Application.App.Stores;
using TakeoutSaaS.Application.App.Stores.Commands;
using TakeoutSaaS.Application.App.Stores.Dto;
using TakeoutSaaS.Application.App.Stores.Validators;
using TakeoutSaaS.Domain.Stores.Entities;
using TakeoutSaaS.Domain.Stores.Repositories;
using TakeoutSaaS.Shared.Abstractions.Constants;
using TakeoutSaaS.Shared.Abstractions.Exceptions;
using TakeoutSaaS.Shared.Abstractions.Tenancy;

namespace TakeoutSaaS.Application.App.Stores.Handlers;

/// <summary>
/// 批量更新营业时段处理器。
/// </summary>
public sealed class BatchUpdateBusinessHoursCommandHandler(
    IStoreRepository storeRepository,
    ITenantProvider tenantProvider,
    ILogger<BatchUpdateBusinessHoursCommandHandler> logger)
    : IRequestHandler<BatchUpdateBusinessHoursCommand, IReadOnlyList<StoreBusinessHourDto>>
{
    /// <inheritdoc />
    public async Task<IReadOnlyList<StoreBusinessHourDto>> Handle(BatchUpdateBusinessHoursCommand request, CancellationToken cancellationToken)
    {
        // 1. 校验门店存在
        var tenantId = tenantProvider.GetCurrentTenantId();
        var store = await storeRepository.FindByIdAsync(request.StoreId, tenantId, cancellationToken);
        if (store is null)
        {
            throw new BusinessException(ErrorCodes.NotFound, "门店不存在");
        }
        var storeTenantId = store.TenantId;

        // 2. (空行后) 校验时段重叠
        var overlapError = BusinessHourValidators.ValidateOverlap(request.Items);
        if (!string.IsNullOrWhiteSpace(overlapError))
        {
            throw new BusinessException(ErrorCodes.ValidationFailed, overlapError);
        }

        // 3. (空行后) 删除旧时段
        var existingHours = await storeRepository.GetBusinessHoursAsync(request.StoreId, storeTenantId, cancellationToken);
        foreach (var hour in existingHours)
        {
            await storeRepository.DeleteBusinessHourAsync(hour.Id, storeTenantId, cancellationToken);
        }

        // 4. (空行后) 新增时段配置
        if (request.Items.Count > 0)
        {
            var hours = request.Items.Select(item => new StoreBusinessHour
            {
                TenantId = storeTenantId,
                StoreId = request.StoreId,
                DayOfWeek = item.DayOfWeek,
                HourType = item.HourType,
                StartTime = item.StartTime,
                EndTime = item.EndTime,
                CapacityLimit = item.CapacityLimit,
                Notes = item.Notes?.Trim()
            }).ToList();

            await storeRepository.AddBusinessHoursAsync(hours, cancellationToken);
        }

        // 5. (空行后) 保存并返回结果
        await storeRepository.SaveChangesAsync(cancellationToken);
        logger.LogInformation("批量更新门店营业时段 {StoreId}", request.StoreId);

        var refreshed = await storeRepository.GetBusinessHoursAsync(request.StoreId, storeTenantId, cancellationToken);
        return refreshed.Select(StoreMapping.ToDto).ToList();
    }
}
