import { Cloudflare, ErrorFactory, FeatureFlags, Logger, QueryBuilder } from '../../../src/index.js';
function getD1Binding(config) {
    return Cloudflare.getD1Binding(config);
}
function ensureConnected(state) {
    if (!state.connected)
        throw ErrorFactory.createConnectionError('Database not connected');
}
function requireD1(config) {
    const db = getD1Binding(config);
    if (db === null) {
        const isWorkersRuntime = Cloudflare.getWorkersEnv() !== null;
        const message = isWorkersRuntime
            ? 'D1 database binding not found. Ensure your Worker has a D1 binding (for example `DB` or `zintrust_db`) and wrangler d1_databases.binding matches.'
            : 'D1 database binding not found. You are running outside Workers. Use `DB_CONNECTION=d1-remote` with D1_REMOTE_URL/D1_REMOTE_KEY_ID/D1_REMOTE_SECRET, or run in Workers mode (`zin s --wg`).';
        throw ErrorFactory.createConfigError(message);
    }
    return db;
}
async function queryD1(config, sql, parameters) {
    const db = requireD1(config);
    try {
        const stmt = db.prepare(sql);
        const result = await stmt.bind(...parameters).all();
        const rows = result.results ?? [];
        return { rows, rowCount: rows.length };
    }
    catch (error) {
        throw ErrorFactory.createTryCatchError(`D1 query failed: ${sql}`, error);
    }
}
async function queryOneD1(config, sql, parameters) {
    const db = requireD1(config);
    try {
        const stmt = db.prepare(sql);
        const result = await stmt.bind(...parameters).first();
        return result ?? null;
    }
    catch (error) {
        throw ErrorFactory.createTryCatchError(`D1 queryOne failed: ${sql}`, error);
    }
}
async function pingD1(config) {
    const db = requireD1(config);
    try {
        await db.prepare(QueryBuilder.create('').select('1').toSQL()).bind().first();
    }
    catch (error) {
        throw ErrorFactory.createTryCatchError('D1 ping failed', error);
    }
}
async function rawQueryD1(config, sql, parameters) {
    if (!FeatureFlags.isRawQueryEnabled()) {
        throw ErrorFactory.createConfigError('Raw SQL queries are disabled');
    }
    const db = requireD1(config);
    try {
        Logger.warn(`Raw SQL Query executed: ${sql}`, { parameters });
        const stmt = db.prepare(sql);
        const result = await stmt.bind(...(parameters ?? [])).all();
        return result.results ?? [];
    }
    catch (error) {
        throw ErrorFactory.createTryCatchError(`Raw SQL query failed: ${sql}`, error);
    }
}
function createD1Adapter(config) {
    const state = { connected: false, config };
    const adapter = {
        connect: async () => {
            state.connected = true;
            Logger.info('✓ D1 connected');
        },
        disconnect: async () => {
            state.connected = false;
            Logger.info('✓ D1 disconnected');
        },
        query: async (sql, parameters) => {
            ensureConnected(state);
            return queryD1(state.config, sql, parameters);
        },
        queryOne: async (sql, parameters) => {
            ensureConnected(state);
            return queryOneD1(state.config, sql, parameters);
        },
        ping: async () => {
            ensureConnected(state);
            return pingD1(state.config);
        },
        transaction: async (callback) => {
            ensureConnected(state);
            try {
                return await callback(adapter);
            }
            catch (error) {
                throw ErrorFactory.createTryCatchError('Transaction failed', error);
            }
        },
        getType: () => 'd1',
        isConnected: () => state.connected,
        rawQuery: async (sql, parameters) => {
            ensureConnected(state);
            return rawQueryD1(state.config, sql, parameters);
        },
        getPlaceholder: (_index) => '?',
    };
    return adapter;
}
export const D1Adapter = Object.freeze({
    create: (config) => createD1Adapter(config),
});
export default D1Adapter;
/**
 * Package version and build metadata
 * Available at runtime for debugging and health checks
 */
export const _ZINTRUST_DB_D1_VERSION = '0.1.15';
export const _ZINTRUST_DB_D1_BUILD_DATE = '__BUILD_DATE__';
