using Collaboration.Application.DTOs.Requests; using Collaboration.Application.Interfaces; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using System.Security.Claims; namespace Collaboration.Api.Controllers; [Authorize] [ApiController] [Route("api/collab")] [Produces("application/json")] public class CollabSessionController : ControllerBase { private readonly ICollabSessionService _service; private Guid UserId => Guid.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier)!); private Guid OrgId => Guid.Parse(User.FindFirstValue("orgId")!); private string DisplayName => User.FindFirstValue("displayName") ?? "Unknown"; public CollabSessionController(ICollabSessionService service) => _service = service; /// Create a new ad-hoc or scheduled session. [HttpPost("sessions")] [ProducesResponseType(typeof(Application.DTOs.Responses.SessionResponse), 201)] public async Task Create([FromBody] CreateSessionRequest request, CancellationToken ct) { var result = await _service.CreateAsync(request, UserId, OrgId, DisplayName, ct); return CreatedAtAction(nameof(GetById), new { id = result.SessionId }, result); } /// Get session by ID. [HttpGet("sessions/{id:guid}")] public async Task GetById(Guid id, CancellationToken ct) { var result = await _service.GetAsync(id, OrgId, ct); return result is null ? NotFound() : Ok(result); } /// Get all sessions I'm currently active in. [HttpGet("sessions/active")] public async Task GetActive(CancellationToken ct) => Ok(await _service.GetActiveSessionsAsync(UserId, OrgId, ct)); /// Get my upcoming scheduled sessions. [HttpGet("sessions/scheduled")] public async Task GetScheduled(CancellationToken ct) => Ok(await _service.GetScheduledSessionsAsync(UserId, OrgId, ct)); /// Start, pause, resume, or end a session. [HttpPatch("sessions/{id:guid}/status")] public async Task UpdateStatus( Guid id, [FromBody] UpdateSessionStatusRequest request, CancellationToken ct) { var result = await _service.UpdateStatusAsync(id, request, UserId, OrgId, ct); return Ok(result); } /// Join a session directly (in-org, by ID). [HttpGet("sessions/{id:guid}/join")] public async Task Join(Guid id, CancellationToken ct) { var result = await _service.JoinAsync(id, UserId, OrgId, DisplayName, ct); return Ok(result); } /// Invite specific users to a session. [HttpPost("sessions/{id:guid}/invites/users")] public async Task InviteUsers( Guid id, [FromBody] InviteUsersRequest request, CancellationToken ct) { await _service.SendUserInvitesAsync(id, request, UserId, OrgId, ct); return NoContent(); } /// Create a shareable invite link for a session. [HttpPost("sessions/{id:guid}/invites/link")] public async Task CreateLinkInvite( Guid id, [FromBody] CreateLinkInviteRequest request, CancellationToken ct) { var result = await _service.CreateLinkInviteAsync(id, request, UserId, OrgId, ct); return Ok(result); } /// Get my pending invites. [HttpGet("invites/pending")] public async Task GetPendingInvites(CancellationToken ct) => Ok(await _service.GetPendingInvitesAsync(UserId, ct)); /// Resolve an invite token and join the session. [HttpPost("invites/{token}/join")] public async Task JoinViaToken(string token, CancellationToken ct) { var result = await _service.JoinViaTokenAsync(token, UserId, OrgId, DisplayName, ct); return Ok(result); } /// Accept or decline an invite. [HttpPatch("invites/{id:guid}/respond")] public async Task RespondToInvite( Guid id, [FromBody] RespondToInviteRequest request, CancellationToken ct) { await _service.RespondToInviteAsync(id, request, UserId, ct); return NoContent(); } /// Grant control to another participant (Host only). [HttpPost("sessions/{id:guid}/control/grant")] public async Task GrantControl( Guid id, [FromBody] GrantControlRequest request, CancellationToken ct) { await _service.GrantControlAsync(id, request, UserId, OrgId, ct); return NoContent(); } /// Revoke control and return it to host (Host only). [HttpPost("sessions/{id:guid}/control/revoke")] public async Task RevokeControl(Guid id, CancellationToken ct) { await _service.RevokeControlAsync(id, UserId, OrgId, ct); return NoContent(); } } [Authorize] [ApiController] [Route("api/collab/config")] [Produces("application/json")] public class CollabConfigController : ControllerBase { private readonly ICollabConfigService _service; private Guid OrgId => Guid.Parse(User.FindFirstValue("orgId")!); public CollabConfigController(ICollabConfigService service) => _service = service; /// Get org collaboration configuration. [HttpGet] public async Task Get(CancellationToken ct) => Ok(await _service.GetAsync(OrgId, ct)); /// Update org collaboration configuration (Admin only). [HttpPut] [Authorize(Policy = "CollabAdmin")] public async Task Update([FromBody] UpdateCollabConfigRequest request, CancellationToken ct) => Ok(await _service.UpdateAsync(OrgId, request, ct)); }