using System.Text.Json;
using Microsoft.EntityFrameworkCore;
using Tiku.Application.Tenancy;
using Tiku.Domain.Common;
using Tiku.Domain.Operations;
using Tiku.Infrastructure.Persistence;

namespace Tiku.Infrastructure.Tenancy;

internal sealed class PublicTenantConfigurationQuery(TikuDbContext dbContext)
    : IPublicTenantConfigurationQuery
{
    public async Task<PublicTenantConfiguration> GetAsync(
        Guid tenantId,
        CancellationToken cancellationToken = default)
    {
        var branding = await dbContext.TenantBrandings.AsNoTracking()
            .SingleOrDefaultAsync(item => item.TenantId == tenantId, cancellationToken);
        var settings = await dbContext.TenantSettings.AsNoTracking()
            .SingleOrDefaultAsync(item => item.TenantId == tenantId, cancellationToken);
        var theme = await dbContext.TenantThemeConfigs.AsNoTracking()
            .SingleOrDefaultAsync(
                item => item.TenantId == tenantId && item.Status == TenantThemeConfigStatus.Published,
                cancellationToken);

        return new PublicTenantConfiguration(
            branding?.BrandName,
            branding?.ShortName,
            branding?.Slogan,
            branding?.LogoUrl,
            branding?.FaviconUrl,
            branding?.ServiceWechat,
            branding?.ServiceAccountName,
            IsNonEmptyObject(theme?.ActiveTheme) ? theme!.ActiveTheme.Clone() : CloneOrDefault(branding?.Theme),
            IsNonEmptyObject(theme?.ActivePublicAssets)
                ? theme!.ActivePublicAssets.Clone()
                : CloneOrDefault(branding?.PublicAssets),
            CloneOrDefault(settings?.FeatureFlags),
            CloneOrDefault(settings?.AdminFeatureFlags),
            CloneOrDefault(settings?.PublicConfig));
    }

    private static bool IsNonEmptyObject(JsonElement? value)
    {
        return value is { ValueKind: JsonValueKind.Object } json && json.EnumerateObject().Any();
    }

    private static JsonElement CloneOrDefault(JsonElement? value)
    {
        return value.HasValue ? value.Value.Clone() : JsonDefaults.Object();
    }
}