using Books.Api.EventFlow.ReadModels;
using Dapper;
using Npgsql;

namespace Books.Api.EventFlow.Repositories;

public class JournalEntryDraftRepository(NpgsqlDataSource dataSource) : IJournalEntryDraftRepository
{
    private const string SelectColumns = """
        aggregate_id AS Id,
        company_id AS CompanyId,
        name AS Name,
        voucher_number AS VoucherNumber,
        document_date AS DocumentDate,
        description AS Description,
        fiscal_year_id AS FiscalYearId,
        lines AS Lines,
        attachment_ids AS AttachmentIds,
        status AS Status,
        transaction_id AS TransactionId,
        posted_at AS PostedAt,
        created_by AS CreatedBy,
        create_time AS CreatedAt,
        updated_time AS UpdatedAt,
        extraction_data AS ExtractionData
        """;

    public async Task<JournalEntryDraftReadModelDto?> GetByIdAsync(
        string id,
        CancellationToken cancellationToken = default)
    {
        await using var connection = await dataSource.OpenConnectionAsync(cancellationToken);

        var sql = $"""
            SELECT {SelectColumns}
            FROM journal_entry_draft_read_models
            WHERE aggregate_id = @Id
            """;

        return await connection.QuerySingleOrDefaultAsync<JournalEntryDraftReadModelDto>(
            sql,
            new { Id = id });
    }

    public async Task<IReadOnlyList<JournalEntryDraftReadModelDto>> GetActiveByCompanyIdAsync(
        string companyId,
        CancellationToken cancellationToken = default)
    {
        await using var connection = await dataSource.OpenConnectionAsync(cancellationToken);

        var sql = $"""
            SELECT {SelectColumns}
            FROM journal_entry_draft_read_models
            WHERE company_id = @CompanyId AND status = 'active'
            ORDER BY updated_time DESC
            """;

        var result = await connection.QueryAsync<JournalEntryDraftReadModelDto>(
            sql,
            new { CompanyId = companyId });

        return result.ToList();
    }

    public async Task<IReadOnlyList<JournalEntryDraftReadModelDto>> GetByCompanyIdAsync(
        string companyId,
        CancellationToken cancellationToken = default)
    {
        await using var connection = await dataSource.OpenConnectionAsync(cancellationToken);

        var sql = $"""
            SELECT {SelectColumns}
            FROM journal_entry_draft_read_models
            WHERE company_id = @CompanyId
            ORDER BY updated_time DESC
            """;

        var result = await connection.QueryAsync<JournalEntryDraftReadModelDto>(
            sql,
            new { CompanyId = companyId });

        return result.ToList();
    }
}
