using Dapper;
using Npgsql;

namespace Books.Api.EventFlow.Repositories;

/// <summary>
/// PostgreSQL implementation of voucher number generation.
/// Uses database-level locking to ensure unique sequential numbers.
/// </summary>
public class VoucherNumberService(NpgsqlDataSource dataSource) : IVoucherNumberService
{
    public async Task<string> GetNextVoucherNumberAsync(
        string companyId,
        string? fiscalYearId = null,
        CancellationToken cancellationToken = default)
    {
        var effectiveFiscalYearId = fiscalYearId ?? "default";

        await using var connection = await dataSource.OpenConnectionAsync(cancellationToken);

        // Use UPSERT with RETURNING to atomically get and increment the sequence
        const string sql = """
            INSERT INTO voucher_number_sequences (company_id, fiscal_year_id, last_number, prefix, updated_at)
            VALUES (@CompanyId, @FiscalYearId, 1, @Prefix, NOW())
            ON CONFLICT (company_id, fiscal_year_id)
            DO UPDATE SET
                last_number = voucher_number_sequences.last_number + 1,
                updated_at = NOW()
            RETURNING prefix, last_number
            """;

        // Generate prefix from fiscal year (e.g., "2025-") or use "K-" for kassekladde
        var prefix = GeneratePrefix(fiscalYearId);

        var result = await connection.QuerySingleAsync<(string Prefix, int LastNumber)>(
            sql,
            new { CompanyId = companyId, FiscalYearId = effectiveFiscalYearId, Prefix = prefix });

        // Format: K-0001 or 2025-0001
        return $"{result.Prefix}{result.LastNumber:D4}";
    }

    private static string GeneratePrefix(string? fiscalYearId)
    {
        if (string.IsNullOrEmpty(fiscalYearId) || fiscalYearId == "default")
        {
            return "K-"; // K for Kassekladde
        }

        // Try to extract year from fiscal year ID (format: fiscalyear-{guid})
        // In a real scenario, you might want to look up the fiscal year's actual year
        return "K-";
    }
}
