using Tiku.Application.Storage;
using Tiku.Domain.Operations;

namespace Tiku.Application.Tenancy;

public sealed record TenantArchivePreview(
    Guid TenantId,
    bool CanArchive,
    bool HasRecentSuccessfulExport,
    IReadOnlyCollection<string> Blockers);

public sealed record TenantLifecycleOperationItem(
    Guid Id,
    Guid TenantId,
    TenantLifecycleOperationType OperationType,
    TenantLifecycleOperationStatus Status,
    Guid RequestedBy,
    Guid? TargetUserId,
    Guid? ExportAssetId,
    string? Reason,
    string? LastError,
    DateTimeOffset CreatedAt,
    DateTimeOffset? CompletedAt);

public interface ITenantLifecycleService
{
    Task<TenantArchivePreview> PreviewArchiveAsync(Guid tenantId, CancellationToken cancellationToken = default);

    Task<TenantLifecycleOperationItem> CreateExportAsync(Guid tenantId, Guid actorUserId,
        CancellationToken cancellationToken = default);

    Task<TenantLifecycleOperationItem?> GetOperationAsync(Guid tenantId, Guid operationId,
        CancellationToken cancellationToken = default);

    Task<ObjectStorageSignedUrl> SignExportDownloadAsync(Guid tenantId, Guid operationId,
        CancellationToken cancellationToken = default);

    Task<TenantLifecycleOperationItem> ArchiveAsync(Guid tenantId, Guid actorUserId, string reason,
        CancellationToken cancellationToken = default);

    Task<TenantLifecycleOperationItem> RestoreAsync(Guid tenantId, Guid actorUserId, string reason,
        CancellationToken cancellationToken = default);

    Task<TenantLifecycleOperationItem> TransferOwnerAsync(Guid tenantId, Guid actorUserId, Guid targetUserId,
        string reason, CancellationToken cancellationToken = default);
}

public sealed class TenantLifecycleException(string code, string message) : Exception(message)
{
    public string Code { get; } = code;
}