/**
 * 보조지표 설정 편집 — 개별 모달·일괄 설정 팝업 공통 직렬화/초기화
 */
import type { IndicatorConfig, HlinesBackground, Timeframe } from '../types';
import type { PlotDef, HLineDef } from './indicatorRegistry';
import {
  getIndicatorDef,
  mergePlotDefs,
  normalizeHLines,
  normalizeObvParams,
  enrichIndicatorConfig,
} from './indicatorRegistry';
import {
  normalizeBollingerParams,
  DEFAULT_BB_BAND_BACKGROUND,
  resolveBbBandBackground,
} from './bollingerConfig';
import { normalizeDmiParams } from './indicatorRegistry';
import {
  normalizeSmaConfig,
  createDefaultSmaParams,
  createDefaultSmaPlots,
  createDefaultSmaPlotVisibility,
} from './smaConfig';
import {
  normalizeIchimokuConfig,
  createDefaultIchimokuParams,
  createDefaultIchimokuPlotVisibility,
  mergeIchimokuPlots,
  DEFAULT_ICHIMOKU_CLOUD_COLORS,
  resolveIchimokuCloudColors,
  type IchimokuCloudColors,
} from './ichimokuConfig';

export const DEFAULT_HLINES_BG: HlinesBackground = { visible: true, color: '#787B8640' };

export interface IndicatorSettingsEditorSnapshot {
  params: Record<string, number | string | boolean>;
  plots: PlotDef[];
  plotVis: Record<string, boolean>;
  hlines: HLineDef[];
  hlinesBg: HlinesBackground;
  lastValueVisible: boolean;
  timeframeVis: Partial<Record<Timeframe, boolean>>;
  cloudColors: IchimokuCloudColors;
  bandBg: HlinesBackground;
}

/** 차트·DB 값으로 편집기 초기 config (개별 모달·일괄 팝업 동일) */
export function initializeIndicatorConfigForEditor(
  raw: IndicatorConfig,
  getParams?: (type: string, defaults: Record<string, number | string | boolean>) => Record<string, number | string | boolean>,
  getVisualConfig?: (
    type: string,
    defaultPlots: PlotDef[],
    defaultHlines?: HLineDef[],
  ) => { plots: PlotDef[]; hlines: HLineDef[]; cloudColors?: IchimokuCloudColors },
): IndicatorConfig {
  const def = getIndicatorDef(raw.type);
  if (!def) return enrichIndicatorConfig(raw);

  const params = getParams
    ? { ...getParams(raw.type, def.defaultParams), ...raw.params }
    : { ...raw.params };
  const visual = getVisualConfig?.(raw.type, def.plots, def.hlines);

  return enrichIndicatorConfig({
    ...raw,
    params,
    plots: raw.plots?.length ? raw.plots : visual?.plots,
    hlines: raw.hlines?.length ? raw.hlines : visual?.hlines,
    cloudColors: raw.cloudColors ?? visual?.cloudColors,
  });
}

export function createEditorSnapshot(config: IndicatorConfig): IndicatorSettingsEditorSnapshot {
  const normalized = config.type === 'SMA'
    ? normalizeSmaConfig(config)
    : config.type === 'IchimokuCloud'
      ? normalizeIchimokuConfig(config)
      : config;
  const def = getIndicatorDef(config.type);

  const baseParams = config.type === 'SMA' || config.type === 'IchimokuCloud'
    ? { ...normalized.params }
    : { ...(def?.defaultParams ?? {}), ...normalized.params };

  let params = baseParams;
  if (config.type === 'OBV') params = normalizeObvParams(baseParams);
  if (config.type === 'BollingerBands') params = normalizeBollingerParams(baseParams);
  if (config.type === 'DMI') params = normalizeDmiParams(baseParams);

  const basePlots: PlotDef[] = config.type === 'IchimokuCloud'
    ? mergeIchimokuPlots(normalized.plots, def?.plots ?? [])
    : mergePlotDefs(normalized.plots, def?.plots ?? []);

  const plotVis: Record<string, boolean> = { ...normalized.plotVisibility };
  const mergedParams = { ...(def?.defaultParams ?? {}), ...normalized.params };
  for (const p of basePlots) {
    if (plotVis[p.id] === undefined) {
      plotVis[p.id] = normalized.plotVisibility?.[p.id] !== false;
    }
  }
  if ((config.type === 'CCI' || config.type === 'RSI') && mergedParams.maType === 'None') {
    plotVis.plot1 = false;
  }

  const baseHLines: HLineDef[] = config.hlines ?? def?.hlines ?? [];

  return {
    params,
    plots: basePlots.map(p => ({ ...p })),
    plotVis,
    hlines: normalizeHLines(
      baseHLines.map(h => ({ ...h, visible: h.visible !== false })),
      config.type,
      def?.hlines,
    ),
    hlinesBg: normalized.hlinesBackground ?? { ...DEFAULT_HLINES_BG },
    lastValueVisible: normalized.lastValueVisible !== false,
    timeframeVis: { ...normalized.timeframeVisibility },
    cloudColors: resolveIchimokuCloudColors(normalized.cloudColors),
    bandBg: resolveBbBandBackground(normalized.bandBackground),
  };
}

