using Microsoft.EntityFrameworkCore;
using Tiku.Application.PlatformAdmin;
using Tiku.Application.Security;

namespace Tiku.Infrastructure.PlatformAdmin;

internal sealed partial class PlatformAdminService
{
    public async Task<PlatformOverview> GetOverviewAsync(
        PlatformAdminActor actor,
        CancellationToken cancellationToken = default)
    {
        await AssertPlatformPermissionAsync(actor, BackendPermissions.PlatformDashboardView, cancellationToken);
        return await ExecuteSystemAsync("platform overview", async dbContext =>
        {
            var row = await dbContext.Database.SqlQuery<PlatformOverviewRow>($"""
                                                                              SELECT
                                                                                  (SELECT count(*)::integer FROM tenants WHERE mode <> 'platform_owned') AS "TenantCount",
                                                                                  (SELECT count(*)::integer FROM tenants WHERE mode <> 'platform_owned' AND status = 'active') AS "ActiveTenantCount",
                                                                                  (SELECT count(*)::integer FROM tenants WHERE mode <> 'platform_owned' AND status = 'suspended') AS "SuspendedTenantCount",
                                                                                  (SELECT count(*)::integer FROM orders) AS "OrderCount",
                                                                                  (SELECT count(*)::integer FROM orders WHERE status = 'paid') AS "PaidOrderCount",
                                                                                  (SELECT COALESCE(sum(amount_cents - refunded_amount_cents), 0)::integer FROM orders WHERE status IN ('paid', 'partially_refunded')) AS "RevenueCents",
                                                                                  (SELECT count(*)::integer FROM question_banks) AS "QuestionBankCount",
                                                                                  (SELECT count(*)::integer FROM questions WHERE status = 'published') AS "QuestionCount",
                                                                                  (SELECT count(DISTINCT user_id)::integer FROM practice_sessions WHERE started_at >= {DateTimeOffset.UtcNow.AddDays(-7)}) AS "LearningActiveUserCount"
                                                                              """).SingleAsync(cancellationToken);
            return new PlatformOverview(
                row.TenantCount,
                row.ActiveTenantCount,
                row.SuspendedTenantCount,
                row.OrderCount,
                row.PaidOrderCount,
                row.RevenueCents,
                row.QuestionBankCount,
                row.QuestionCount,
                row.LearningActiveUserCount);
        }, cancellationToken);
    }

    private sealed class PlatformOverviewRow
    {
        public int TenantCount { get; init; }
        public int ActiveTenantCount { get; init; }
        public int SuspendedTenantCount { get; init; }
        public int OrderCount { get; init; }
        public int PaidOrderCount { get; init; }
        public int RevenueCents { get; init; }
        public int QuestionBankCount { get; init; }
        public int QuestionCount { get; init; }
        public int LearningActiveUserCount { get; init; }
    }
}