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

const isRecord = (value: unknown): value is Record<string, unknown> =>
    !!value && typeof value === 'object' && !Array.isArray(value);

const fromNestedMap = (
    payload: Record<string, Partial<Record<BacktestTimeframe, Candle[]>>>
): BacktestRawCandle[] => {
    const rows: BacktestRawCandle[] = [];
    for (const [symbol, byTimeframe] of Object.entries(payload || {})) {
        if (!isRecord(byTimeframe)) continue;
        for (const timeframe of ['1m', '15m', '1h', '4h'] as BacktestTimeframe[]) {
            const candles = byTimeframe[timeframe];
            if (!Array.isArray(candles)) continue;
            for (const candle of candles) {
                rows.push({
                    symbol,
                    timeframe,
                    timestamp: candle.timestamp,
                    open: candle.open,
                    high: candle.high,
                    low: candle.low,
                    close: candle.close,
                    volume: candle.volume
                });
            }
        }
    }
    return rows;
};

export const loadDatasetFromJsonPayload = (payload: unknown): HistoricalDataset => {
    if (!isRecord(payload) || !('candles' in payload)) {
        throw new Error('JSON payload must include a "candles" field.');
    }
    const candlesPayload = (payload as { candles: unknown }).candles;
    if (Array.isArray(candlesPayload)) {
        return buildDatasetFromRows(normalizeRawCandles(candlesPayload as BacktestRawCandle[]));
    }
    if (isRecord(candlesPayload)) {
        return buildDatasetFromRows(normalizeRawCandles(fromNestedMap(candlesPayload as Record<string, Partial<Record<BacktestTimeframe, Candle[]>>>)));
    }
    throw new Error('Unsupported JSON candles payload shape.');
};
