using BlueLaminate.EFCore.Data;
using Microsoft.EntityFrameworkCore;
namespace BlueLaminate.Core.CsMoney;
/// One marketplace's current presence for a skin or a physical item.
/// "csfloat", "csmoney", …
/// Active listings on this market.
/// Cheapest active listing (the comparable price).
/// Dearest active listing.
/// When this market was last observed to have it.
public sealed record MarketPresence(
string Marketplace, int ActiveCount, decimal MinPrice, decimal MaxPrice, DateTimeOffset LastSeenAt);
///
/// Answers "where is this listed?" over the cross-market market_listings view.
/// Per physical item () for the exact-copy / arbitrage /
/// dupe view, or per catalogue skin () for "which markets
/// carry this skin, and cheapest where".
///
public sealed class MarketPresenceService
{
private const string Active = "Active";
private readonly SkinTrackerDbContext _db;
public MarketPresenceService(SkinTrackerDbContext db) => _db = db;
/// Markets currently listing this exact physical copy.
public Task> ForInstanceAsync(int skinInstanceId, CancellationToken ct = default) =>
_db.MarketListings
.Where(m => m.SkinInstanceId == skinInstanceId && m.Status == Active)
.GroupBy(m => m.Marketplace)
.Select(g => new MarketPresence(
g.Key, g.Count(), g.Min(x => x.Price), g.Max(x => x.Price), g.Max(x => x.LastSeenAt)))
.ToListAsync(ct);
/// Markets currently listing this skin (any wear), cheapest per market.
public Task> ForSkinAsync(int skinId, CancellationToken ct = default) =>
_db.MarketListings
.Where(m => m.SkinId == skinId && m.Status == Active)
.GroupBy(m => m.Marketplace)
.Select(g => new MarketPresence(
g.Key, g.Count(), g.Min(x => x.Price), g.Max(x => x.Price), g.Max(x => x.LastSeenAt)))
.ToListAsync(ct);
}