using foodmarket.Application.Common.Tenancy;
using foodmarket.Domain.Organizations;
using foodmarket.Infrastructure.Persistence;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace foodmarket.Api.Controllers;
/// Регистрация токенов устройств для push (iOS/Android/Web). Приложение/PWA
/// вызывает после получения разрешения. Реальная отправка пока заглушка — см.
/// IPushSender/StubPushSender; таблица и регистрация заложены заранее.
[ApiController]
[Authorize]
[Route("api/me/device-tokens")]
public class DeviceTokensController : ControllerBase
{
private readonly AppDbContext _db;
private readonly ITenantContext _tenant;
public DeviceTokensController(AppDbContext db, ITenantContext tenant)
{
_db = db;
_tenant = tenant;
}
public record RegisterInput(string Platform, string Token);
/// Зарегистрировать/обновить токен устройства текущего пользователя.
/// Идемпотентно по токену (повторный вызов обновляет LastSeenAt/владельца).
[HttpPost]
public async Task Register([FromBody] RegisterInput input, CancellationToken ct)
{
var orgId = _tenant.OrganizationId;
var userId = _tenant.UserId;
if (orgId is null || userId is null) return Unauthorized();
if (string.IsNullOrWhiteSpace(input.Token)) return BadRequest(new { error = "Пустой токен." });
var platform = string.IsNullOrWhiteSpace(input.Platform) ? "ios" : input.Platform.Trim().ToLowerInvariant();
var now = DateTime.UtcNow;
var existing = await _db.DeviceTokens.FirstOrDefaultAsync(t => t.Token == input.Token, ct);
if (existing is null)
{
_db.DeviceTokens.Add(new DeviceToken
{
OrganizationId = orgId.Value, UserId = userId.Value,
Platform = platform, Token = input.Token.Trim(), LastSeenAt = now,
});
}
else
{
existing.OrganizationId = orgId.Value;
existing.UserId = userId.Value;
existing.Platform = platform;
existing.LastSeenAt = now;
}
await _db.SaveChangesAsync(ct);
return NoContent();
}
/// Удалить токен (при выходе/отзыве разрешения).
[HttpDelete]
public async Task Unregister([FromQuery] string token, CancellationToken ct)
{
var existing = await _db.DeviceTokens.FirstOrDefaultAsync(t => t.Token == token, ct);
if (existing is not null) { _db.DeviceTokens.Remove(existing); await _db.SaveChangesAsync(ct); }
return NoContent();
}
}