using MediatR;
using Microsoft.Extensions.Logging;
using TakeoutSaaS.Application.App.Tenants.Commands;
using TakeoutSaaS.Domain.Tenants.Repositories;
using TakeoutSaaS.Shared.Abstractions.Constants;
using TakeoutSaaS.Shared.Abstractions.Exceptions;
using TakeoutSaaS.Shared.Abstractions.Tenancy;

namespace TakeoutSaaS.Application.App.Tenants.Handlers;

/// <summary>
/// 更新租户基础信息处理器。
/// </summary>
public sealed class UpdateTenantCommandHandler(
    ITenantRepository tenantRepository,
    ITenantProvider tenantProvider,
    ILogger<UpdateTenantCommandHandler> logger)
    : IRequestHandler<UpdateTenantCommand, Unit>
{
    /// <inheritdoc />
    public async Task<Unit> Handle(UpdateTenantCommand request, CancellationToken cancellationToken)
    {
        // 1. 校验租户上下文（租户端禁止跨租户）
        var currentTenantId = tenantProvider.GetCurrentTenantId();
        if (currentTenantId <= 0)
        {
            throw new BusinessException(ErrorCodes.BadRequest, "缺少租户标识");
        }

        // 2. (空行后) 兼容旧调用：若传入 TenantId，则必须与当前租户一致
        if (request.TenantId > 0 && request.TenantId != currentTenantId)
        {
            throw new BusinessException(ErrorCodes.Forbidden, "无权操作其他租户信息");
        }

        // 3. (空行后) 参数校验：租户名称
        if (string.IsNullOrWhiteSpace(request.Name))
        {
            throw new BusinessException(ErrorCodes.BadRequest, "租户名称不能为空");
        }

        // 4. (空行后) 查询租户
        var tenant = await tenantRepository.FindByIdAsync(currentTenantId, cancellationToken)
            ?? throw new BusinessException(ErrorCodes.NotFound, "租户不存在");

        // 5. (空行后) 校验租户名称唯一性（排除自身）
        var normalizedName = request.Name.Trim();
        if (await tenantRepository.ExistsByNameAsync(normalizedName, excludeTenantId: currentTenantId, cancellationToken))
        {
            throw new BusinessException(ErrorCodes.Conflict, $"租户名称 {normalizedName} 已存在");
        }

        // 6. (空行后) 校验联系人手机号唯一性（仅当填写时）
        if (!string.IsNullOrWhiteSpace(request.ContactPhone))
        {
            var normalizedPhone = request.ContactPhone.Trim();
            var existingTenantId = await tenantRepository.FindTenantIdByContactPhoneAsync(normalizedPhone, cancellationToken);
            if (existingTenantId.HasValue && existingTenantId.Value != currentTenantId)
            {
                throw new BusinessException(ErrorCodes.Conflict, $"手机号 {normalizedPhone} 已注册");
            }
        }

        // 7. (空行后) 更新基础信息（禁止修改 Code）
        tenant.Name = normalizedName;
        tenant.ShortName = string.IsNullOrWhiteSpace(request.ShortName) ? null : request.ShortName.Trim();
        tenant.Industry = string.IsNullOrWhiteSpace(request.Industry) ? null : request.Industry.Trim();
        tenant.ContactName = string.IsNullOrWhiteSpace(request.ContactName) ? null : request.ContactName.Trim();
        tenant.ContactPhone = string.IsNullOrWhiteSpace(request.ContactPhone) ? null : request.ContactPhone.Trim();
        tenant.ContactEmail = string.IsNullOrWhiteSpace(request.ContactEmail) ? null : request.ContactEmail.Trim();

        // 8. (空行后) 持久化更新
        await tenantRepository.UpdateTenantAsync(tenant, cancellationToken);
        await tenantRepository.SaveChangesAsync(cancellationToken);

        // 9. (空行后) 记录日志
        logger.LogInformation("已更新租户基础信息 {TenantId}", tenant.Id);

        return Unit.Value;
    }
}
