using Luna.Channels.Abstractions; using Luna.Core.Abstractions; using Luna.Identity.Abstractions; using Luna.Shared; namespace Luna.Channels.Web; public class WebChannel(string channelId, IChatHubContext hubContext, IUserIdentityService identityService) : IChannel { public string ChannelId { get; } = channelId; public string ChannelType => Abstractions.ChannelType.Web; public string DisplayName { get; } = "Web Interface"; public bool IsConnected { get; } public event ChannelMessageReceivedEventHandler? MessageReceived; public event ChannelConnectionChangedEventHandler? ConnectionStateChanged; public Task VerifyChannelLinkAsync() => Task.FromResult(true); public async Task SendStreamingMessageAsync(IAsyncEnumerable messageStream, CancellationToken cancellationToken = default) { await hubContext.SendStreamingResponseAsync(ChannelId, messageStream, cancellationToken); } public async Task SendMessageAsync(ChannelMessage message, CancellationToken cancellationToken = default) { await hubContext.SendResponseAsync(ChannelId, message, cancellationToken); } public async Task RaiseMessageReceivedAsync(object? sender, ChannelMessage message) { if (message.Content.StartsWith("/")) { await HandleCommandAsync(message.Content); return; } MessageReceived?.Invoke(sender, new ChannelMessageReceivedEventArgs { Channel = this, Message = message, IsHandled = false }); } private async Task HandleCommandAsync(string command) { var parts = command.Split(' ', StringSplitOptions.RemoveEmptyEntries); var commandName = parts[0].ToLowerInvariant(); var responseText = commandName switch { "/link" => HandleLinkCommand(parts), _ => $"Unknown command: {commandName}" }; await SendMessageAsync(new ChannelMessage( MessageId: Guid.NewGuid().ToString(), ConversationId: Guid.NewGuid().ToString(), SenderId: "luna", SenderName: "Luna", Content: responseText, Timestamp: DateTimeOffset.UtcNow)); } private string HandleLinkCommand(string[] parts) { if (parts.Length < 3) return "Usage: /link "; var channelType = parts[1].ToLowerInvariant(); var code = parts[2].ToUpperInvariant(); var currentUser = identityService.GetCurrentUser(); if (identityService.IsChannelLinked(currentUser.UserId, channelType)) return $"Channel {channelType} is already linked to your account."; try { identityService.CompleteChannelLink(currentUser.UserId, channelType, code); return $"Successfully linked {channelType} channel to your account."; } catch (InvalidOperationException ex) { return $"Failed to link channel: {ex.Message}"; } } public void Dispose() { } }