namespace BlueLaminate.EFCore.Entities;
///
/// One offer observed on skin.land via its internal
/// GET /api/v2/obtained-skins?skin_id={id}&page={n} endpoint (scraped through
/// the Python worker, since skin.land has no public API and sits behind Cloudflare).
///
/// Kept in its own table like , but deliberately thinner:
/// skin.land exposes a full-precision float and price but no paint seed / def index,
/// so an offer can't be fingerprinted to a market-agnostic and
/// there is no cross-market roll-up or dupe detection here (revisit if pattern is ever
/// exposed). StatTrak and Souvenir live on separate skin.land pages (their own
/// stattrak-/souvenir- slugs); v1 sweeps the base page per skin+wear, so
/// / are normally false.
///
/// Soft-tracked across sweeps exactly like :
/// / bound the observation window and
/// flips to when a once-seen
/// offer stops appearing (sold/delisted).
///
public class SkinLandListing
{
public int Id { get; set; }
/// skin.land's offer id (obtained-skin id). Natural key for dedup.
public long ListingId { get; set; }
// Catalogue links. Like cs.money (and unlike the CSFloat global sweep) these are NOT
// best-effort: each scrape job targets one skin+wear, so we set them directly.
public int SkinId { get; set; }
public Skin Skin { get; set; } = null!;
public int? ConditionId { get; set; }
public SkinCondition? Condition { get; set; }
// Item identity, from the offer's skin block.
public string MarketHashName { get; set; } = null!;
public decimal? FloatValue { get; set; } // item_float (string, full precision)
public bool IsStatTrak { get; set; }
public bool IsSouvenir { get; set; }
public string? NameTag { get; set; } // offer.name_tag (rare; affects value)
public int StickerCount { get; set; }
// Pricing. skin.land returns a single price (the amount to buy/withdraw the item).
public decimal Price { get; set; } // final_withdrawal_price
public string Currency { get; set; } = "USD"; // prices are read in USD
public string? InspectLink { get; set; } // item_link (steam:// inspect)
// Soft-tracking across sweeps.
public DateTimeOffset FirstSeenAt { get; set; }
public DateTimeOffset LastSeenAt { get; set; }
public ListingStatus Status { get; set; }
public DateTimeOffset? RemovedAt { get; set; }
}