using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json.Serialization;
using NodaTime;
namespace DysonNetwork.Shared.Models;
public class RemoteStorageConfig
{
    public string Id { get; set; } = string.Empty;
    public string Label { get; set; } = string.Empty;
    public string Region { get; set; } = string.Empty;
    public string Bucket { get; set; } = string.Empty;
    public string Endpoint { get; set; } = string.Empty;
    public string SecretId { get; set; } = string.Empty;
    public string SecretKey { get; set; } = string.Empty;
    public bool EnableSigned { get; set; }
    public bool EnableSsl { get; set; }
    public string? ImageProxy { get; set; }
    public string? AccessProxy { get; set; }
}
/// 
/// Common interface for cloud file entities that can be used in file operations.
/// This interface exposes the essential properties needed for file operations
/// and is implemented by both CloudFile and CloudFileReferenceObject.
/// 
public interface ICloudFile
{
    public Instant CreatedAt { get; }
    public Instant UpdatedAt { get; }
    public Instant? DeletedAt { get; }
    
    /// 
    /// Gets the unique identifier of the cloud file.
    /// 
    string Id { get; }
    /// 
    /// Gets the name of the cloud file.
    /// 
    string Name { get; }
    /// 
    /// Gets the file metadata dictionary.
    /// 
    Dictionary? FileMeta { get; }
    /// 
    /// Gets the user metadata dictionary.
    /// 
    Dictionary? UserMeta { get; }
    /// 
    /// Gets the MIME type of the file.
    /// 
    string? MimeType { get; }
    /// 
    /// Gets the hash of the file content.
    /// 
    string? Hash { get; }
    /// 
    /// Gets the size of the file in bytes.
    /// 
    long Size { get; }
    /// 
    /// Gets whether the file has a compressed version available.
    /// 
    bool HasCompression { get; }
}
/// 
/// The class that used in jsonb columns which referenced the cloud file.
/// The aim of this class is to store some properties that won't change to a file to reduce the database load.
/// 
public class CloudFileReferenceObject : ModelBase, ICloudFile
{
    public string Id { get; set; } = null!;
    public string Name { get; set; } = string.Empty;
    public Dictionary? FileMeta { get; set; } = null!;
    public Dictionary? UserMeta { get; set; } = null!;
    public string? MimeType { get; set; }
    public string? Hash { get; set; }
    public long Size { get; set; }
    public bool HasCompression { get; set; } = false;
}
public class CloudFile : ModelBase, ICloudFile, IIdentifiedResource
{
    /// The id generated by TuS, basically just UUID remove the dash lines
    [MaxLength(32)]
    public string Id { get; set; } = Guid.NewGuid().ToString();
    [MaxLength(1024)] public string Name { get; set; } = string.Empty;
    [MaxLength(4096)] public string? Description { get; set; }
    [Column(TypeName = "jsonb")] public Dictionary? FileMeta { get; set; } = null!;
    [Column(TypeName = "jsonb")] public Dictionary? UserMeta { get; set; } = null!;
    [Column(TypeName = "jsonb")] public List? SensitiveMarks { get; set; } = [];
    [MaxLength(256)] public string? MimeType { get; set; }
    [MaxLength(256)] public string? Hash { get; set; }
    public long Size { get; set; }
    public Instant? UploadedAt { get; set; }
    [MaxLength(128)] public string? UploadedTo { get; set; }
    public bool HasCompression { get; set; } = false;
    
    /// 
    /// The field is set to true if the recycling job plans to delete the file.
    /// Due to the unstable of the recycling job, this doesn't really delete the file until a human verifies it.
    /// 
    public bool IsMarkedRecycle { get; set; } = false;
    /// The object name which stored remotely,
    /// multiple cloud file may have same storage id to indicate they are the same file
    /// 
    /// If the storage id was null and the uploaded at is not null, means it is an embedding file,
    /// The embedding file means the file is store on another site,
    /// or it is a webpage (based on mimetype)
    [MaxLength(32)]
    public string? StorageId { get; set; }
    /// This field should be null when the storage id is filled
    /// Indicates the off-site accessible url of the file
    [MaxLength(4096)]
    public string? StorageUrl { get; set; }
    [JsonIgnore] public Shared.Models.Account Account { get; set; } = null!;
    public Guid AccountId { get; set; }
    public CloudFileReferenceObject ToReferenceObject()
    {
        return new CloudFileReferenceObject
        {
            CreatedAt = CreatedAt,
            UpdatedAt = UpdatedAt,
            DeletedAt = DeletedAt,
            Id = Id,
            Name = Name,
            FileMeta = FileMeta,
            UserMeta = UserMeta,
            MimeType = MimeType,
            Hash = Hash,
            Size = Size,
            HasCompression = HasCompression
        };
    }
    public string ResourceIdentifier => $"file/{Id}";
}
public enum ContentSensitiveMark
{
    Language,
    SexualContent,
    Violence,
    Profanity,
    HateSpeech,
    Racism,
    AdultContent,
    DrugAbuse,
    AlcoholAbuse,
    Gambling,
    SelfHarm,
    ChildAbuse,
    Other
}
public class CloudFileReference : ModelBase
{
    public Guid Id { get; set; } = Guid.NewGuid();
    [MaxLength(32)] public string FileId { get; set; } = null!;
    public CloudFile File { get; set; } = null!;
    [MaxLength(1024)] public string Usage { get; set; } = null!;
    [MaxLength(1024)] public string ResourceId { get; set; } = null!;
    /// 
    /// Optional expiration date for the file reference
    /// 
    public Instant? ExpiredAt { get; set; }
}