import express from 'express';
import cors from 'cors';
import {
    resetDatabase,
    seedDatabase,
    seedDatabaseLite,
    seedDatabaseNoLocations
} from './index.js';
import { pool } from './db.js';

// --- Console Interception for Streaming ---
const originalLog = console.log;
const originalError = console.error;
let streamCallback = null;

console.log = (...args) => {
    originalLog.apply(console, args);
    if (streamCallback) {
        const msg = args.map(arg =>
            typeof arg === 'object' ? JSON.stringify(arg) : String(arg)
        ).join(' ');
        streamCallback('INFO', msg);
    }
};

console.error = (...args) => {
    originalError.apply(console, args);
    if (streamCallback) {
        const msg = args.map(arg =>
            typeof arg === 'object' ? JSON.stringify(arg) : String(arg)
        ).join(' ');
        streamCallback('ERROR', msg);
    }
};
// ------------------------------------------

const app = express();
const port = process.env.PORT || 8080;

app.use(cors());
app.use(express.json());

// Root Handler
app.get('/', (req, res) => {
    res.json({
        message: "🌱 GoHorseJobs Seeder API is running! (Node.js Mode)",
        version: "1.0.0",
        ip: req.ip,
        endpoints: {
            health: "/health",
            seed: "POST /seed",
            reset: "POST /reset",
            stream: "GET /seed/stream"
        }
    });
});

// Middleware to log requests
app.use((req, res, next) => {
    console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
    next();
});

// Health check
app.get('/health', async (req, res) => {
    try {
        const result = await pool.query('SELECT 1');
        res.json({ status: 'ok', database: 'connected', version: '1.0.0' });
    } catch (error) {
        console.error('Health check failed:', error);
        res.status(500).json({ status: 'error', database: 'disconnected', error: error.message });
    }
});

// Seed endpoint
// Options: type = 'full' | 'lite' | 'no-locations'
// Seed endpoint with SSE
app.get('/seed/stream', async (req, res) => {
    if (isSeeding) {
        // If already seeding, just tell them. 
        // Ideally we would share the same stream but for simplicity we block new connections or just tell them to wait.
        // Actually, let's allow connecting to the *log stream* even if unrelated? No, let's keep it simple.
        // We will just expose an endpoint that TRIGGERS the seed AND streams the output.
    }

    // Set headers for SSE
    res.setHeader('Content-Type', 'text/event-stream');
    res.setHeader('Cache-Control', 'no-cache');
    res.setHeader('Connection', 'keep-alive');
    res.flushHeaders();

    const sendLog = (msg) => {
        // Handle "INFO" or "ERROR" prefix if passed from interceptor, or just raw string
        res.write(`data: ${JSON.stringify({ message: msg, timestamp: new Date().toISOString() })}\n\n`);
    };

    if (isSeeding) {
        sendLog('⚠️ Seeding already in progress...');
        // allow them to watch? For now blocking new triggers.
        return res.end();
    }

    const type = req.query.type || 'full';
    isSeeding = true;

    // Hook up the stream callback
    streamCallback = (level, text) => {
        const icon = level === 'ERROR' ? '❌' : 'ℹ️';
        sendLog(`${icon} ${text}`);
    };

    // sendLog(`🚀 Starting manual seed (${type})...`); // This will be logged by console.log inside functions anyway

    try {
        if (type === 'lite') {
            await seedDatabaseLite();
        } else if (type === 'no-locations') {
            await seedDatabaseNoLocations();
        } else {
            await seedDatabase();
        }
        res.write(`data: ${JSON.stringify({ type: 'done' })}\n\n`);
    } catch (error) {
        console.error('Manual seed fatal error:', error); // Captured by interceptor
        res.write(`data: ${JSON.stringify({ type: 'error', error: error.message })}\n\n`);
    } finally {
        isSeeding = false;
        streamCallback = null; // Detach
        res.end();
    }
});

// Keep legacy POST for compatibility if needed, using the new shared function logic
app.post('/seed', async (req, res) => {
    // ... keep existing logic but warn it's deprecated? 
    // Actually let's just keep it simple.
    if (isSeeding) return res.status(409).json({ error: 'Seeding in progress' });
    isSeeding = true;
    res.json({ message: 'Seeding started' });
    try {
        await seedDatabase();
    } catch (e) { console.error(e); }
    finally { isSeeding = false; }
});

// Reset endpoint
app.post('/reset', async (req, res) => {
    if (isSeeding) {
        return res.status(409).json({ error: 'Seeding/Reset in progress' });
    }

    const password = req.body?.password;
    if (process.env.SEED_PASSWORD && password !== process.env.SEED_PASSWORD) {
        return res.status(401).json({ error: 'Unauthorized' });
    }

    isSeeding = true;
    res.json({ message: 'Reset started' });

    try {
        console.log('🚀 Starting manual reset...');
        await resetDatabase();
        console.log('✅ Manual reset completed');
    } catch (error) {
        console.error('❌ Manual reset failed:', error);
    } finally {
        isSeeding = false;
    }
});

let isSeeding = false;

app.listen(port, () => {
    console.log(`🌱 GoHorseJobs Seeder API listening on port ${port}`);
    console.log(`   Health check: http://localhost:${port}/health`);
});
