using GmRelay.Shared.Features.Sessions.CreateSession;
using GmRelay.Shared.Platform;

namespace GmRelay.DiscordBot.Features.Sessions;

public sealed record DiscordSessionInteractionInput(
    Guid SessionId,
    string InteractionId,
    string GuildId,
    string ChannelId,
    string MessageId,
    ulong UserId,
    string Username,
    string? DisplayName);

public static class DiscordSessionInteractionMapper
{
    public static bool TryParseCustomId(string customId, string expectedAction, out Guid sessionId)
    {
        sessionId = default;

        var parts = customId.Split(':', 2);
        return parts.Length == 2
            && string.Equals(parts[0], expectedAction, StringComparison.Ordinal)
            && Guid.TryParse(parts[1], out sessionId);
    }

    public static JoinSessionCommand CreateJoinCommand(DiscordSessionInteractionInput input) =>
        new(
            SessionId: input.SessionId,
            User: CreateUser(input),
            InteractionId: input.InteractionId,
            Group: CreateGroup(input),
            ScheduleMessage: CreateMessageRef(input));

    public static LeaveSessionCommand CreateLeaveCommand(DiscordSessionInteractionInput input) =>
        new(
            SessionId: input.SessionId,
            User: CreateUser(input),
            InteractionId: input.InteractionId,
            Group: CreateGroup(input),
            ScheduleMessage: CreateMessageRef(input));

    private static PlatformUser CreateUser(DiscordSessionInteractionInput input) =>
        new(
            PlatformKind.Discord,
            input.UserId.ToString(System.Globalization.CultureInfo.InvariantCulture),
            string.IsNullOrWhiteSpace(input.DisplayName) ? input.Username : input.DisplayName,
            input.Username);

    private static PlatformGroup CreateGroup(DiscordSessionInteractionInput input) =>
        new(
            PlatformKind.Discord,
            input.GuildId,
            input.GuildId,
            input.ChannelId);

    private static PlatformMessageRef CreateMessageRef(DiscordSessionInteractionInput input) =>
        new(
            PlatformKind.Discord,
            input.GuildId,
            null,
            input.MessageId);
}
