import { config } from '../../config/index.js';
import type { BacktestWarmupReport } from '../types.js';

const clampPositiveInt = (value: unknown, fallback: number): number => {
    const parsed = Number(value);
    if (!Number.isFinite(parsed) || parsed <= 0) return fallback;
    return Math.max(1, Math.floor(parsed));
};

const getRuleParams = (strategyConfig: any, ruleId: string): Record<string, any> => {
    const rules = Array.isArray(strategyConfig?.rules) ? strategyConfig.rules : [];
    const found = rules.find((rule: any) => String(rule?.ruleId || '').trim() === ruleId);
    return (found?.params && typeof found.params === 'object') ? found.params : {};
};

const isRuleEnabled = (strategyConfig: any, ruleId: string): boolean => {
    const rules = Array.isArray(strategyConfig?.rules) ? strategyConfig.rules : [];
    const found = rules.find((rule: any) => String(rule?.ruleId || '').trim() === ruleId);
    if (!found) return true;
    return found.enabled !== false;
};

export interface WarmupRequirements {
    '15m': number;
    '1h': number;
    '4h': number;
}

export const computeWarmupRequirements = (strategyConfig: any): WarmupRequirements => {
    const requirements: WarmupRequirements = {
        '15m': 2,
        '1h': 2,
        '4h': 2
    };

    if (isRuleEnabled(strategyConfig, 'TrendBiasRule')) {
        const trendParams = getRuleParams(strategyConfig, 'TrendBiasRule');
        const slowPeriod = clampPositiveInt(
            trendParams?.slowPeriod,
            Number(config.PRO_STRATEGY.PARAMETERS.TREND_EMA_SLOW || 200)
        );
        requirements['4h'] = Math.max(requirements['4h'], slowPeriod + 1);
    }

    if (isRuleEnabled(strategyConfig, 'MomentumRule')) {
        const momentumParams = getRuleParams(strategyConfig, 'MomentumRule');
        const timeframeRaw = String(momentumParams?.timeframe || config.PRO_STRATEGY.PARAMETERS.MOMENTUM_TIMEFRAME || '15m').trim().toLowerCase();
        const momentumTf: '15m' | '1h' = timeframeRaw === '1h' ? '1h' : '15m';
        const rsiPeriod = clampPositiveInt(momentumParams?.rsiPeriod, Number(config.PRO_STRATEGY.PARAMETERS.RSI_PERIOD || 14));
        requirements[momentumTf] = Math.max(requirements[momentumTf], rsiPeriod + 1);
    }

    if (isRuleEnabled(strategyConfig, 'ZoneRule')) {
        const zoneParams = getRuleParams(strategyConfig, 'ZoneRule');
        const executionTfRaw = String(zoneParams?.timeframe || config.PRO_STRATEGY.PARAMETERS.EXECUTION_TIMEFRAME || '15m').trim().toLowerCase();
        const zoneTf: '15m' | '1h' = executionTfRaw === '1h' ? '1h' : '15m';
        const zoneEmaPeriod = clampPositiveInt(zoneParams?.emaPeriod, Number(config.PRO_STRATEGY.PARAMETERS.ZONE_EMA_PERIOD || 20));
        requirements[zoneTf] = Math.max(requirements[zoneTf], zoneEmaPeriod + 1);
    }

    if (isRuleEnabled(strategyConfig, 'EntryTriggerRule')) {
        const entryParams = getRuleParams(strategyConfig, 'EntryTriggerRule');
        const executionTfRaw = String(entryParams?.timeframe || config.PRO_STRATEGY.PARAMETERS.EXECUTION_TIMEFRAME || '15m').trim().toLowerCase();
        const entryTf: '15m' | '1h' = executionTfRaw === '1h' ? '1h' : '15m';
        requirements[entryTf] = Math.max(requirements[entryTf], 3);
    }

    if (isRuleEnabled(strategyConfig, 'RiskManagementRule')) {
        const riskParams = getRuleParams(strategyConfig, 'RiskManagementRule');
        const atrPeriod = clampPositiveInt(riskParams?.atrPeriod, Number(config.PRO_STRATEGY.PARAMETERS.ATR_PERIOD || 14));
        requirements['1h'] = Math.max(requirements['1h'], Math.max(20, atrPeriod + 1));
    }

    return requirements;
};

export const createWarmupReport = (
    startTimestamp: number,
    endTimestamp: number,
    candlesRequired: WarmupRequirements,
    signalsIgnored: number
): BacktestWarmupReport => ({
    startTimestamp,
    endTimestamp,
    candlesRequired,
    signalsIgnored
});

