/**
 * 일목균형표(IchimokuCloud) 설정
 */
import type { IndicatorConfig } from '../types';
import type { PlotDef } from './indicatorRegistry';

/** 설정 화면 한 줄 = 플롯 1개 + (선택) 기간 파라미터 */
export interface IchimokuLineRowDef {
  plotIndex: number;
  plotId: string;
  /** 플롯 행 기간 입력에 쓰는 params 키 */
  paramKey?: string;
}

/** registry plot ID → 차트·설정 화면 한글 라벨 */
export const ICHIMOKU_PLOT_TITLES: Record<string, string> = {
  plot0: '전환선',
  plot1: '기준선',
  plot2: '후행스팬',
  plot3: '선행스팬1',
  plot4: '선행스팬2',
};

export function getIchimokuPlotTitle(plotId: string): string {
  return ICHIMOKU_PLOT_TITLES[plotId] ?? plotId;
}

export const ICHIMOKU_LINE_ROWS: IchimokuLineRowDef[] = [
  { plotIndex: 0, plotId: 'plot0', paramKey: 'conversionPeriods' },
  { plotIndex: 1, plotId: 'plot1', paramKey: 'basePeriods' },
  { plotIndex: 2, plotId: 'plot2', paramKey: 'displacement' },
  { plotIndex: 3, plotId: 'plot3', paramKey: 'laggingSpan2Periods' },
  { plotIndex: 4, plotId: 'plot4', paramKey: 'displacement' },
];

export const ICHIMOKU_DEFAULT_PARAMS: Record<string, number> = {
  conversionPeriods: 9,
  basePeriods: 26,
  laggingSpan2Periods: 52,
  displacement: 26,
};

export function createDefaultIchimokuParams(): Record<string, number> {
  return { ...ICHIMOKU_DEFAULT_PARAMS };
}

export function createDefaultIchimokuPlotVisibility(): Record<string, boolean> {
  const vis: Record<string, boolean> = {};
  for (const row of ICHIMOKU_LINE_ROWS) vis[row.plotId] = true;
  return vis;
}

export interface IchimokuCloudColors {
  /** 선행스팬1 > 선행스팬2 (상승 구름) */
  bullishColor: string;
  /** 선행스팬1 < 선행스팬2 (하락 구름) */
  bearishColor: string;
}

/** #RRGGBBAA — 상승 구름 빨강 20%, 하락 구름 청록 20% */
export const DEFAULT_ICHIMOKU_CLOUD_COLORS: IchimokuCloudColors = {
  bullishColor: '#EF535033',
  bearishColor: '#26A69A33',
};

/** registry plot ID → lightweight-charts-indicators plot ID */
export const ICHIMOKU_REGISTRY_TO_LIB: Record<string, string> = {
  plot0: 'plot0',
  plot1: 'plot1',
  plot2: 'plot3',
  plot3: 'plot4',
  plot4: 'plot2',
};

export const ICHIMOKU_LIB_TO_REGISTRY: Record<string, string> = {
  plot0: 'plot0',
  plot1: 'plot1',
  plot2: 'plot4',
  plot3: 'plot2',
  plot4: 'plot3',
};

export function isIchimokuCloudVisible(config: IndicatorConfig): boolean {
  return (
    config.plotVisibility?.['plot2'] !== false &&
    config.plotVisibility?.['plot3'] !== false
  );
}

export function resolveIchimokuCloudColors(
  colors?: Partial<IchimokuCloudColors>,
): IchimokuCloudColors {
  return {
    bullishColor: colors?.bullishColor ?? DEFAULT_ICHIMOKU_CLOUD_COLORS.bullishColor,
    bearishColor: colors?.bearishColor ?? DEFAULT_ICHIMOKU_CLOUD_COLORS.bearishColor,
  };
}

export function normalizeIchimokuConfig(config: IndicatorConfig): IndicatorConfig {
  if (config.type !== 'IchimokuCloud') return config;

  const params: Record<string, number | string | boolean> = {
    ...createDefaultIchimokuParams(),
    ...config.params,
  };
  for (const key of Object.keys(ICHIMOKU_DEFAULT_PARAMS)) {
    const v = params[key];
    if (typeof v !== 'number' || v < 1) {
      params[key] = ICHIMOKU_DEFAULT_PARAMS[key];
    }
  }

  const plotVisibility: Record<string, boolean> = {
    ...createDefaultIchimokuPlotVisibility(),
    ...config.plotVisibility,
  };

  return {
    ...config,
    params,
    plotVisibility,
    cloudColors: resolveIchimokuCloudColors(config.cloudColors),
  };
}

/** registry 기본 플롯과 병합된 일목 플롯 목록 */
export function mergeIchimokuPlots(
  saved: PlotDef[] | undefined,
  defaults: PlotDef[],
): PlotDef[] {
  const savedMap = new Map((saved ?? []).map(p => [p.id, p]));
  return defaults.map(def => {
    const s = savedMap.get(def.id);
    const title = getIchimokuPlotTitle(def.id);
    return s
      ? { ...def, ...s, id: def.id, title, type: 'line' as const }
      : { ...def, title };
  });
}

/** #RRGGBB 또는 #RRGGBBAA → rgba(r,g,b,a) 표시 문자열 */
export function colorToRgbaString(color: string): string {
  if (color.startsWith('rgba(')) return color;
  const hex = color.startsWith('#') ? color.slice(1) : color;
  if (hex.length < 6) return color;
  const r = parseInt(hex.slice(0, 2), 16);
  const g = parseInt(hex.slice(2, 4), 16);
  const b = parseInt(hex.slice(4, 6), 16);
  const a = hex.length >= 8
    ? Math.round(parseInt(hex.slice(6, 8), 16) / 255 * 100) / 100
    : 1;
  return `rgba(${r}, ${g}, ${b}, ${a})`;
}

export function cloudColorOpacityPercent(color: string): number {
  if (color.startsWith('rgba(')) {
    const m = color.match(/,\s*([\d.]+)\s*\)$/);
    return m ? Math.round(parseFloat(m[1]) * 100) : 100;
  }
  if (color.length >= 9) {
    return Math.round(parseInt(color.slice(7, 9), 16) / 255 * 100);
  }
  return 100;
}
