import type { OHLCVBar, Timeframe } from '../types';
import { formatUnixForChart } from './timezone';

export const SYMBOLS = [
  'BTCUSD','ETHUSD','BNBUSD','SOLUSD','ADAUSD',
  'AAPL','MSFT','TSLA','NVDA','AMZN','GOOGL','META',
  'SPX500','NASDAQ','DJI',
  'EURUSD','GBPUSD','USDJPY','AUDUSD',
  'XAUUSD','XAGUSD','USOIL',
];

const TF_SECONDS: Record<Timeframe, number> = {
  '1m':60,'3m':180,'5m':300,'15m':900,'30m':1800,'1h':3600,'4h':14400,'1D':86400,'1W':604800,'1M':2592000,
};

const TF_BARS: Record<Timeframe, number> = {
  '1m':300,'3m':300,'5m':300,'15m':300,'30m':300,'1h':500,'4h':500,'1D':500,'1W':300,'1M':120,
};

const SEED_MAP: Record<string, number> = {
  BTCUSD:1, ETHUSD:2, BNBUSD:3, SOLUSD:4, ADAUSD:5,
  AAPL:6, MSFT:7, TSLA:8, NVDA:9, AMZN:10, GOOGL:11, META:12,
  SPX500:13, NASDAQ:14, DJI:15,
  EURUSD:16, GBPUSD:17, USDJPY:18, AUDUSD:19,
  XAUUSD:20, XAGUSD:21, USOIL:22,
};

const BASE_PRICE: Record<string, number> = {
  BTCUSD:45000, ETHUSD:2800, BNBUSD:380, SOLUSD:105, ADAUSD:0.52,
  AAPL:192, MSFT:420, TSLA:245, NVDA:870, AMZN:195, GOOGL:172, META:510,
  SPX500:5200, NASDAQ:18500, DJI:39000,
  EURUSD:1.088, GBPUSD:1.268, USDJPY:148, AUDUSD:0.655,
  XAUUSD:2050, XAGUSD:23.5, USOIL:78,
};

const VOLATILITY: Record<string, number> = {
  BTCUSD:0.025, ETHUSD:0.03, BNBUSD:0.025, SOLUSD:0.04, ADAUSD:0.035,
  AAPL:0.012, MSFT:0.011, TSLA:0.03, NVDA:0.025, AMZN:0.013, GOOGL:0.012, META:0.018,
  SPX500:0.008, NASDAQ:0.01, DJI:0.007,
  EURUSD:0.004, GBPUSD:0.005, USDJPY:0.004, AUDUSD:0.005,
  XAUUSD:0.008, XAGUSD:0.012, USOIL:0.015,
};

function lcg(seed: number) {
  let s = seed;
  return () => { s = (s * 1664525 + 1013904223) & 0xffffffff; return (s >>> 0) / 0xffffffff; };
}

export function generateBars(symbol: string, timeframe: Timeframe): OHLCVBar[] {
  const seed  = (SEED_MAP[symbol] ?? 1) * 97 + (TF_SECONDS[timeframe] ?? 86400);
  const rand  = lcg(seed);
  const count = TF_BARS[timeframe] ?? 300;
  const tfSec = TF_SECONDS[timeframe] ?? 86400;
  const baseP = BASE_PRICE[symbol] ?? 100;
  const vol   = VOLATILITY[symbol] ?? 0.015;

  const now = Math.floor(Date.now() / 1000);
  const startTime = now - count * tfSec;

  const bars: OHLCVBar[] = [];
  let price = baseP;
  const digits = baseP < 5 ? 4 : baseP < 100 ? 2 : 0;
  const roundP = (p: number) => parseFloat(p.toFixed(digits));

  for (let i = 0; i < count; i++) {
    const t = startTime + i * tfSec;
    // Trend bias - creates realistic trending periods
    const trendBias = Math.sin(i / 40) * vol * 0.4 + (rand() - 0.495) * vol;
    const open = price;
    const close = roundP(open * (1 + trendBias));
    const spread = Math.abs(close - open);
    const highExtra = rand() * spread * (1.5 + rand());
    const lowExtra  = rand() * spread * (1.5 + rand());
    const high  = roundP(Math.max(open, close) + highExtra);
    const low   = roundP(Math.min(open, close) - lowExtra);
    const volume = Math.round((0.5 + rand() * 1.5) * baseP * 1000 * (1 + Math.abs(trendBias) / vol));

    bars.push({ time: t, open, high, low, close, volume });
    price = close;
  }
  return bars;
}

export function formatPrice(price: number): string {
  if (price >= 10000) return price.toLocaleString('en-US', { minimumFractionDigits: 0, maximumFractionDigits: 0 });
  if (price >= 100)   return price.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
  if (price >= 1)     return price.toLocaleString('en-US', { minimumFractionDigits: 3, maximumFractionDigits: 4 });
  return price.toLocaleString('en-US', { minimumFractionDigits: 4, maximumFractionDigits: 6 });
}

export function formatTime(ts: number, timeframe: Timeframe): string {
  return formatUnixForChart(ts, timeframe);
}
