using System.ComponentModel.DataAnnotations;
namespace DorkNet.Server.Data.Entities;
///
/// One in-game camera photo, posted to the social feed. The actual
/// pixel bytes live in keyed by
/// (uploaded earlier via storage.rec.net's
/// /upload endpoint with FileType=Image). This entity wraps that blob
/// with the social metadata: who took it, where, who's tagged in it,
/// when it was posted, and how many cheers it has.
///
/// Public photos are visible without auth on feed.rec.net; private
/// photos are only listable by the uploader (and admins). Soft-delete
/// via so moderation can take a photo down
/// without losing the audit trail.
///
public class PhotoEntity
{
public long Id { get; set; }
public long UploaderPlayerId { get; set; }
/// The cdn filename — the same string returned by
/// storage.rec.net/upload and used in the cdn.rec.net/{name}
/// download path. Indexed because feed lookups join blob bytes
/// via this key.
[MaxLength(256)]
public string BlobName { get; set; } = string.Empty;
/// Optional caption typed on the watch's "Share" panel
/// before posting. Limited so a single photo can't grow the
/// table row unbounded.
[MaxLength(2048)]
public string Caption { get; set; } = string.Empty;
/// The room the photo was taken in (resolved from
/// PlayerPresenceService at upload time). 0 if the player wasn't
/// in any room (rare — only happens during loading).
public long RoomId { get; set; }
/// Comma-separated list of tagged player IDs. The watch
/// builds this from the players visible in the camera's frustum
/// when the shutter was pressed. Tagged players show up in their
/// own "Photos of me" feed.
[MaxLength(2048)]
public string TaggedPlayerIdsCsv { get; set; } = string.Empty;
/// If false, photo only appears in the uploader's own
/// "My photos" page (and admin views); if true, it shows up on
/// the public feed.rec.net feed and any tagged player's
/// "Photos of me" tab. Defaults to true since the camera's
/// "Share" button is the natural action — making it private is
/// an explicit toggle.
public bool IsPublic { get; set; } = true;
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
/// Soft-delete sentinel — non-null means the photo is
/// hidden from every feed but still in the table for audit.
/// Admin moderation tools set this; the bytes blob is kept until
/// a separate cleanup job decides the audit window has elapsed.
public DateTime? DeletedAt { get; set; }
/// Denormalised cheer counter — incremented when a
/// CheerEntity row is inserted with TargetPhotoId=this.Id, so the
/// feed sort doesn't have to JOIN+aggregate every render.
public int CheerCount { get; set; }
public int ViewCount { get; set; }
}