/** 편집 스냅샷 → IndicatorConfig (저장·일괄 적용·실시간 onChange 공통) */
export function configFromEditorSnapshot(
  base: IndicatorConfig,
  snap: IndicatorSettingsEditorSnapshot,
): IndicatorConfig {
  const def = getIndicatorDef(base.type);
  const hasHLines = (def?.hlines ?? []).length > 0 || snap.hlines.length > 0;
  const tfVis = Object.values(snap.timeframeVis).some(v => v === false)
    ? snap.timeframeVis
    : undefined;

  const draft: IndicatorConfig = {
    ...base,
    params: snap.params,
    plots: snap.plots,
    plotVisibility: snap.plotVis,
    hlines: snap.hlines,
    hlinesBackground: hasHLines ? snap.hlinesBg : undefined,
    lastValueVisible: snap.lastValueVisible,
    timeframeVisibility: tfVis,
    ...(base.type === 'IchimokuCloud' ? { cloudColors: snap.cloudColors } : {}),
  };

  if (base.type === 'SMA') return normalizeSmaConfig(draft);
  if (base.type === 'IchimokuCloud') return normalizeIchimokuConfig(draft);
  if (base.type === 'BollingerBands') {
    return enrichIndicatorConfig({
      ...draft,
      params: normalizeBollingerParams(draft.params),
      bandBackground: snap.bandBg,
    });
  }
  return enrichIndicatorConfig(draft);
}

/** 지표별 기본값 (id·hidden 유지) */
export function resetConfigToDefaults(config: IndicatorConfig): IndicatorConfig {
  const def = getIndicatorDef(config.type);
  if (!def) return config;

  if (config.type === 'SMA') {
    return normalizeSmaConfig({
      ...config,
      params: createDefaultSmaParams(),
      plots: createDefaultSmaPlots(),
      plotVisibility: createDefaultSmaPlotVisibility(),
      hlines: [],
      hlinesBackground: undefined,
      lastValueVisible: true,
      timeframeVisibility: undefined,
    });
  }
  if (config.type === 'IchimokuCloud') {
    return normalizeIchimokuConfig({
      ...config,
      params: createDefaultIchimokuParams(),
      plots: def.plots.map(p => ({ ...p })),
      plotVisibility: createDefaultIchimokuPlotVisibility(),
      cloudColors: DEFAULT_ICHIMOKU_CLOUD_COLORS,
      hlines: [],
      hlinesBackground: undefined,
      lastValueVisible: true,
      timeframeVisibility: undefined,
    });
  }

  const baseParams = { ...(def.defaultParams as Record<string, number | string | boolean>) };
  const plots = def.plots.map(p => ({ ...p }));
  const plotVis: Record<string, boolean> = {};
  for (const p of def.plots) plotVis[p.id] = true;

  let params = config.type === 'BollingerBands'
    ? normalizeBollingerParams(baseParams)
    : baseParams;

  const draft: IndicatorConfig = {
    ...config,
    params,
    plots,
    plotVisibility: plotVis,
    hlines: normalizeHLines(
      (def.hlines ?? []).map(h => ({ ...h, visible: h.visible !== false })),
      config.type,
      def.hlines,
    ),
    hlinesBackground: { ...DEFAULT_HLINES_BG },
    lastValueVisible: true,
    timeframeVisibility: undefined,
    cloudColors: undefined,
    bandBackground: config.type === 'BollingerBands' ? { ...DEFAULT_BB_BAND_BACKGROUND } : undefined,
  };
  return enrichIndicatorConfig(draft);
}
