/**
 * 보조지표 설정 화면 — 플롯 행·전역 파라미터 배치 (일목/SMA 단일 화면 컨셉)
 */
import type { PlotDef } from './indicatorRegistry';

/** 플롯 행에 붙지 않고 상단에만 표시할 키 (우선 순서) */
const GLOBAL_FIRST_KEYS: string[] = [
  'src', 'maType', 'mult', 'multiplier', 'percent', 'bbMult', 'offset', 'sigma',
];

const GLOBAL_FIRST_SET = new Set(GLOBAL_FIRST_KEYS);

/** 지표별 플롯 ID → 파라미터 키 (빈 배열 = 자동/공유) */
export const INDICATOR_PLOT_PARAMS: Record<string, Record<string, string[]>> = {
  MACross: { plot0: ['fastLength'], plot1: ['slowLength'] },
  Stochastic: { plot0: ['kLength', 'smooth'], plot1: ['dSmoothing'] },
  StochRSI: { plot0: ['lengthRSI', 'lengthStoch', 'smoothK'], plot1: ['smoothD'] },
  CCI: { plot0: ['length'], plot1: ['maLength'] },
  RSI: { plot0: ['length'], plot1: ['maLength'] },
  /** 업비트: OBV 행=이동평균 종류, 신호선 행=기간 (색상 컨트롤 좌측) */
  OBV: { plot0: ['maType'], plot1: ['maLength'] },
  /** 업비트: 길이·곱·오프셋은 상단 전역 행, 플롯 행은 스타일만 */
  BollingerBands: { plot0: [], plot1: [], plot2: [] },
  /** 업비트: DI 길이·ADX 스무딩은 상단 전역, 플롯 행은 스타일만 */
  DMI: { plot0: [], plot1: [], plot2: [], plot3: [], plot4: [] },
  KeltnerChannels: { plot0: ['length', 'multiplier'], plot1: [], plot2: [] },
  DonchianChannels: { plot0: ['length'], plot1: [], plot2: [] },
  Envelope: { plot0: ['length', 'percent'], plot1: [], plot2: [] },
  RVI: { plot0: ['length'], plot1: [] },
  FisherTransform: { plot0: ['length'], plot1: [] },
  MACD: { plot0: ['fastLength', 'slowLength', 'signalLength'], plot1: [], plot2: [] },
  TSI: { plot0: ['longLength', 'shortLength'], plot1: ['signalLength'] },
  TRIX: { plot0: ['length'], plot1: ['signalLength'] },
  SMIErgodic: { plot0: ['shortLength', 'longLength'], plot1: ['signalLength'] },
  SMIErgodicOscillator: { plot0: ['shortLength', 'longLength'], plot1: ['signalLength'] },
  UltimateOscillator: { plot0: ['length1', 'length2', 'length3'] },
  ConnorsRSI: { plot0: ['rsiLength', 'upDownLength', 'rocLength'] },
  Psychological: { plot0: ['length'] },
  InvestPsychological: { plot0: ['length'] },
  Disparity: {
    plot0: ['ultraLength'],
    plot1: ['shortLength'],
    plot2: ['midLength'],
    plot3: ['longLength'],
  },
  IchimokuCloud: {
    plot0: ['conversionPeriods'],
    plot1: ['basePeriods'],
    /** 선행스팬1 — 전환·기준 평균선의 미래 이동(shift) 기간 */
    plot2: ['displacement'],
    plot3: ['laggingSpan2Periods'],
    /** 후행스팬 — chikou 이동(선행스팬1과 동일 displacement) */
    plot4: ['displacement'],
  },
};

const PLOT_INDEX_FALLBACK: Record<number, string[]> = {
  0: [
    'length', 'len', 'kLength', 'fastLength', 'length1', 'lengthRSI', 'rsiLength',
    'shortLength', 'ultraLength', 'conversionPeriods', 'turbolen',
  ],
  1: ['dSmoothing', 'slowLength', 'length2', 'smoothD', 'maLength', 'signalLength', 'midLength', 'basePeriods'],
  2: ['smooth', 'length3', 'longLength', 'laggingSpan2Periods'],
  3: ['longLength', 'displacement'],
  4: ['displacement'],
};

function keysInParams(keys: string[], params: Record<string, unknown>): string[] {
  return keys.filter(k => k in params);
}

/** 플롯 한 줄에 표시할 숫자·선택 파라미터 키 */
export function getPlotParamKeys(
  indicatorType: string,
  plotId: string,
  plotIndex: number,
  plots: PlotDef[],
  params: Record<string, number | string | boolean>,
): string[] {
  const mapped = INDICATOR_PLOT_PARAMS[indicatorType]?.[plotId];
  if (mapped !== undefined) {
    return keysInParams(mapped, params);
  }

  if (plots.length === 1) {
    return Object.keys(params).filter(
      k => !GLOBAL_FIRST_SET.has(k) && typeof params[k] === 'number',
    );
  }

  const fallback = keysInParams(PLOT_INDEX_FALLBACK[plotIndex] ?? [], params);
  if (fallback.length) return fallback;

  return [];
}

/** 업비트 BB 인풋 탭 순서 */
const BOLLINGER_GLOBAL_KEYS = ['length', 'mult', 'offset'] as const;

/** 플롯에 할당되지 않은 전역 파라미터 (상단 행) */
export function getGlobalParamKeys(
  indicatorType: string,
  params: Record<string, number | string | boolean>,
  plots: PlotDef[],
): string[] {
  if (indicatorType === 'BollingerBands') {
    return BOLLINGER_GLOBAL_KEYS.filter(k => k in params);
  }

  const assigned = new Set<string>();
  for (let i = 0; i < plots.length; i++) {
    for (const k of getPlotParamKeys(indicatorType, plots[i].id, i, plots, params)) {
      assigned.add(k);
    }
  }

  const remaining = Object.keys(params).filter(
    k => !assigned.has(k) && k !== 'symbolMode' && k !== 'refSymbol' && k !== 'src' && k !== 'maType',
  );
  const ordered = GLOBAL_FIRST_KEYS.filter(k => remaining.includes(k));
  const rest = remaining.filter(k => !ordered.includes(k));
  return [...ordered, ...rest];
}

/** 플롯 행 입력란에 표시할 내용 없음 */
export function plotRowHasNoInputs(
  indicatorType: string,
  plotId: string,
  plotIndex: number,
  plots: PlotDef[],
  params: Record<string, number | string | boolean>,
): boolean {
  return getPlotParamKeys(indicatorType, plotId, plotIndex, plots, params).length === 0;
}

/** 파라미터가 상단 전역 행에만 있음 (OBV: maType·maLength) — 플롯 행 '자동' 미표시 */
export function plotParamsOnGlobalRowOnly(indicatorType: string, plotId: string): boolean {
  const mapped = INDICATOR_PLOT_PARAMS[indicatorType]?.[plotId];
  return mapped !== undefined && mapped.length === 0;
}
