using System.ComponentModel.DataAnnotations;
namespace DorkNet.Server.Data.Entities;
///
/// A Maker-Pen creation that the player has saved as a reusable
/// "invention" — can be re-spawned in any room they enter, shared with
/// other players, or featured on the watch's Inventions tab. The
/// underlying SpawnableTemplateData protobuf bytes are uploaded via
/// storage.rec.net/upload with FileType=Invention (5).
///
public class InventionEntity
{
public long Id { get; set; }
public long CreatorPlayerId { get; set; }
/// Stable opaque GUID the client uses to deduplicate
/// instantiated inventions across rooms (matches
/// Invention.ReplicationId). Generated server-side at
/// create time.
[MaxLength(64)]
public string ReplicationId { get; set; } = string.Empty;
[MaxLength(128)]
public string Name { get; set; } = string.Empty;
[MaxLength(2000)]
public string Description { get; set; } = string.Empty;
[MaxLength(256)]
public string ImageName { get; set; } = string.Empty;
/// Legacy permission column (private=0/friends=1/public=2)
/// — kept for backward-compat with existing rows; new logic uses
/// +
/// (InventionPermission enum: Unassigned=0, LimitedOneUseOnly=10,
/// UseOnly=20, EditAndSave=40, Publish=60, Charge=80,
/// Unlimited=100).
public int Permission { get; set; } = 0;
/// InventionPermission value the creator gets when
/// spawning their own creation (default Unlimited=100).
public int CreatorPermission { get; set; } = 100;
/// InventionPermission value other players get when
/// spawning. Defaults Unassigned=0 (private).
public int GeneralPermission { get; set; } = 0;
/// True once POST api/inventions/v2/publish sets
/// a non-Unassigned . Stays true
/// across re-edits — the wire field tracks "has this ever been
/// published".
public bool IsPublished { get; set; } = false;
/// 1-based latest version index. Bumped each time
/// POST api/inventions/v3/addversion uploads new bytes.
/// Mirrors Invention.CurrentVersionNumber.
public int CurrentVersionNumber { get; set; } = 1;
/// Set on first publish. Null until then.
public DateTime? FirstPublishedAt { get; set; }
/// If the creator was in a room when first saving,
/// the originating room id for analytics.
public long? CreationRoomId { get; set; }
/// How many distinct players have spawned this
/// invention in any room (rolling counter — increments on
/// download).
public int NumPlayersHaveUsedInRoom { get; set; } = 0;
/// True for AG (community-built) inventions, false for
/// "Rec Room Original" / staff-baked ones.
public bool IsAgInvention { get; set; } = true;
/// Most recent uploaded blob name. Format
/// invention__v.dat; the cdn catch-all serves the
/// matching bytes.
[MaxLength(128)]
public string CurrentBlobName { get; set; } = string.Empty;
[MaxLength(1024)]
public string TagsCsv { get; set; } = string.Empty;
public int CheerCount { get; set; } = 0;
public int SpawnCount { get; set; } = 0;
public int Price { get; set; } = 0;
/// Soft-delete flag. When set, the row is hidden from
/// browse / search / detail endpoints but stays in the table so
/// existing references (cheers, reports) keep resolving and the
/// blob bytes can be restored if needed.
public bool IsDeleted { get; set; } = false;
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
}