import type { BacktestRawCandle, HistoricalDataset } from '../types.js';
import { buildDatasetFromRows, normalizeRawCandles } from './normalize.js';

const EXPECTED_COLUMNS = ['symbol', 'timeframe', 'timestamp', 'open', 'high', 'low', 'close', 'volume'];

const parseCsvLine = (line: string): string[] => {
    const out: string[] = [];
    let current = '';
    let inQuotes = false;
    for (let i = 0; i < line.length; i++) {
        const char = line[i];
        if (char === '"' && line[i + 1] === '"') {
            current += '"';
            i += 1;
            continue;
        }
        if (char === '"') {
            inQuotes = !inQuotes;
            continue;
        }
        if (char === ',' && !inQuotes) {
            out.push(current.trim());
            current = '';
            continue;
        }
        current += char;
    }
    out.push(current.trim());
    return out;
};

export const loadDatasetFromCsv = (payload: string): HistoricalDataset => {
    const normalizedPayload = String(payload || '').trim();
    if (!normalizedPayload) {
        throw new Error('CSV payload is empty.');
    }

    const lines = normalizedPayload
        .split(/\r?\n/)
        .map((line) => line.trim())
        .filter(Boolean);
    if (lines.length < 2) {
        throw new Error('CSV payload must include a header and at least one data row.');
    }

    const header = parseCsvLine(lines[0]).map((value) => value.toLowerCase());
    for (const expected of EXPECTED_COLUMNS) {
        if (!header.includes(expected)) {
            throw new Error(`CSV header missing required column "${expected}".`);
        }
    }

    const idx = (name: string): number => header.indexOf(name);
    const rows: BacktestRawCandle[] = [];
    for (let i = 1; i < lines.length; i++) {
        const cols = parseCsvLine(lines[i]);
        if (cols.length !== header.length) {
            throw new Error(`CSV row ${i + 1} has ${cols.length} columns; expected ${header.length}.`);
        }
        rows.push({
            symbol: cols[idx('symbol')],
            timeframe: cols[idx('timeframe')],
            timestamp: cols[idx('timestamp')],
            open: cols[idx('open')],
            high: cols[idx('high')],
            low: cols[idx('low')],
            close: cols[idx('close')],
            volume: cols[idx('volume')]
        });
    }

    return buildDatasetFromRows(normalizeRawCandles(rows));
};

