using MediatR;
using Microsoft.Extensions.Logging;
using TakeoutSaaS.Application.App.Stores.Commands;
using TakeoutSaaS.Application.App.Stores.Dto;
using TakeoutSaaS.Domain.Stores.Enums;
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 ToggleBusinessStatusCommandHandler(
    IStoreRepository storeRepository,
    ITenantProvider tenantProvider,
    ILogger<ToggleBusinessStatusCommandHandler> logger)
    : IRequestHandler<ToggleBusinessStatusCommand, StoreDto>
{
    /// <inheritdoc />
    public async Task<StoreDto> Handle(ToggleBusinessStatusCommand 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, "门店不存在");
        }

        if (store.AuditStatus != StoreAuditStatus.Activated)
        {
            throw new BusinessException(ErrorCodes.Conflict, "门店未激活，无法切换状态");
        }

        if (store.BusinessStatus == StoreBusinessStatus.ForceClosed)
        {
            throw new BusinessException(ErrorCodes.Conflict, "门店已被风控强制关闭，无法切换");
        }

        // 2. (空行后) 应用状态变更
        if (request.BusinessStatus == StoreBusinessStatus.Resting)
        {
            if (!request.ClosureReason.HasValue)
            {
                throw new BusinessException(ErrorCodes.ValidationFailed, "切换休息中必须选择歇业原因");
            }

            store.BusinessStatus = StoreBusinessStatus.Resting;
            store.ClosureReason = request.ClosureReason;
            store.ClosureReasonText = request.ClosureReasonText?.Trim();
        }
        else
        {
            store.BusinessStatus = StoreBusinessStatus.Open;
            store.ClosureReason = null;
            store.ClosureReasonText = null;
        }

        // 3. (空行后) 保存并返回
        await storeRepository.UpdateStoreAsync(store, cancellationToken);
        await storeRepository.SaveChangesAsync(cancellationToken);
        logger.LogInformation("切换门店 {StoreId} 状态至 {BusinessStatus}", store.Id, store.BusinessStatus);

        return StoreMapping.ToDto(store);
    }
}
