using System.Text.Json;
using Microsoft.EntityFrameworkCore;
using Tiku.Application.Jobs;
using Tiku.Domain.Content;
using Tiku.Infrastructure.Jobs;
using Tiku.Infrastructure.Persistence;

namespace Tiku.Infrastructure.Content.Exports;

internal sealed class ContentExportJobHandler(TikuDbContext dbContext) : IBackgroundJobHandler
{
    public string JobType => "content_export";

    public async Task<BackgroundJobHandlerResult> HandleAsync(
        BackgroundJobExecutionContext context,
        CancellationToken cancellationToken = default)
    {
        var exportType = BackgroundJobPayload.GetString(context.Payload, "exportType") ?? "summary";
        var assetKey = $"background-jobs/{context.JobId:N}/content-export.json";
        var asset = await dbContext.ContentAssets.SingleOrDefaultAsync(
            item => item.TenantId == context.TenantId && item.AssetKey == assetKey,
            cancellationToken);
        if (asset is null)
        {
            asset = new ContentAsset
            {
                TenantId = context.TenantId,
                AssetKey = assetKey,
                AssetType = ContentAssetType.Document,
                StorageProvider = AssetStorageProvider.ExternalUrl,
                UploadStatus = AssetUploadStatus.Verified,
                SecurityScanStatus = AssetSecurityScanStatus.NotRequired,
                Source = "background_job"
            };
            dbContext.ContentAssets.Add(asset);
        }

        var questionBankCount =
            await dbContext.QuestionBanks.CountAsync(item => item.TenantId == context.TenantId, cancellationToken);
        var questionCount =
            await dbContext.Questions.CountAsync(item => item.TenantId == context.TenantId, cancellationToken);
        var studentCount =
            await dbContext.StudentProfiles.CountAsync(item => item.TenantId == context.TenantId, cancellationToken);
        asset.FileName = $"content-export-{DateTimeOffset.UtcNow:yyyyMMddHHmmss}.json";
        asset.Title = "Content export manifest";
        asset.Description = $"Generated content export manifest for {exportType}.";
        asset.ObjectKey = assetKey;
        asset.MimeType = "application/json";
        asset.Metadata = JsonSerializer.SerializeToElement(new
        {
            exportType,
            generatedAt = DateTimeOffset.UtcNow,
            questionBankCount,
            questionCount,
            studentCount,
            payload = context.Payload
        });
        await dbContext.SaveChangesAsync(cancellationToken);
        return new BackgroundJobHandlerResult(
            JsonSerializer.SerializeToElement(new
            {
                outputAssetId = asset.Id,
                asset.AssetKey,
                questionBankCount,
                questionCount,
                studentCount
            }),
            asset.Id);
    }
}
