/**
 * 캔들 데이터 API 최적화 버전
 * - 캐싱 적용
 * - 중복 요청 방지 (Request Deduplication)
 * - 배치 요청 지원
 */

import axios from 'axios';
import { getApiBaseUrl } from './apiConfig';
import { apiCache, cachedFetch } from './apiCacheService';
import type { CandleData, IndicatorData } from './backtestApi';

const API_BASE_URL = getApiBaseUrl();

// 진행 중인 요청 추적 (중복 요청 방지)
const pendingRequests = new Map<string, Promise<any>>();

/**
 * 중복 요청 방지 래퍼
 */
async function deduplicatedFetch<T>(
  key: string,
  fetcher: () => Promise<T>
): Promise<T> {
  // 이미 진행 중인 요청이 있으면 재사용
  if (pendingRequests.has(key)) {
    console.log(`⏳ [Request DEDUP] ${key}`);
    return pendingRequests.get(key) as Promise<T>;
  }

  // 새 요청 시작
  const promise = fetcher().finally(() => {
    pendingRequests.delete(key);
  });

  pendingRequests.set(key, promise);
  return promise;
}

interface CandleApiParams {
  symbol: string;
  interval: string;
  count: number;
  to?: string;
}

/**
 * 캔들 데이터 로드 (캐싱 + 중복 방지)
 */
export async function fetchCandlesOptimized(
  params: CandleApiParams
): Promise<CandleData[]> {
  const cacheKey = apiCache.createKey('candles', params);

  return deduplicatedFetch(cacheKey, async () => {
    return cachedFetch(
      cacheKey,
      async () => {
        console.log(`📡 [API] 캔들 데이터 요청:`, params);
        const response = await axios.get(`${API_BASE_URL}/pattern/candles`, {
          params: {
            market: params.symbol,
            timeframe: params.interval,
            count: params.count,
            to: params.to,
          },
        });
        // 백엔드 응답: {data: [...], success: true, ...}
        // data 배열만 추출
        if (response.data && response.data.data) {
          return response.data.data;
        }
        return response.data;
      },
      { ttl: 30 * 1000 } // 30초 캐시 (실시간성 유지)
    );
  });
}

interface IndicatorApiParams {
  symbol: string;
  interval: string;
  candles: CandleData[];
  maPeriods?: number[];
  indicatorSettings?: Record<string, any>;
  vrPeriod?: number;
  vr2Enabled?: boolean;
  vr2Period?: number;
}

/**
 * 보조지표 데이터 로드 (캐싱 + 중복 방지)
 */
export async function fetchIndicatorsOptimized(
  params: IndicatorApiParams
): Promise<IndicatorData[]> {
  // 캔들 데이터는 해시로 변환 (정확한 캐시 키 생성)
  const candlesHash = hashCandles(params.candles);
  const cacheParams = {
    symbol: params.symbol,
    interval: params.interval,
    candlesHash,
    maPeriods: params.maPeriods,
    indicatorSettings: params.indicatorSettings,
    vrPeriod: params.vrPeriod,
    vr2Enabled: params.vr2Enabled,
    vr2Period: params.vr2Period,
  };

  const cacheKey = apiCache.createKey('indicators', cacheParams);

  return deduplicatedFetch(cacheKey, async () => {
    return cachedFetch(
      cacheKey,
      async () => {
        console.log(`📡 [API] 지표 데이터 요청:`, {
          symbol: params.symbol,
          interval: params.interval,
          candlesCount: params.candles.length,
        });
        const response = await axios.post(
          `${API_BASE_URL}/upbit/analyze`,
          {
            symbol: params.symbol,
            interval: params.interval,
            candles: params.candles,
            maPeriods: params.maPeriods || [],
            indicatorSettings: params.indicatorSettings || {},
            vrPeriod: params.vrPeriod,
            vr2Enabled: params.vr2Enabled,
            vr2Period: params.vr2Period,
          }
        );
        return response.data;
      },
      { ttl: 60 * 1000 } // 1분 캐시
    );
  });
}

/**
 * 캔들 데이터 해시 생성 (캐시 키용)
 * - 첫/마지막 캔들의 시간과 가격만 사용 (성능 최적화)
 */
function hashCandles(candles: CandleData[]): string {
  if (candles.length === 0) return 'empty';
  
  const first = candles[0];
  const last = candles[candles.length - 1];
  
  return `${candles.length}_${first.time}_${first.close}_${last.time}_${last.close}`;
}

/**
 * 종목/시간봉 변경 시 관련 캐시 무효화
 */
export function invalidateCandleCache(symbol?: string, interval?: string): void {
  if (symbol && interval) {
    apiCache.invalidate(`candles:.*symbol="${symbol}".*interval="${interval}"`);
    apiCache.invalidate(`indicators:.*symbol="${symbol}".*interval="${interval}"`);
  } else if (symbol) {
    apiCache.invalidate(`candles:.*symbol="${symbol}"`);
    apiCache.invalidate(`indicators:.*symbol="${symbol}"`);
  } else {
    apiCache.invalidate(/^(candles|indicators):/);
  }
  
  console.log(`🧹 [Cache] 캐시 무효화: symbol=${symbol}, interval=${interval}`);
}

/**
 * 배치 캔들 로드 (여러 시간대 동시 로드)
 */
export async function fetchCandlesBatch(
  requests: CandleApiParams[]
): Promise<CandleData[][]> {
  console.log(`📦 [API] 배치 요청 (${requests.length}개)`);
  
  const promises = requests.map(params => fetchCandlesOptimized(params));
  return Promise.all(promises);
}

/**
 * 증분 업데이트 (마지막 N개 캔들만 로드)
 */
export async function fetchCandlesIncremental(
  symbol: string,
  interval: string,
  count: number = 10
): Promise<CandleData[]> {
  // 증분 업데이트는 캐시하지 않음 (항상 최신 데이터)
  const key = `candles_incremental_${symbol}_${interval}_${count}`;
  
  return deduplicatedFetch(key, async () => {
    console.log(`📡 [API] 증분 캔들 요청: ${symbol} ${interval} (최근 ${count}개)`);
    const response = await axios.get(`${API_BASE_URL}/pattern/candles`, {
      params: {
        symbol,
        interval,
        count,
      },
    });
    return response.data;
  });
}
