// -- Table generation ---------------------------------------------------------
export function generateTables(entities, engine) {
    const tables = [];
    for (const entity of entities) {
        const columns = [
            {
                name: 'id',
                type: engine === 'mongodb' ? 'ObjectId' : 'uuid',
                nullable: false,
                default: engine === 'postgresql' || engine === 'supabase' ? 'gen_random_uuid()' : null,
                comment: 'Primary key',
            },
        ];
        for (const field of entity.fields) {
            columns.push({
                name: field,
                type: inferColumnType(field),
                nullable: !isRequiredField(field),
                default: null,
                comment: '',
            });
        }
        const foreignKeys = [];
        for (const related of entity.relatesTo) {
            const fkColumn = `${related}_id`;
            columns.push({
                name: fkColumn,
                type: engine === 'mongodb' ? 'ObjectId' : 'uuid',
                nullable: true,
                default: null,
                comment: `FK to ${related}`,
            });
            foreignKeys.push({
                column: fkColumn,
                references: `${related}(id)`,
                onDelete: 'SET NULL',
                onUpdate: 'CASCADE',
            });
        }
        columns.push({
            name: 'created_at',
            type: 'timestamp',
            nullable: false,
            default: engine === 'mongodb' ? null : 'now()',
            comment: 'Creation timestamp',
        }, {
            name: 'updated_at',
            type: 'timestamp',
            nullable: false,
            default: engine === 'mongodb' ? null : 'now()',
            comment: 'Last update timestamp',
        });
        tables.push({
            name: entity.name,
            columns,
            primaryKey: 'id',
            foreignKeys,
            uniqueConstraints: detectUniqueConstraints(entity),
            checkConstraints: detectCheckConstraints(entity),
        });
    }
    return tables;
}
function inferColumnType(fieldName) {
    const lower = fieldName.toLowerCase();
    if (lower.includes('email') || lower.includes('url') || lower.includes('link')) {
        return 'text';
    }
    if (lower.includes('price') || lower.includes('amount') || lower.includes('cost')) {
        return 'decimal(10,2)';
    }
    if (lower.includes('count') || lower.includes('quantity') || lower.includes('order')) {
        return 'integer';
    }
    if (lower.includes('is_') ||
        lower.includes('has_') ||
        lower.includes('active') ||
        lower.includes('enabled')) {
        return 'boolean';
    }
    if (lower.includes('date') || lower.includes('_at')) {
        return 'timestamp';
    }
    if (lower.includes('description') || lower.includes('content') || lower.includes('body')) {
        return 'text';
    }
    if (lower.includes('status')) {
        return 'varchar(50)';
    }
    if (lower.includes('name') || lower.includes('title') || lower.includes('label')) {
        return 'varchar(255)';
    }
    if (lower.includes('json') || lower.includes('metadata') || lower.includes('config')) {
        return 'jsonb';
    }
    return 'varchar(255)';
}
function isRequiredField(fieldName) {
    const required = ['name', 'title', 'status', 'email', 'type'];
    return required.some((r) => fieldName.toLowerCase().includes(r));
}
function detectUniqueConstraints(entity) {
    const uniques = [];
    for (const field of entity.fields) {
        if (field.toLowerCase().includes('email') || field.toLowerCase() === 'slug') {
            uniques.push(field);
        }
    }
    return uniques;
}
function detectCheckConstraints(entity) {
    const checks = [];
    for (const field of entity.fields) {
        if (field.toLowerCase().includes('status')) {
            checks.push(`${field} IN ('active', 'inactive', 'pending', 'archived')`);
        }
        if (field.toLowerCase().includes('price') || field.toLowerCase().includes('amount')) {
            checks.push(`${field} >= 0`);
        }
    }
    return checks;
}
// -- Index generation ---------------------------------------------------------
export function generateIndexes(tables, _engine) {
    const indexes = [];
    for (const table of tables) {
        for (const fk of table.foreignKeys) {
            indexes.push({
                name: `idx_${table.name}_${fk.column}`,
                table: table.name,
                columns: [fk.column],
                type: 'btree',
                unique: false,
                justification: `Foreign key lookup optimization for ${fk.column}`,
            });
        }
        const statusCol = table.columns.find((c) => c.name.includes('status'));
        if (statusCol) {
            indexes.push({
                name: `idx_${table.name}_${statusCol.name}`,
                table: table.name,
                columns: [statusCol.name],
                type: 'btree',
                unique: false,
                justification: 'Status-based filtering is a common query pattern',
            });
        }
        indexes.push({
            name: `idx_${table.name}_created_at`,
            table: table.name,
            columns: ['created_at'],
            type: 'btree',
            unique: false,
            justification: 'Efficient ordering by creation date',
        });
        for (const unique of table.uniqueConstraints) {
            indexes.push({
                name: `idx_${table.name}_${unique}_unique`,
                table: table.name,
                columns: [unique],
                type: 'btree',
                unique: true,
                justification: `Enforce uniqueness on ${unique}`,
            });
        }
    }
    return indexes;
}
// -- RLS policies -------------------------------------------------------------
export function generateRLSPolicies(tables) {
    const policies = [];
    for (const table of tables) {
        policies.push({
            name: `${table.name}_select_authenticated`,
            table: table.name,
            operation: 'SELECT',
            using: "auth.role() = 'authenticated'",
            justification: 'Only authenticated users can read records',
        });
        const ownerCol = table.columns.find((c) => c.name === 'user_id' || c.name === 'owner_id' || c.name === 'created_by');
        if (ownerCol) {
            policies.push({
                name: `${table.name}_insert_owner`,
                table: table.name,
                operation: 'INSERT',
                using: 'true',
                withCheck: `auth.uid() = ${ownerCol.name}`,
                justification: 'Users can only insert records they own',
            }, {
                name: `${table.name}_update_owner`,
                table: table.name,
                operation: 'UPDATE',
                using: `auth.uid() = ${ownerCol.name}`,
                justification: 'Users can only update their own records',
            }, {
                name: `${table.name}_delete_owner`,
                table: table.name,
                operation: 'DELETE',
                using: `auth.uid() = ${ownerCol.name}`,
                justification: 'Users can only delete their own records',
            });
        }
        else {
            policies.push({
                name: `${table.name}_all_authenticated`,
                table: table.name,
                operation: 'ALL',
                using: "auth.role() = 'authenticated'",
                justification: 'All CRUD operations require authentication',
            });
        }
    }
    return policies;
}
//# sourceMappingURL=tables.js.map