using System.ComponentModel.DataAnnotations;
using System.Text.Json;
using Tiku.Application.Assets;
using Tiku.Application.Storage;
using Tiku.Domain.Content;

namespace Tiku.Api.Contracts;

/// <summary>
///     资产访问签名查询参数。
/// </summary>
public sealed class AssetAccessQueryDto
{
    /// <summary>
    ///     租户编码。
    /// </summary>
    [StringLength(100)]
    public string? TenantCode { get; set; }

    /// <summary>
    ///     有效期秒数。
    /// </summary>
    [Range(1, 7200)]
    public int? ExpiresInSeconds { get; set; }
}

/// <summary>
///     资产访问签名响应。
/// </summary>
public sealed record AssetAccessResponseDto(
    ContentAssetAccessSummaryDto Item,
    AssetAccessPrincipalDto Access,
    SignedStorageUrlDto Url,
    JsonElement Watermark)
{
    public static AssetAccessResponseDto FromApplication(AssetAccessResultModel result)
    {
        return new AssetAccessResponseDto(
            ContentAssetAccessSummaryDto.FromApplication(result.Item),
            new AssetAccessPrincipalDto(
                result.Access.UserId,
                result.Access.IsMember,
                result.Access.HasSvip),
            SignedStorageUrlDto.FromApplication(result.Url),
            result.Watermark);
    }
}

/// <summary>
///     内容资产访问摘要。
/// </summary>
public sealed record ContentAssetAccessSummaryDto(
    Guid Id,
    ContentAssetType AssetType,
    string? Title,
    string? FileName,
    string? PreviewUrl,
    AssetUploadStatus UploadStatus,
    AssetSecurityScanStatus SecurityScanStatus,
    AssetPreviewStatus PreviewStatus,
    ContentVisibility Visibility)
{
    public static ContentAssetAccessSummaryDto FromApplication(ContentAssetAccessSummary item)
    {
        return new ContentAssetAccessSummaryDto(
            item.Id,
            item.AssetType,
            item.Title,
            item.FileName,
            item.PreviewUrl,
            item.UploadStatus,
            item.SecurityScanStatus,
            item.PreviewStatus,
            item.Visibility);
    }
}

/// <summary>
///     资产访问Principal请求 DTO。
/// </summary>
public sealed record AssetAccessPrincipalDto(
    Guid? UserId,
    bool IsMember,
    bool HasSvip);

/// <summary>
///     SignedStorageUrl请求 DTO。
/// </summary>
public sealed record SignedStorageUrlDto(
    string Provider,
    string? Bucket,
    string? ObjectKey,
    string Method,
    string Url,
    IReadOnlyDictionary<string, string> Headers,
    DateTimeOffset ExpiresAt,
    int ExpiresInSeconds,
    string SignatureMode)
{
    public static SignedStorageUrlDto FromApplication(ObjectStorageSignedUrl signedUrl)
    {
        return new SignedStorageUrlDto(
            signedUrl.Provider,
            signedUrl.Bucket,
            signedUrl.ObjectKey,
            signedUrl.Method,
            signedUrl.Url.AbsoluteUri,
            signedUrl.Headers,
            signedUrl.ExpiresAt,
            (int)signedUrl.ExpiresIn.TotalSeconds,
            signedUrl.SignatureMode);
    }
}