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; /// /// Sterowanie muzyka przez hosta (ETAP 4). Trasa zaczyna sie od "api/host", wiec jest automatycznie /// chroniona [Authorize] przez KonwencjaAutoryzacjiHosta. /// /// KONTEKST: muzyka NIE idzie przez LiveKit ani SignalR jako dzwiek -- kazda przegladarka (host i /// kazdy widz) samodzielnie odtwarza TEN SAM plik audio spod Utwor.Url, a backend trzyma tylko /// "zegar" (kiedy sie zaczelo, od ktorego miejsca) i widzowie synchronizuja swoja pozycje /// odtwarzania do tego zegara. To jak radio internetowe. /// /// Po kazdej akcji sterujacej zegarem rozsylamy "StanMuzykiZmieniony" (payload StanMuzykiDto) do /// WSZYSTKICH klientow. Zmiany samej biblioteki/kolejki (dodanie/usuniecie utworu) rozsylamy jako /// "MuzykaZmieniona" z aktualna kolejka (payload List<PozycjaPlaylistyDto>). /// [ApiController] [Route("api/host/music")] public class HostMusicController : ControllerBase { private readonly ISerwisMuzyki _serwisMuzyki; private readonly IHubContext _hubKontekst; public HostMusicController(ISerwisMuzyki serwisMuzyki, IHubContext hubKontekst) { _serwisMuzyki = serwisMuzyki; _hubKontekst = hubKontekst; } [HttpPost("utwory")] public async Task DodajUtworAsync([FromBody] DodajUtworKomenda komenda, CancellationToken token) { var wynik = await _serwisMuzyki.DodajUtworAsync(komenda, token); if (!wynik.Sukces || wynik.Dane is null) { return BadRequest(new { blad = wynik.Blad }); } return Ok(wynik.Dane); } /// Cala biblioteka utworow -- do wyboru przy dodawaniu na playliste. [HttpGet("utwory")] public async Task PobierzUtworyAsync(CancellationToken token) { var wynik = await _serwisMuzyki.PobierzUtworyAsync(token); if (!wynik.Sukces || wynik.Dane is null) { return BadRequest(new { blad = wynik.Blad }); } return Ok(wynik.Dane); } [HttpPost("playlista/dodaj")] public async Task DodajDoPlaylistyAsync([FromBody] DodajDoPlaylistyKomenda komenda, CancellationToken token) { var wynik = await _serwisMuzyki.DodajDoPlaylistyAsync(komenda.UtworId, token); if (!wynik.Sukces || wynik.Dane is null) { return BadRequest(new { blad = wynik.Blad }); } await _hubKontekst.Clients.All.SendAsync("MuzykaZmieniona", wynik.Dane, cancellationToken: token); return Ok(wynik.Dane); } [HttpDelete("playlista/{pozycjaId:guid}")] public async Task UsunZPlaylistyAsync(Guid pozycjaId, CancellationToken token) { var wynik = await _serwisMuzyki.UsunZPlaylistyAsync(pozycjaId, token); if (!wynik.Sukces || wynik.Dane is null) { return BadRequest(new { blad = wynik.Blad }); } await _hubKontekst.Clients.All.SendAsync("MuzykaZmieniona", wynik.Dane, cancellationToken: token); return Ok(wynik.Dane); } /// Aktualna kolejka -- do wyswietlenia w panelu hosta po odswiezeniu strony. [HttpGet("playlista")] public async Task PobierzPlaylisteAsync(CancellationToken token) { var wynik = await _serwisMuzyki.PobierzPlaylisteAsync(token); if (!wynik.Sukces || wynik.Dane is null) { return BadRequest(new { blad = wynik.Blad }); } return Ok(wynik.Dane); } [HttpPost("play")] public async Task OdtworzAsync([FromBody] OdtworzKomenda komenda, CancellationToken token) { var wynik = await _serwisMuzyki.OdtworzAsync(komenda.UtworId, token); return await RozglosStanMuzykiAsync(wynik, token); } [HttpPost("pause")] public async Task WstrzymajAsync(CancellationToken token) { var wynik = await _serwisMuzyki.WstrzymajAsync(token); return await RozglosStanMuzykiAsync(wynik, token); } [HttpPost("next")] public async Task NastepnyAsync(CancellationToken token) { var wynik = await _serwisMuzyki.NastepnyAsync(token); return await RozglosStanMuzykiAsync(wynik, token); } [HttpPost("poprzedni")] public async Task PoprzedniAsync(CancellationToken token) { var wynik = await _serwisMuzyki.PoprzedniAsync(token); return await RozglosStanMuzykiAsync(wynik, token); } [HttpPost("glosnosc")] public async Task UstawGlosnoscAsync([FromBody] UstawGlosnoscKomenda komenda, CancellationToken token) { var wynik = await _serwisMuzyki.UstawGlosnoscAsync(komenda.Wartosc, token); return await RozglosStanMuzykiAsync(wynik, token); } private async Task RozglosStanMuzykiAsync(WynikOperacji wynik, CancellationToken token) { if (!wynik.Sukces || wynik.Dane is null) { return BadRequest(new { blad = wynik.Blad }); } await _hubKontekst.Clients.All.SendAsync("StanMuzykiZmieniony", wynik.Dane, cancellationToken: token); return Ok(wynik.Dane); } }