/**
 * API Routes for Test Data Database
 * FIXED VERSION - Compatible with readonly mode
 */

const express = require('express');
const path = require('path');
const Database = require('better-sqlite3');
const { generateDatasheet } = require('../templates/datasheet');

const router = express.Router();

// Database connection
const DB_PATH = path.join(__dirname, '..', 'database', 'testdata.db');

// FIXED: Readonly-compatible optimizations
function getDb() {
    const db = new Database(DB_PATH, { readonly: true, timeout: 10000 });

    // Performance optimizations compatible with readonly mode
    db.pragma('cache_size = -64000');       // 64MB cache (negative = KB)
    db.pragma('mmap_size = 268435456');     // 256MB memory-mapped I/O
    db.pragma('temp_store = MEMORY');       // Temporary tables in memory
    db.pragma('query_only = ON');           // Enforce read-only mode

    return db;
}

/**
 * GET /api/search
 * Search test records
 * Query params: serial, model, from, to, result, q, station, logtype, limit, offset
 */
router.get('/search', (req, res) => {
    try {
        const db = getDb();
        const { serial, model, from, to, result, q, station, logtype, limit = 100, offset = 0 } = req.query;

        let sql = 'SELECT * FROM test_records WHERE 1=1';
        const params = [];

        if (serial) {
            sql += ' AND serial_number LIKE ?';
            params.push(serial.includes('%') ? serial : `%${serial}%`);
        }

        if (model) {
            sql += ' AND model_number LIKE ?';
            params.push(model.includes('%') ? model : `%${model}%`);
        }

        if (from) {
            sql += ' AND test_date >= ?';
            params.push(from);
        }

        if (to) {
            sql += ' AND test_date <= ?';
            params.push(to);
        }

        if (result) {
            sql += ' AND overall_result = ?';
            params.push(result.toUpperCase());
        }

        if (station) {
            sql += ' AND test_station = ?';
            params.push(station);
        }

        if (logtype) {
            sql += ' AND log_type = ?';
            params.push(logtype);
        }

        if (q) {
            // Full-text search - rebuild query with FTS
            sql = `SELECT test_records.* FROM test_records
                   JOIN test_records_fts ON test_records.id = test_records_fts.rowid
                   WHERE test_records_fts MATCH ?`;
            params.length = 0;
            params.push(q);

            if (serial) {
                sql += ' AND serial_number LIKE ?';
                params.push(serial.includes('%') ? serial : `%${serial}%`);
            }
            if (model) {
                sql += ' AND model_number LIKE ?';
                params.push(model.includes('%') ? model : `%${model}%`);
            }
            if (station) {
                sql += ' AND test_station = ?';
                params.push(station);
            }
            if (logtype) {
                sql += ' AND log_type = ?';
                params.push(logtype);
            }
            if (result) {
                sql += ' AND overall_result = ?';
                params.push(result.toUpperCase());
            }
            if (from) {
                sql += ' AND test_date >= ?';
                params.push(from);
            }
            if (to) {
                sql += ' AND test_date <= ?';
                params.push(to);
            }
        }

        sql += ' ORDER BY test_date DESC, serial_number';
        sql += ` LIMIT ? OFFSET ?`;
        params.push(parseInt(limit), parseInt(offset));

        const records = db.prepare(sql).all(...params);

        // Get total count
        let countSql = sql.replace(/SELECT .* FROM/, 'SELECT COUNT(*) as count FROM')
                         .replace(/ORDER BY.*$/, '');
        countSql = countSql.replace(/LIMIT \? OFFSET \?/, '');

        const countParams = params.slice(0, -2);
        const total = db.prepare(countSql).get(...countParams);

        db.close();

        res.json({
            records,
            total: total?.count || records.length,
            limit: parseInt(limit),
            offset: parseInt(offset)
        });
    } catch (err) {
        res.status(500).json({ error: err.message });
    }
});

/**
 * GET /api/record/:id
 * Get single record by ID
 */
router.get('/record/:id', (req, res) => {
    try {
        const db = getDb();
        const record = db.prepare('SELECT * FROM test_records WHERE id = ?').get(req.params.id);
        db.close();

        if (!record) {
            return res.status(404).json({ error: 'Record not found' });
        }

        res.json(record);
    } catch (err) {
        res.status(500).json({ error: err.message });
    }
});

/**
 * GET /api/datasheet/:id
 * Generate datasheet for a record
 * Query params: format (html, txt)
 */
