import type { APIRoute } from 'astro';
import { pool } from '@/lib/db';
import { sanitizeSQL, sanitizeSQLForMaintenance } from '@/lib/db/sanitizer';
import { vacuumAnalyze, killLocks } from '@/lib/db/mechanic';
import { queues } from '@/lib/queue/config';

/**
 * Enhanced SQL Endpoint - The Ultimate God Mode Feature
 * 
 * Features:
 * 1. Multi-statement transactions (auto-rollback on failure)
 * 2. SQL sanitization (blocks dangerous commands)
 * 3. Mechanic integration (auto-cleanup after large ops)
 * 4. Queue injection (push results to BullMQ)
 */

function validateGodToken(request: Request): boolean {
    const token = request.headers.get('X-God-Token') ||
        request.headers.get('Authorization')?.replace('Bearer ', '') ||
        new URL(request.url).searchParams.get('token');

    const godToken = process.env.GOD_MODE_TOKEN || import.meta.env.GOD_MODE_TOKEN;
    if (!godToken) return true;
    return token === godToken;
}

export const POST: APIRoute = async ({ request }) => {
    if (!validateGodToken(request)) {
        return new Response(JSON.stringify({ error: 'Unauthorized' }), {
            status: 401,
            headers: { 'Content-Type': 'application/json' }
        });
    }

    try {
        const body = await request.json();
        const {
            query,
            run_mechanic,      // 'vacuum' | 'kill-locks'
            push_to_queue,     // 'publish_job' | 'generate_article'
            transaction = true // Auto-wrap in transaction if multiple statements
        } = body;

        if (!query) {
            return new Response(JSON.stringify({ error: 'Missing query' }), {
                status: 400,
                headers: { 'Content-Type': 'application/json' }
            });
        }

        // Step 1: SQL Sanitization
        const sanitizationMode = run_mechanic ? 'maintenance' : 'normal';
        const sanitizationResult = sanitizationMode === 'maintenance'
            ? sanitizeSQLForMaintenance(query)
            : sanitizeSQL(query);

        if (!sanitizationResult.safe) {
            return new Response(JSON.stringify({
                error: 'SQL blocked by safety check',
                reason: sanitizationResult.blocked,
                tip: 'Use run_mechanic flag for maintenance operations'
            }), {
                status: 403,
                headers: { 'Content-Type': 'application/json' }
            });
        }

        // Step 2: Split into statements for transaction handling
        const statements = query.split(';').map((s: string) => s.trim()).filter(Boolean);
        const isMultiStatement = statements.length > 1;

        // Step 3: Execute Query
        const client = await pool.connect();
        let result;
        let rowsAffected = 0;

        try {
            if (isMultiStatement && transaction) {
                // Multi-statement transaction
                await client.query('BEGIN');
                console.log(`🔱 [SQL] Starting transaction with ${statements.length} statements`);

                const results = [];
                for (const stmt of statements) {
                    const r = await client.query(stmt);
                    results.push(r);
                    rowsAffected += r.rowCount || 0;
                }

                await client.query('COMMIT');
                console.log(`✅ [SQL] Transaction committed - ${rowsAffected} rows affected`);

                result = results[results.length - 1]; // Return last result

            } else {
                // Single statement
                result = await client.query(query);
                rowsAffected = result.rowCount || 0;
            }

        } catch (error: any) {
            if (isMultiStatement && transaction) {
                await client.query('ROLLBACK');
                console.error(`❌ [SQL] Transaction rolled back: ${error.message}`);
            }
            throw error;

        } finally {
            client.release();
        }

        // Step 4: Mechanic Integration
        let mechanicResult;
        if (run_mechanic) {
            console.log(`🔧 [Mechanic] Running ${run_mechanic}...`);

            if (run_mechanic === 'vacuum') {
                await vacuumAnalyze();
                mechanicResult = { action: 'vacuum', status: 'completed' };
            } else if (run_mechanic === 'kill-locks') {
                const killed = await killLocks();
                mechanicResult = { action: 'kill-locks', killed };
            }
        }

        // Step 5: Queue Injection
        let queueResult;
        if (push_to_queue && result.rows && result.rows.length > 0) {
            console.log(`📋 [Queue] Pushing ${result.rows.length} rows to ${push_to_queue}`);

            const jobs = result.rows.map((row: any, index: number) => ({
                name: `${push_to_queue}-${index}`,
                data: row
            }));

            // Use addBulk for efficiency
            const queue = queues.generation; // Default queue
            await queue.addBulk(jobs);

            queueResult = {
                queue: push_to_queue,
                jobsAdded: jobs.length
            };
        }

        // Step 6: Build Response
        const response: any = {
            success: true,
            rowCount: result.rowCount,
            rows: result.rows,
            command: result.command,
            timestamp: new Date().toISOString()
        };

        if (sanitizationResult.warnings.length > 0) {
            response.warnings = sanitizationResult.warnings;
        }

        if (isMultiStatement) {
            response.transaction = {
                statements: statements.length,
                committed: true,
                rowsAffected
            };
        }

        if (mechanicResult) {
            response.mechanic = mechanicResult;
        }

        if (queueResult) {
            response.queue = queueResult;
        }

        return new Response(JSON.stringify(response), {
            status: 200,
            headers: { 'Content-Type': 'application/json' }
        });

    } catch (error: any) {
        return new Response(JSON.stringify({
            error: error.message,
            code: error.code,
            detail: error.detail,
            hint: error.hint
        }), {
            status: 500,
            headers: { 'Content-Type': 'application/json' }
        });
    }
};

// GET for documentation
export const GET: APIRoute = async ({ request }) => {
    if (!validateGodToken(request)) {
        return new Response(JSON.stringify({ error: 'Unauthorized' }), {
            status: 401,
            headers: { 'Content-Type': 'application/json' }
        });
    }

    return new Response(JSON.stringify({
        endpoint: 'POST /api/god/sql',
        description: 'Execute raw SQL with enhanced features',
        features: {
            '1_transactions': 'Auto-wrap multiple statements in BEGIN/COMMIT',
            '2_sanitization': 'Blocks dangerous commands (DROP DATABASE, etc)',
            '3_mechanic': 'Auto-cleanup with run_mechanic flag',
            '4_queue_injection': 'Push results to BullMQ with push_to_queue flag'
        },
        usage: {
            basic: {
                query: 'SELECT * FROM sites LIMIT 10'
            },
            transaction: {
                query: 'INSERT INTO sites (domain, name) VALUES (\'example.com\', \'Example\'); UPDATE sites SET status=\'active\';',
                transaction: true
            },
            with_vacuum: {
                query: 'DELETE FROM posts WHERE status=\'draft\'',
                run_mechanic: 'vacuum'
            },
            queue_injection: {
                query: 'SELECT id, url FROM posts WHERE status=\'draft\'',
                push_to_queue: 'publish_job'
            }
        },
        safety: {
            blocked: ['DROP DATABASE', 'ALTER USER', 'DELETE without WHERE'],
            warnings: ['TRUNCATE', 'DROP TABLE', 'UPDATE without WHERE']
        }
    }, null, 2), {
        status: 200,
        headers: { 'Content-Type': 'application/json' }
    });
};
