import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import { ensureFinancialEntity } from './seed-helpers.js';
import { qualifyTable } from './test-db-config.js';
import { EntityValidationError } from './seed-errors.js';
import { TestDatabase } from './db-setup.js';
describe('ensureFinancialEntity', () => {
    let db;
    beforeAll(async () => {
        db = new TestDatabase();
        await db.connect();
    });
    afterAll(async () => {
        await db.close();
    });
    it('should create a new financial entity when it does not exist', async () => db.withTransaction(async (client) => {
        const result = await ensureFinancialEntity(client, {
            name: 'Test Entity',
            type: 'business',
        });
        expect(result).toHaveProperty('id');
        expect(typeof result.id).toBe('string');
        // Verify it was inserted
        const checkResult = await client.query(`SELECT id, name, type, owner_id FROM ${qualifyTable('financial_entities')} WHERE id = $1`, [result.id]);
        expect(checkResult.rows.length).toBe(1);
        expect(checkResult.rows[0].name).toBe('Test Entity');
        expect(checkResult.rows[0].type).toBe('business');
        expect(checkResult.rows[0].owner_id).toBeNull();
    }));
    it('should return existing entity when called twice with same parameters', async () => db.withTransaction(async (client) => {
        const firstResult = await ensureFinancialEntity(client, {
            name: 'Duplicate Test',
            type: 'tax_category',
        });
        const secondResult = await ensureFinancialEntity(client, {
            name: 'Duplicate Test',
            type: 'tax_category',
        });
        expect(firstResult.id).toBe(secondResult.id);
        // Verify only one row exists
        const countResult = await client.query(`SELECT COUNT(*) FROM ${qualifyTable('financial_entities')} WHERE name = $1 AND type = $2`, ['Duplicate Test', 'tax_category']);
        expect(parseInt(countResult.rows[0].count)).toBe(1);
    }));
    it('should handle entities with owner_id', async () => db.withTransaction(async (client) => {
        // First create an owner entity (business)
        const ownerEntityResult = await ensureFinancialEntity(client, {
            name: 'Owner Entity',
            type: 'business',
        });
        // Create corresponding business record (required for foreign key)
        await client.query(`INSERT INTO ${qualifyTable('businesses')} (id, owner_id) VALUES ($1, $2)`, [
            ownerEntityResult.id, ownerEntityResult.id,
        ]);
        // Create owned entity (tax_category)
        const result = await ensureFinancialEntity(client, {
            name: 'Owned Entity',
            type: 'tax_category',
            ownerId: ownerEntityResult.id,
        });
        expect(result).toHaveProperty('id');
        // Verify owner_id is set correctly
        const checkResult = await client.query(`SELECT owner_id FROM ${qualifyTable('financial_entities')} WHERE id = $1`, [result.id]);
        expect(checkResult.rows[0].owner_id).toBe(ownerEntityResult.id);
    }));
    it('should be idempotent for entities with owner_id', async () => db.withTransaction(async (client) => {
        const ownerEntityResult = await ensureFinancialEntity(client, {
            name: 'Owner Business',
            type: 'business',
        });
        // Create corresponding business record
        await client.query(`INSERT INTO ${qualifyTable('businesses')} (id, owner_id) VALUES ($1, $2)`, [
            ownerEntityResult.id, ownerEntityResult.id,
        ]);
        const firstResult = await ensureFinancialEntity(client, {
            name: 'Child Entity',
            type: 'tax_category',
            ownerId: ownerEntityResult.id,
        });
        const secondResult = await ensureFinancialEntity(client, {
            name: 'Child Entity',
            type: 'tax_category',
            ownerId: ownerEntityResult.id,
        });
        expect(firstResult.id).toBe(secondResult.id);
        // Verify only one row
        const countResult = await client.query(`SELECT COUNT(*) FROM ${qualifyTable('financial_entities')}
       WHERE name = $1 AND type = $2 AND owner_id = $3`, ['Child Entity', 'tax_category', ownerEntityResult.id]);
        expect(parseInt(countResult.rows[0].count)).toBe(1);
    }));
    it('should distinguish entities by type', async () => db.withTransaction(async (client) => {
        const businessResult = await ensureFinancialEntity(client, {
            name: 'Same Name',
            type: 'business',
        });
        const taxCategoryResult = await ensureFinancialEntity(client, {
            name: 'Same Name',
            type: 'tax_category',
        });
        expect(businessResult.id).not.toBe(taxCategoryResult.id);
    }));
    it('should distinguish entities by owner_id', async () => db.withTransaction(async (client) => {
        const owner1Entity = await ensureFinancialEntity(client, {
            name: 'Owner 1',
            type: 'business',
        });
        await client.query(`INSERT INTO ${qualifyTable('businesses')} (id, owner_id) VALUES ($1, $2)`, [
            owner1Entity.id, owner1Entity.id,
        ]);
        const owner2Entity = await ensureFinancialEntity(client, {
            name: 'Owner 2',
            type: 'business',
        });
        await client.query(`INSERT INTO ${qualifyTable('businesses')} (id, owner_id) VALUES ($1, $2)`, [
            owner2Entity.id, owner2Entity.id,
        ]);
        const entity1 = await ensureFinancialEntity(client, {
            name: 'Same Child',
            type: 'tax_category',
            ownerId: owner1Entity.id,
        });
        const entity2 = await ensureFinancialEntity(client, {
            name: 'Same Child',
            type: 'tax_category',
            ownerId: owner2Entity.id,
        });
        expect(entity1.id).not.toBe(entity2.id);
    }));
    it('should handle null vs undefined owner_id consistently', async () => db.withTransaction(async (client) => {
        const result1 = await ensureFinancialEntity(client, {
            name: 'No Owner Entity',
            type: 'business',
            ownerId: undefined,
        });
        const result2 = await ensureFinancialEntity(client, {
            name: 'No Owner Entity',
            type: 'business',
        });
        expect(result1.id).toBe(result2.id);
    }));
    it('should not leak data between tests', async () => db.withTransaction(async (client) => {
        // This test verifies that ROLLBACK works correctly
        // Create an entity in this test
        await ensureFinancialEntity(client, {
            name: 'Transient Entity',
            type: 'business',
        });
        // The entity should exist within this transaction
        const checkInTransaction = await client.query(`SELECT COUNT(*) FROM ${qualifyTable('financial_entities')} WHERE name = $1`, ['Transient Entity']);
        expect(parseInt(checkInTransaction.rows[0].count)).toBe(1);
        // After ROLLBACK in afterEach, this data won't be visible in next test
    }));
    // Validation tests
    it('should reject empty entity name', async () => db.withTransaction(async (client) => {
        await expect(ensureFinancialEntity(client, {
            name: '',
            type: 'business',
        })).rejects.toThrow(EntityValidationError);
    }));
    it('should reject invalid entity type', async () => db.withTransaction(async (client) => {
        await expect(ensureFinancialEntity(client, {
            name: 'Test Entity',
            type: 'invalid_type',
        })).rejects.toThrow(EntityValidationError);
    }));
    it('should reject whitespace-only name', async () => db.withTransaction(async (client) => {
        await expect(ensureFinancialEntity(client, {
            name: '   ',
            type: 'business',
        })).rejects.toThrow(EntityValidationError);
    }));
});
//# sourceMappingURL=seed-helpers.financial-entity.test.js.map