using MediatR;
using TakeoutSaaS.Application.App.Stores.Dto;
using TakeoutSaaS.Application.App.Stores.Queries;
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 CheckStoreQualificationsQueryHandler(
    IStoreRepository storeRepository,
    ITenantProvider tenantProvider)
    : IRequestHandler<CheckStoreQualificationsQuery, StoreQualificationCheckResultDto>
{
    /// <inheritdoc />
    public async Task<StoreQualificationCheckResultDto> Handle(CheckStoreQualificationsQuery 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, "门店不存在");
        }

        // 2. (空行后) 同主体门店默认视为完整
        if (store.OwnershipType == StoreOwnershipType.SameEntity)
        {
            return new StoreQualificationCheckResultDto
            {
                IsComplete = true,
                CanSubmitAudit = true
            };
        }

        // 3. (空行后) 读取资质列表并统计
        var qualifications = await storeRepository.GetQualificationsAsync(request.StoreId, tenantId, cancellationToken);
        var grouped = qualifications
            .GroupBy(x => x.QualificationType)
            .ToDictionary(x => x.Key, x => x.ToList());

        var expiredCount = qualifications.Count(x => x.IsExpired);
        var expiringSoonCount = qualifications.Count(x => x.IsExpiringSoon);

        var foodStats = BuildRequirement(grouped, StoreQualificationType.FoodServiceLicense, true);
        var businessStats = BuildRequirement(grouped, StoreQualificationType.BusinessLicense, true);
        var storefrontStats = BuildRequirement(grouped, StoreQualificationType.StorefrontPhoto, true);
        var interiorStats = BuildInteriorRequirement(grouped);

        var hasLicense = foodStats.IsValid || businessStats.IsValid;
        var hasStorefront = storefrontStats.IsValid;
        var hasInterior = interiorStats.IsValid;

        var missingTypes = new List<string>();
        if (!hasLicense)
        {
            missingTypes.Add("营业执照/食品经营许可证");
        }

        if (!hasStorefront)
        {
            missingTypes.Add("门头实景照");
        }

        if (!hasInterior)
        {
            missingTypes.Add("店内环境照(至少2张)");
        }

        var warnings = missingTypes.Count == 0
            ? Array.Empty<string>()
            : missingTypes.Select(type => $"缺少必要资质：{type}").ToArray();

        // 4. (空行后) 组装结果
        var requirements = new List<StoreQualificationRequirementDto>
        {
            foodStats,
            businessStats,
            storefrontStats,
            interiorStats
        };

        var isComplete = hasLicense && hasStorefront && hasInterior;
        return new StoreQualificationCheckResultDto
        {
            IsComplete = isComplete,
            CanSubmitAudit = isComplete,
            RequiredTypes = requirements,
            ExpiringSoonCount = expiringSoonCount,
            ExpiredCount = expiredCount,
            MissingTypes = missingTypes,
            Warnings = warnings
        };
    }

    private static StoreQualificationRequirementDto BuildRequirement(
        IReadOnlyDictionary<StoreQualificationType, List<Domain.Stores.Entities.StoreQualification>> grouped,
        StoreQualificationType type,
        bool required)
    {
        var list = grouped.TryGetValue(type, out var items) ? items : [];
        var hasUploaded = list.Count > 0;
        var hasValid = list.Any(item => !item.IsExpired);
        return new StoreQualificationRequirementDto
        {
            QualificationType = type,
            IsRequired = required,
            IsUploaded = hasUploaded,
            IsValid = hasValid,
            UploadedCount = list.Count
        };
    }

    private static StoreQualificationRequirementDto BuildInteriorRequirement(
        IReadOnlyDictionary<StoreQualificationType, List<Domain.Stores.Entities.StoreQualification>> grouped)
    {
        var list = grouped.TryGetValue(StoreQualificationType.InteriorPhoto, out var items) ? items : [];
        var validCount = list.Count(item => !item.IsExpired);
        return new StoreQualificationRequirementDto
        {
            QualificationType = StoreQualificationType.InteriorPhoto,
            IsRequired = true,
            IsUploaded = list.Count > 0,
            IsValid = validCount >= 2,
            UploadedCount = list.Count
        };
    }
}
