// Self-contained Stochastic Oscillator indicator
// Includes math, metadata, signal calculation, and base class

// Signal constants (defined in each indicator file)
const SIGNAL_TYPES = {
    BUY: 'buy',
    SELL: 'sell',
    HOLD: 'hold'
};

const SIGNAL_COLORS = {
    buy: '#26a69a',
    hold: '#787b86',
    sell: '#ef5350'
};

// Base class (inline replacement for BaseIndicator)
class BaseIndicator {
    constructor(config) {
        this.id = config.id;
        this.type = config.type;
        this.name = config.name;
        this.params = config.params || {};
        this.timeframe = config.timeframe || '1m';
        this.series = [];
        this.visible = config.visible !== false;
        this.cachedResults = null;
        this.cachedMeta = null;
        this.lastSignalTimestamp = null;
        this.lastSignalType = null;
    }
}

// Signal calculation for Stochastic
function calculateStochSignal(indicator, lastCandle, prevCandle, values, prevValues) {
    const k = values?.k;
    const d = values?.d;
    const prevK = prevValues?.k;
    const prevD = prevValues?.d;
    const overbought = indicator.params?.overbought || 80;
    const oversold = indicator.params?.oversold || 20;
    
    if (k === undefined || d === undefined || prevK === undefined || prevD === undefined) {
        return null;
    }

    // BUY: %K crosses UP through %D while both are oversold
    if (prevK <= prevD && k > d && k < oversold) {
        return {
            type: SIGNAL_TYPES.BUY,
            strength: 80,
            value: k,
            reasoning: `Stochastic %K crossed UP through %D in oversold zone`
        };
    } 
    // SELL: %K crosses DOWN through %D while both are overbought
    else if (prevK >= prevD && k < d && k > overbought) {
        return {
            type: SIGNAL_TYPES.SELL,
            strength: 80,
            value: k,
            reasoning: `Stochastic %K crossed DOWN through %D in overbought zone`
        };
    }

    return null;
}

// Stochastic Oscillator Indicator class
export class StochasticIndicator extends BaseIndicator {
    constructor(config) {
        super(config);
        this.lastSignalTimestamp = null;
        this.lastSignalType = null;
    }

    calculate(candles) {
        const kPeriod = this.params.kPeriod || 14;
        const dPeriod = this.params.dPeriod || 3;
        const results = new Array(candles.length).fill(null);
        
        const kValues = new Array(candles.length).fill(null);
        
        for (let i = kPeriod - 1; i < candles.length; i++) {
            let lowest = Infinity;
            let highest = -Infinity;
            for (let j = 0; j < kPeriod; j++) {
                lowest = Math.min(lowest, candles[i-j].low);
                highest = Math.max(highest, candles[i-j].high);
            }
            const diff = highest - lowest;
            kValues[i] = diff === 0 ? 50 : ((candles[i].close - lowest) / diff) * 100;
        }
        
        for (let i = kPeriod + dPeriod - 2; i < candles.length; i++) {
            let sum = 0;
            for (let j = 0; j < dPeriod; j++) sum += kValues[i-j];
            results[i] = { k: kValues[i], d: sum / dPeriod };
        }
        
        return results;
    }
    
    getMetadata() {
        return {
            name: 'Stochastic',
            description: 'Stochastic Oscillator - compares close to high-low range',
            inputs: [
                { 
                    name: 'kPeriod', 
                    label: '%K Period', 
                    type: 'number', 
                    default: 14, 
                    min: 1, 
                    max: 100,
                    description: 'Lookback period for %K calculation'
                },
                { 
                    name: 'dPeriod', 
                    label: '%D Period', 
                    type: 'number', 
                    default: 3, 
                    min: 1, 
                    max: 20,
                    description: 'Smoothing period for %D (SMA of %K)'
                }
            ],
            plots: [
                { id: 'k', color: '#3f51b5', title: '%K', style: 'solid', width: 1 },
                { id: 'd', color: '#ff9800', title: '%D', style: 'solid', width: 1 }
            ],
            displayMode: 'pane',
            paneMin: 0,
            paneMax: 100
        };
    }
}

export { calculateStochSignal };