/**
 * Technical Indicators Controller
 * Handles indicator calculation endpoints
 */

import type { Request, Response, NextFunction } from 'express';
import { indicatorsService } from '../services/indicators.service';
import type { Interval } from '../services/binance.service';

// ============================================================================
// Moving Averages
// ============================================================================

export async function getSMA(req: Request, res: Response, next: NextFunction): Promise<void> {
  try {
    const { symbol } = req.params;
    const interval = (req.query.interval as Interval) || '1h';
    const period = parseInt(req.query.period as string, 10) || 20;
    const limit = parseInt(req.query.limit as string, 10) || 100;

    const data = await indicatorsService.getSMA({ symbol, interval, period, limit });
    res.json({ success: true, data });
  } catch (error) {
    next(error);
  }
}

export async function getEMA(req: Request, res: Response, next: NextFunction): Promise<void> {
  try {
    const { symbol } = req.params;
    const interval = (req.query.interval as Interval) || '1h';
    const period = parseInt(req.query.period as string, 10) || 20;
    const limit = parseInt(req.query.limit as string, 10) || 100;

    const data = await indicatorsService.getEMA({ symbol, interval, period, limit });
    res.json({ success: true, data });
  } catch (error) {
    next(error);
  }
}

// ============================================================================
// Oscillators
// ============================================================================

export async function getRSI(req: Request, res: Response, next: NextFunction): Promise<void> {
  try {
    const { symbol } = req.params;
    const interval = (req.query.interval as Interval) || '1h';
    const period = parseInt(req.query.period as string, 10) || 14;
    const limit = parseInt(req.query.limit as string, 10) || 100;

    const data = await indicatorsService.getRSI({ symbol, interval, period, limit });
    res.json({ success: true, data });
  } catch (error) {
    next(error);
  }
}

export async function getMACD(req: Request, res: Response, next: NextFunction): Promise<void> {
  try {
    const { symbol } = req.params;
    const interval = (req.query.interval as Interval) || '1h';
    const fastPeriod = parseInt(req.query.fastPeriod as string, 10) || 12;
    const slowPeriod = parseInt(req.query.slowPeriod as string, 10) || 26;
    const signalPeriod = parseInt(req.query.signalPeriod as string, 10) || 9;
    const limit = parseInt(req.query.limit as string, 10) || 100;

    const data = await indicatorsService.getMACD({
      symbol,
      interval,
      fastPeriod,
      slowPeriod,
      signalPeriod,
      limit,
    });
    res.json({ success: true, data });
  } catch (error) {
    next(error);
  }
}

export async function getStochastic(req: Request, res: Response, next: NextFunction): Promise<void> {
  try {
    const { symbol } = req.params;
    const interval = (req.query.interval as Interval) || '1h';
    const kPeriod = parseInt(req.query.kPeriod as string, 10) || 14;
    const dPeriod = parseInt(req.query.dPeriod as string, 10) || 3;
    const smoothK = parseInt(req.query.smoothK as string, 10) || 3;
    const limit = parseInt(req.query.limit as string, 10) || 100;

    const data = await indicatorsService.getStochastic({
      symbol,
      interval,
      kPeriod,
      dPeriod,
      smoothK,
      limit,
    });
    res.json({ success: true, data });
  } catch (error) {
    next(error);
  }
}

// ============================================================================
// Volatility Indicators
// ============================================================================

export async function getBollingerBands(req: Request, res: Response, next: NextFunction): Promise<void> {
  try {
    const { symbol } = req.params;
    const interval = (req.query.interval as Interval) || '1h';
    const period = parseInt(req.query.period as string, 10) || 20;
    const stdDev = parseFloat(req.query.stdDev as string) || 2;
    const limit = parseInt(req.query.limit as string, 10) || 100;

    const data = await indicatorsService.getBollingerBands({
      symbol,
      interval,
      period,
      stdDev,
      limit,
    });
    res.json({ success: true, data });
  } catch (error) {
    next(error);
  }
}

export async function getATR(req: Request, res: Response, next: NextFunction): Promise<void> {
  try {
    const { symbol } = req.params;
    const interval = (req.query.interval as Interval) || '1h';
    const period = parseInt(req.query.period as string, 10) || 14;
    const limit = parseInt(req.query.limit as string, 10) || 100;

    const data = await indicatorsService.getATR({ symbol, interval, period, limit });
    res.json({ success: true, data });
  } catch (error) {
    next(error);
  }
}

// ============================================================================
// Volume Indicators
// ============================================================================

export async function getVWAP(req: Request, res: Response, next: NextFunction): Promise<void> {
  try {
    const { symbol } = req.params;
    const interval = (req.query.interval as Interval) || '1h';
    const limit = parseInt(req.query.limit as string, 10) || 100;

    const data = await indicatorsService.getVWAP({ symbol, interval, limit });
    res.json({ success: true, data });
  } catch (error) {
    next(error);
  }
}

// ============================================================================
// All-in-One
// ============================================================================

export async function getAllIndicators(req: Request, res: Response, next: NextFunction): Promise<void> {
  try {
    const { symbol } = req.params;
    const interval = (req.query.interval as Interval) || '1h';
    const limit = parseInt(req.query.limit as string, 10) || 100;

    const data = await indicatorsService.getAllIndicators(symbol, interval, limit);
    res.json({ success: true, data });
  } catch (error) {
    next(error);
  }
}
