// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System.Text.Json.Nodes;
using Microsoft.Extensions.AI;
using Microsoft.Teams.Apps;
using Microsoft.Teams.Apps.Handlers;
using Microsoft.Teams.Apps.Schema;
using Microsoft.Teams.Apps.Schema.Entities;
using OpenAI;

WebApplicationBuilder builder = WebApplication.CreateSlimBuilder(args);
builder.Services.AddTeamsBotApplication();

string apiKey = builder.Configuration["OpenAI:ApiKey"] ?? throw new InvalidOperationException("OpenAI:ApiKey is required.");
string modelId = builder.Configuration["OpenAI:ModelId"] ?? throw new InvalidOperationException("OpenAI:ModelId is required.");

IChatClient chatClient = new OpenAIClient(apiKey)
    .GetChatClient(modelId)
    .AsIChatClient();

WebApplication webApp = builder.Build();
TeamsBotApplication teamsApp = webApp.UseTeamsBotApplication();

teamsApp.OnMessage(async (context, cancellationToken) =>
{
    TeamsStreamingWriter writer = TeamsStreamingWriter.CreateFromContext(context);
    await writer.SendInformativeUpdateAsync("Thinking…", cancellationToken);
    await Task.Delay(500, cancellationToken);
    await writer.SendInformativeUpdateAsync("Thinking again !!!", cancellationToken);

    string userText = context.Activity.Text ?? "Tell me something interesting.";

    await foreach (ChatResponseUpdate update in chatClient.GetStreamingResponseAsync(
        [new ChatMessage(ChatRole.User, userText)],
        cancellationToken: cancellationToken))
    {
        if (!string.IsNullOrEmpty(update.Text))
            await writer.AppendResponseAsync(update.Text, cancellationToken);
    }

    await writer.AppendResponseAsync(" [1]", cancellationToken);

    CitationEntity citation = new()
    {
        AdditionalType = ["AIGeneratedContent"],
        Citation =
        [
            new CitationClaim
            {
                Position = 1,
                Appearance = new CitationAppearance
                {
                    Name     = "OpenAI " + modelId,
                    Abstract = "Response generated by " + modelId + " via the OpenAI API.",
                    Url      = new Uri("https://platform.openai.com/docs/models"),
                    Icon     = CitationIcon.Text,
                }.ToDocument()
            }
        ]
    };

    TeamsAttachment card = TeamsAttachment.CreateBuilder()
        .WithAdaptiveCard(new JsonObject
        {
            ["type"] = "AdaptiveCard",
            ["version"] = "1.5",
            ["body"] = new JsonArray
            {
                new JsonObject
                {
                    ["type"] = "TextBlock",
                    ["text"] = "Response generated by " + modelId,
                    ["wrap"] = true,
                }
            }
        })
        .Build();

    await writer.FinalizeResponseAsync(
        attachments: [card],
        entities: [citation],
        feedbackEnabled: true,
        cancellationToken: cancellationToken);
});

teamsApp.OnMessageSubmitAction(async (context, cancellationToken) =>
{
    await context.SendActivityAsync("You submitted an action with name and value:" + context.Activity.Value?.ActionName + " - " + context.Activity.Value?.ActionValue, cancellationToken);

    return new InvokeResponse(200);
});

webApp.Run();
