using Npgsql;
using Testcontainers.PostgreSql;

namespace GmRelay.Bot.Tests.Features.Sessions.CreateSession.Wizard;

[CollectionDefinition(Name)]
public sealed class WizardDraftRepositoryCollection : ICollectionFixture<WizardDraftRepositoryFixture>
{
    public const string Name = "Wizard draft repository PostgreSQL";
}

public sealed class WizardDraftRepositoryFixture : IAsyncLifetime
{
    private static readonly TimeSpan ContainerTimeout = TimeSpan.FromMinutes(2);
    private readonly PostgreSqlContainer container = new PostgreSqlBuilder("postgres:17-alpine").Build();

    public Task InitializeAsync()
    {
        return container.StartAsync().WaitAsync(ContainerTimeout);
    }

    public Task DisposeAsync()
    {
        return container.DisposeAsync().AsTask().WaitAsync(ContainerTimeout);
    }

    public async Task<string> CreateSchemaDatabaseAsync()
    {
        var databaseName = $"wizard_drafts_{Guid.NewGuid():N}";

        await using (var adminConnection = new NpgsqlConnection(container.GetConnectionString()))
        {
            await adminConnection.OpenAsync().WaitAsync(ContainerTimeout);
            await using var createDatabase = new NpgsqlCommand($"CREATE DATABASE \"{databaseName}\"", adminConnection);
            await createDatabase.ExecuteNonQueryAsync().WaitAsync(ContainerTimeout);
        }

        var connectionString = new NpgsqlConnectionStringBuilder(container.GetConnectionString())
        {
            Database = databaseName,
            Timeout = 10,
            CommandTimeout = 10
        }.ConnectionString;

        await using (var connection = new NpgsqlConnection(connectionString))
        {
            await connection.OpenAsync().WaitAsync(ContainerTimeout);
            await using var createSchema = new NpgsqlCommand(
                """
                CREATE TABLE wizard_drafts (
                    id UUID PRIMARY KEY,
                    chat_id TEXT NOT NULL,
                    message_thread_id TEXT,
                    owner_id TEXT NOT NULL,
                    platform TEXT NOT NULL DEFAULT 'Telegram',
                    step TEXT NOT NULL,
                    payload JSONB NOT NULL,
                    draft_message_id TEXT,
                    created_at TIMESTAMPTZ NOT NULL,
                    updated_at TIMESTAMPTZ NOT NULL,
                    expires_at TIMESTAMPTZ NOT NULL
                );

                CREATE INDEX idx_wizard_drafts_owner
                    ON wizard_drafts(platform, owner_id);

                CREATE INDEX idx_wizard_drafts_platform
                    ON wizard_drafts(platform);
                """,
                connection);
            await createSchema.ExecuteNonQueryAsync().WaitAsync(ContainerTimeout);
        }

        return connectionString;
    }
}