router.get('/datasheet/:id', (req, res) => {
    try {
        const db = getDb();
        const record = db.prepare('SELECT * FROM test_records WHERE id = ?').get(req.params.id);
        db.close();

        if (!record) {
            return res.status(404).json({ error: 'Record not found' });
        }

        const format = req.query.format || 'html';
        const datasheet = generateDatasheet(record, format);

        if (format === 'html') {
            res.type('html').send(datasheet);
        } else {
            res.type('text/plain').send(datasheet);
        }
    } catch (err) {
        res.status(500).json({ error: err.message });
    }
});

/**
 * GET /api/stats
 * Get database statistics
 */
router.get('/stats', (req, res) => {
    try {
        const db = getDb();

        const stats = {
            total_records: db.prepare('SELECT COUNT(*) as count FROM test_records').get().count,
            by_log_type: db.prepare(`
                SELECT log_type, COUNT(*) as count
                FROM test_records
                GROUP BY log_type
                ORDER BY count DESC
            `).all(),
            by_result: db.prepare(`
                SELECT overall_result, COUNT(*) as count
                FROM test_records
                GROUP BY overall_result
            `).all(),
            by_station: db.prepare(`
                SELECT test_station, COUNT(*) as count
                FROM test_records
                WHERE test_station IS NOT NULL AND test_station != ''
                GROUP BY test_station
                ORDER BY test_station
            `).all(),
            date_range: db.prepare(`
                SELECT MIN(test_date) as oldest, MAX(test_date) as newest
                FROM test_records
            `).get(),
            recent_serials: db.prepare(`
                SELECT DISTINCT serial_number, model_number, test_date
                FROM test_records
                ORDER BY test_date DESC
                LIMIT 10
            `).all()
        };

        db.close();
        res.json(stats);
    } catch (err) {
        res.status(500).json({ error: err.message });
    }
});

/**
 * GET /api/filters
 * Get available filter options (test stations, log types, models)
 */
router.get('/filters', (req, res) => {
    try {
        const db = getDb();

        const filters = {
            stations: db.prepare(`
                SELECT DISTINCT test_station
                FROM test_records
                WHERE test_station IS NOT NULL AND test_station != ''
                ORDER BY test_station
            `).all().map(r => r.test_station),
            log_types: db.prepare(`
                SELECT DISTINCT log_type
                FROM test_records
                ORDER BY log_type
            `).all().map(r => r.log_type),
            models: db.prepare(`
                SELECT DISTINCT model_number, COUNT(*) as count
                FROM test_records
                GROUP BY model_number
                ORDER BY count DESC
                LIMIT 500
            `).all()
        };

        db.close();
        res.json(filters);
    } catch (err) {
        res.status(500).json({ error: err.message });
    }
});

/**
 * GET /api/export
 * Export search results as CSV
 */
router.get('/export', (req, res) => {
    try {
        const db = getDb();
        const { serial, model, from, to, result, station, logtype } = req.query;

        let sql = 'SELECT * FROM test_records WHERE 1=1';
        const params = [];

        if (serial) {
            sql += ' AND serial_number LIKE ?';
            params.push(serial.includes('%') ? serial : `%${serial}%`);
        }

        if (model) {
            sql += ' AND model_number LIKE ?';
            params.push(model.includes('%') ? model : `%${model}%`);
        }

        if (from) {
            sql += ' AND test_date >= ?';
            params.push(from);
        }

        if (to) {
            sql += ' AND test_date <= ?';
            params.push(to);
        }

        if (result) {
            sql += ' AND overall_result = ?';
            params.push(result.toUpperCase());
        }

        if (station) {
            sql += ' AND test_station = ?';
            params.push(station);
        }

        if (logtype) {
            sql += ' AND log_type = ?';
            params.push(logtype);
        }

        sql += ' ORDER BY test_date DESC, serial_number LIMIT 10000';

        const records = db.prepare(sql).all(...params);
        db.close();

        // Generate CSV
        const headers = ['id', 'log_type', 'model_number', 'serial_number', 'test_date', 'test_station', 'overall_result', 'source_file'];
        let csv = headers.join(',') + '\n';

        for (const record of records) {
            const row = headers.map(h => {
                const val = record[h] || '';
                return `"${String(val).replace(/"/g, '""')}"`;
            });
            csv += row.join(',') + '\n';
        }

        res.setHeader('Content-Type', 'text/csv');
        res.setHeader('Content-Disposition', 'attachment; filename=test_records.csv');
        res.send(csv);
    } catch (err) {
        res.status(500).json({ error: err.message });
    }
});

module.exports = router;
