using Microsoft.EntityFrameworkCore;
using Tiku.Application.Assets;
using Tiku.Application.Content;
using Tiku.Application.Security;
using Tiku.Domain.Content;

namespace Tiku.Infrastructure.Assets;

public sealed partial class AssetManagementService
{
    public async Task<ContentManagementResult<ContentAssetManagementItem>> ArchiveAssetAsync(
        AssetManagementActor actor,
        Guid assetId,
        CancellationToken cancellationToken = default)
    {
        var asset = await dbContext.ContentAssets.SingleOrDefaultAsync(
            item => item.TenantId == actor.TenantId && item.Id == assetId,
            cancellationToken);
        if (asset is null) throw new AssetManagementException("Asset was not found.", "asset_not_found");

        if (asset.Status == ContentStatus.Archived)
            return new ContentManagementResult<ContentAssetManagementItem>(ToItem(asset));

        var accountedBytes = AccountedStorageBytes(asset);
        asset.Status = ContentStatus.Archived;
        asset.UpdatedBy = actor.UserId;
        await dbContext.SaveChangesAsync(cancellationToken);
        if (accountedBytes > 0)
            await featureAccessService.ReleaseQuotaAsync(
                actor.TenantId,
                SaasQuotaMetricCatalog.StorageBytes,
                accountedBytes,
                CancellationToken.None);

        return new ContentManagementResult<ContentAssetManagementItem>(ToItem(asset));
    }

    public Task<AssetManagementSignedAccessResult> SignDownloadAsync(
        AssetManagementActor actor,
        AssetAccessSignCommand command,
        CancellationToken cancellationToken = default)
    {
        return SignAssetAccessAsync(actor, command, AssetAccessType.AdminDownload, "attachment", cancellationToken);
    }

    public Task<AssetManagementSignedAccessResult> SignPreviewAsync(
        AssetManagementActor actor,
        AssetAccessSignCommand command,
        CancellationToken cancellationToken = default)
    {
        return SignAssetAccessAsync(actor, command, AssetAccessType.AdminPreview, "inline", cancellationToken);
    }
}