using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using DorkNet.Server.Auth;
using DorkNet.Server.Data;
using DorkNet.Server.Data.Entities;
namespace DorkNet.Server.Controllers.API.ScreenShareReports;
[ApiController]
[Authorize]
public class ScreenShareReportsController(DorkNetDbContext db) : ControllerBase
{
/// Screen-share (photo) report. The 2023-03-21 client posts the
/// form keys ImageName, ReportedPlayerId, RoomId,
/// RoomInstanceId, RoomInstanceType and Details
/// (RecNet.Runtime/KAEAEIODGBG.txt:281-360). It sends no
/// reportCategory at all.
///
/// The old signature bound targetPlayerId, so the reported player
/// was stored as 0 on every screen-share report and the reported image was
/// dropped entirely — the report was unactionable. Form binding is
/// case-insensitive, so RoomId/Details did land; the names
/// that differ are the ones spelled out explicitly below.
[HttpPost("api/screensharereports/v1/report")]
public async Task Report(
[FromForm(Name = "ReportedPlayerId")] long? reportedPlayerId,
[FromForm] long? targetPlayerId,
[FromForm] long? roomId,
[FromForm(Name = "RoomInstanceId")] long? roomInstanceId,
[FromForm(Name = "RoomInstanceType")] int? roomInstanceType,
[FromForm(Name = "ImageName")] string? imageName,
[FromForm] int? reportCategory,
[FromForm] string? details)
{
var reporter = this.RequireCurrentPlayerId();
var target = reportedPlayerId
?? targetPlayerId
?? (long.TryParse(Request.Query["ReportedPlayerId"].FirstOrDefault()
?? Request.Query["targetPlayerId"].FirstOrDefault(), out var qTarget) ? qTarget : 0);
var room = roomId
?? (long.TryParse(Request.Query["roomId"].FirstOrDefault(), out var qRoom) ? qRoom : 0);
// The client never sends a category for screen-share reports; 5 is the
// server's existing "other" bucket.
var category = reportCategory
?? (int.TryParse(Request.Query["reportCategory"].FirstOrDefault(), out var qCategory) ? qCategory : 5);
var message = details ?? Request.Query["details"].FirstOrDefault() ?? string.Empty;
// Keep the evidence (image + instance) in the stored text: ReportEntity
// has no dedicated columns for them and a report without the offending
// image is not actionable by a moderator.
var context = new List();
if (!string.IsNullOrWhiteSpace(imageName)) context.Add($"image={imageName}");
if (roomInstanceId is > 0) context.Add($"instance={roomInstanceId}");
if (roomInstanceType is not null) context.Add($"instanceType={roomInstanceType}");
if (context.Count > 0) message = $"[screenshare {string.Join(' ', context)}] {message}".Trim();
db.Reports.Add(new ReportEntity
{
ReporterPlayerId = reporter,
TargetPlayerId = target,
RoomId = room,
Category = category,
Message = message[..Math.Min(1000, message.Length)],
});
await db.SaveChangesAsync();
return Ok(new { Success = true, Error = string.Empty });
}
}