using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using SameBeat.Api.Hubs;
using SameBeat.Application.DTO;
using SameBeat.Application.Interfejsy;
using SameBeat.Application.Komendy;
namespace SameBeat.Api.Controllers;
///
/// Czat na zywo (ETAP 6) -- dostepny dla kazdego widza, nie tylko uczestnikow na scenie. Wszystkie
/// endpointy sa [AllowAnonymous]: widz nie ma konta ani wpisu w poczekalni, tylko lekka tozsamosc
/// czatu (UczestnikCzatu) zalozona przez POST /api/chat/dolacz.
///
[ApiController]
[Route("api/chat")]
public class ChatController : ControllerBase
{
private readonly ISerwisCzatu _serwisCzatu;
private readonly IHubContext _hubKontekst;
public ChatController(ISerwisCzatu serwisCzatu, IHubContext hubKontekst)
{
_serwisCzatu = serwisCzatu;
_hubKontekst = hubKontekst;
}
/// Zaklada nowa tozsamosc czatu dla biezacego wydarzenia. Bez sekretu sesji -- czat nie daje praw do audio/wideo.
[HttpPost("dolacz")]
[AllowAnonymous]
public async Task DolaczAsync([FromBody] DolaczDoCzatuKomenda komenda, CancellationToken token)
{
var wynik = await _serwisCzatu.DolaczAsync(komenda, token);
if (!wynik.Sukces || wynik.Dane is null)
{
return BadRequest(new { blad = wynik.Blad });
}
return Ok(wynik.Dane);
}
/// Wysyla wiadomosc i rozglasza ja przez SignalR do wszystkich klientow. Odrzuca ban/wyciszenie/zbyt szybkie pisanie.
[HttpPost("wiadomosc")]
[AllowAnonymous]
public async Task WyslijWiadomoscAsync([FromBody] WyslijWiadomoscKomenda komenda, CancellationToken token)
{
var wynik = await _serwisCzatu.WyslijWiadomoscAsync(komenda, token);
if (!wynik.Sukces || wynik.Dane is null)
{
return BadRequest(new { blad = wynik.Blad });
}
var pelnaWiadomosc = wynik.Dane;
// Publiczny broadcast (wszyscy, rowniez anonimowi widzowie) -- CELOWO bez UczestnikCzatuId,
// patrz komentarz w WiadomoscCzatuDto. Host dostaje ten sam JSON PLUS UczestnikCzatuId przez
// osobny broadcast tylko do grupy "host" -- bez tego przyciski moderacji (wycisz/zbanuj) nie
// mialyby jak wskazac nadawcy.
var publicznaWiadomosc = new WiadomoscCzatuDto(pelnaWiadomosc.Id, pelnaWiadomosc.Nick, pelnaWiadomosc.Tresc, pelnaWiadomosc.WyslanoUtc);
await _hubKontekst.Clients.All.SendAsync("ChatNowaWiadomosc", publicznaWiadomosc, cancellationToken: token);
await _hubKontekst.Clients.Group(StanImprezyHub.GrupaHost).SendAsync("ChatNowaWiadomoscHost", pelnaWiadomosc, cancellationToken: token);
return Ok(pelnaWiadomosc);
}
/// Ostatnie wiadomosci NIE usuniete dla biezacego wydarzenia -- do zaladowania historii zaraz po wejsciu na /party.
[HttpGet("historia")]
[AllowAnonymous]
public async Task PobierzHistorieAsync(CancellationToken token)
{
var wynik = await _serwisCzatu.PobierzHistorieAsync(token);
if (!wynik.Sukces || wynik.Dane is null)
{
return BadRequest(new { blad = wynik.Blad });
}
return Ok(wynik.Dane);
}
}