/**
 * Work Order Report Importer
 *
 * Imports work order status reports from TS-XX/Reports/ into PostgreSQL.
 * Links work order numbers to existing test records.
 *
 * Usage:
 *   node import-work-orders.js                Full import from all stations
 *   node import-work-orders.js --file <paths> Import specific report files
 *   node import-work-orders.js --station TS-4L Import from one station
 */

const fs = require('fs');
const path = require('path');
const db = require('./db');
const { parseWoReport } = require('../parsers/wo-report');

const TEST_PATH = 'C:\\Shares\\test';

async function run() {
    const args = process.argv.slice(2);
    const stationIdx = args.indexOf('--station');
    const targetStation = stationIdx >= 0 ? args[stationIdx + 1] : null;
    const fileIdx = args.indexOf('--file');
    const specificFiles = fileIdx >= 0 ? args.slice(fileIdx + 1).filter(f => !f.startsWith('--')) : null;

    console.log('========================================');
    console.log('Work Order Report Import');
    console.log('========================================');
    console.log(`Start: ${new Date().toISOString()}`);

    let files = [];

    if (specificFiles && specificFiles.length > 0) {
        files = specificFiles;
    } else {
        try {
            const stationDirs = fs.readdirSync(TEST_PATH, { withFileTypes: true })
                .filter(d => d.isDirectory() && d.name.match(/^TS-/i))
                .filter(d => !targetStation || d.name.toUpperCase() === targetStation.toUpperCase())
                .map(d => d.name);

            for (const station of stationDirs) {
                const reportsDir = path.join(TEST_PATH, station, 'Reports');
                if (!fs.existsSync(reportsDir)) continue;

                const reportFiles = fs.readdirSync(reportsDir)
                    .filter(f => f.toUpperCase().endsWith('.TXT'))
                    .map(f => path.join(reportsDir, f));

                files.push(...reportFiles);
            }
        } catch (err) {
            console.error('Error scanning stations:', err.message);
        }
    }

    console.log(`Found ${files.length} report files to import`);

    let woCount = 0;
    let lineCount = 0;
    let linkedCount = 0;
    let errors = 0;

    const BATCH_SIZE = 500;
    let batch = [];

    for (const filePath of files) {
        try {
            const wo = parseWoReport(filePath);
            if (!wo.wo_number) continue;
            batch.push({ wo, woLines: wo.lines });

            if (batch.length >= BATCH_SIZE) {
                const result = await processBatch(batch);
                woCount += result.woCount;
                lineCount += result.lineCount;
                linkedCount += result.linkedCount;
                batch = [];
                process.stdout.write(`\rProcessed: ${woCount} WOs, ${lineCount} lines`);
            }
        } catch (err) {
            errors++;
        }
    }

    // Flush remaining
    if (batch.length > 0) {
        const result = await processBatch(batch);
        woCount += result.woCount;
        lineCount += result.lineCount;
        linkedCount += result.linkedCount;
    }

    // Bulk update work_order on test_records from serial number pattern
    console.log('\n\nBulk-linking test records by serial number pattern...');
    const bulkResult = await db.execute(`
        UPDATE test_records
        SET work_order = CASE
            WHEN serial_number LIKE '%-%'
            THEN SPLIT_PART(serial_number, '-', 1)
            ELSE serial_number
        END
        WHERE work_order IS NULL
    `);
    console.log(`Bulk-linked ${bulkResult.rowCount} test records`);

    console.log('\n========================================');
    console.log('Import Complete');
    console.log('========================================');
    console.log(`Work orders imported: ${woCount}`);
    console.log(`Test lines imported: ${lineCount}`);
    console.log(`Test records linked: ${linkedCount}`);
    console.log(`Errors: ${errors}`);
    console.log(`End: ${new Date().toISOString()}`);

    await db.close();
}

async function processBatch(items) {
    let woCount = 0;
    let lineCount = 0;
    let linkedCount = 0;

    await db.transaction(async (txClient) => {
        for (const { wo, woLines } of items) {
            await txClient.execute(
                `INSERT INTO work_orders
                (wo_number, wo_date, program, version, lib_version, test_station, source_file)
                VALUES ($1, $2, $3, $4, $5, $6, $7)
                ON CONFLICT (wo_number, test_station)
                DO UPDATE SET wo_date = EXCLUDED.wo_date, program = EXCLUDED.program,
                    version = EXCLUDED.version, lib_version = EXCLUDED.lib_version,
                    source_file = EXCLUDED.source_file`,
                [wo.wo_number, wo.wo_date, wo.program, wo.version, wo.lib_version, wo.station, wo.source_file]
            );
            woCount++;

            for (const line of woLines) {
                const result = await txClient.execute(
                    `INSERT INTO work_order_lines
                    (wo_number, serial_number, status, model_number, ds_filename, test_date, test_time, test_station)
                    VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
                    ON CONFLICT (wo_number, serial_number, test_date, test_time) DO NOTHING`,
                    [wo.wo_number, line.serial_number, line.status, line.model_number,
                     line.ds_filename, line.test_date, line.test_time, wo.station]
                );
                if (result.rowCount > 0) lineCount++;

                // Link to test_records
                const linked = await txClient.execute(
                    'UPDATE test_records SET work_order = $1 WHERE serial_number = $2 AND work_order IS NULL',
                    [wo.wo_number, line.serial_number]
                );
                if (linked.rowCount > 0) linkedCount++;
            }
        }
    });

    return { woCount, lineCount, linkedCount };
}

// Export for use by sync script
async function importReportFiles(filePaths) {
    if (!filePaths || filePaths.length === 0) return 0;

    let imported = 0;

    await db.transaction(async (txClient) => {
        for (const filePath of filePaths) {
            try {
                const wo = parseWoReport(filePath);
                if (!wo.wo_number) continue;

                await txClient.execute(
                    `INSERT INTO work_orders
                    (wo_number, wo_date, program, version, lib_version, test_station, source_file)
                    VALUES ($1, $2, $3, $4, $5, $6, $7)
                    ON CONFLICT (wo_number, test_station)
                    DO UPDATE SET wo_date = EXCLUDED.wo_date, program = EXCLUDED.program,
                        version = EXCLUDED.version, lib_version = EXCLUDED.lib_version,
                        source_file = EXCLUDED.source_file`,
                    [wo.wo_number, wo.wo_date, wo.program, wo.version, wo.lib_version, wo.station, wo.source_file]
                );

                for (const line of wo.lines) {
                    await txClient.execute(
                        `INSERT INTO work_order_lines
                        (wo_number, serial_number, status, model_number, ds_filename, test_date, test_time, test_station)
                        VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
                        ON CONFLICT (wo_number, serial_number, test_date, test_time) DO NOTHING`,
                        [wo.wo_number, line.serial_number, line.status, line.model_number,
                         line.ds_filename, line.test_date, line.test_time, wo.station]
                    );
                    await txClient.execute(
                        'UPDATE test_records SET work_order = $1 WHERE serial_number = $2 AND work_order IS NULL',
                        [wo.wo_number, line.serial_number]
                    );
                }
                imported++;
            } catch (err) {
                // skip bad files
            }
        }
    });

    console.log(`[WO] Imported ${imported} work order report(s)`);
    return imported;
}

if (require.main === module) {
    run().catch(console.error);
}

module.exports = { importReportFiles };
