import type { LogicNode } from './strategyTypes';
import { genId, type DefType } from './strategyEditorShared';

export type SimpleStrategyTemplate = {
  kind: 'simple';
  signal: 'buy' | 'sell';
  label: string;
  description?: string;
  ind: string;
  cond: string;
  l: string;
  r: string;
};

export type CompositeStrategyTemplate = {
  kind: 'composite';
  signal: 'buy' | 'sell';
  label: string;
  description: string;
  build: () => LogicNode;
};

export type StrategyTemplateDef = SimpleStrategyTemplate | CompositeStrategyTemplate;

function condition(
  indicatorType: string,
  conditionType: string,
  leftField: string,
  rightField: string,
  candleRange = 1,
): LogicNode {
  return {
    id: genId(),
    type: 'CONDITION',
    condition: { indicatorType, conditionType, leftField, rightField, candleRange },
  };
}

function andTree(...children: LogicNode[]): LogicNode {
  return { id: genId(), type: 'AND', children };
}

/** 돈천 채널 — N일 최고가 상향 돌파 */
function donchianBreakoutBuy(period: number): LogicNode {
  return condition('DONCHIAN', 'CROSS_UP', 'CLOSE_PRICE', `DC_UPPER_${period}`);
}

/** 돈천 채널 — N일 최저가 하향 이탈 */
function donchianBreakdownSell(period: number): LogicNode {
  return condition('DONCHIAN', 'CROSS_DOWN', 'CLOSE_PRICE', `DC_LOWER_${period}`);
}

/** 일목균형표 — 전환선(9일) / 기준선(26일) 골든·데드크로스 */
function ichimokuTenkanKijunCross(signal: 'buy' | 'sell'): LogicNode {
  return condition(
    'ICHIMOKU',
    signal === 'buy' ? 'CROSS_UP' : 'CROSS_DOWN',
    'CONVERSION_LINE',
    'BASE_LINE',
  );
}

/** 33변곡 매수 — 바닥권 시간변곡(약 33거래일 주기) 전환 구간 */
export function build33InflectionBuyTree(): LogicNode {
  return andTree(
    condition('RSI', 'CROSS_UP', 'RSI_VALUE', 'OVERSOLD_30'),
    condition('MA', 'CROSS_UP', 'MA5', 'MA20'),
    condition('MA', 'CROSS_UP', 'CLOSE_PRICE', 'MA20'),
    condition('MACD', 'CROSS_UP', 'MACD_LINE', 'SIGNAL_LINE'),
    condition('DISPARITY', 'CROSS_UP', 'DISPARITY20', 'OVERSOLD_95'),
  );
}

/** 33변곡 매도 — 상승 5파 끝(33·36·38일 변곡) 구간 이탈 */
export function build33InflectionSellTree(): LogicNode {
  return andTree(
    condition('RSI', 'GTE', 'RSI_VALUE', 'OVERBOUGHT_70'),
    condition('MA', 'CROSS_DOWN', 'MA5', 'MA20'),
    condition('MA', 'CROSS_DOWN', 'CLOSE_PRICE', 'MA20'),
    condition('MACD', 'CROSS_DOWN', 'MACD_LINE', 'SIGNAL_LINE'),
    condition('DISPARITY', 'GTE', 'DISPARITY20', 'OVERBOUGHT_105'),
  );
}

export function getStrategyTemplates(def: DefType): StrategyTemplateDef[] {
  const maShort = `MA${def.maLines[0]}`;
  const maMid = `MA${def.maLines[1]}`;

  return [
    { kind: 'simple', ind: 'MA', cond: 'CROSS_UP', l: maShort, r: maMid, signal: 'buy', label: 'MA 골든크로스 매수' },
    { kind: 'simple', ind: 'MA', cond: 'CROSS_DOWN', l: maShort, r: maMid, signal: 'sell', label: 'MA 데드크로스 매도' },
    { kind: 'simple', ind: 'RSI', cond: 'LTE', l: 'RSI_VALUE', r: 'OVERSOLD_30', signal: 'buy', label: 'RSI 과매도 매수' },
    { kind: 'simple', ind: 'RSI', cond: 'GTE', l: 'RSI_VALUE', r: 'OVERBOUGHT_70', signal: 'sell', label: 'RSI 과매수 매도' },
    { kind: 'simple', ind: 'MACD', cond: 'CROSS_UP', l: 'MACD_LINE', r: 'SIGNAL_LINE', signal: 'buy', label: 'MACD 상향 돌파' },
    { kind: 'simple', ind: 'MACD', cond: 'CROSS_DOWN', l: 'MACD_LINE', r: 'SIGNAL_LINE', signal: 'sell', label: 'MACD 하향 돌파' },
    { kind: 'simple', ind: 'BOLLINGER', cond: 'CROSS_UP', l: 'CLOSE_PRICE', r: 'LOWER_BAND', signal: 'buy', label: '볼린저 하단 돌파 매수' },
    { kind: 'simple', ind: 'BOLLINGER', cond: 'CROSS_UP', l: 'CLOSE_PRICE', r: 'UPPER_BAND', signal: 'sell', label: '볼린저 상단 돌파 매도' },
    { kind: 'simple', ind: 'CCI', cond: 'CROSS_UP', l: 'CCI_VALUE', r: 'OVERSOLD_NEG100', signal: 'buy', label: 'CCI 과매도 반등' },
    { kind: 'simple', ind: 'PSYCHOLOGICAL', cond: 'CROSS_UP', l: 'PSY_VALUE', r: 'OVERBOUGHT_75', signal: 'buy', label: '심리도 상향 돌파' },
    { kind: 'simple', ind: 'STOCHASTIC', cond: 'CROSS_UP', l: 'STOCH_K', r: 'STOCH_D', signal: 'buy', label: '스토캐스틱 골든크로스' },
    { kind: 'simple', ind: 'ADX', cond: 'CROSS_UP', l: 'ADX_VALUE', r: 'ADX_25', signal: 'buy', label: 'ADX 중앙선 상향 돌파' },
    {
      kind: 'composite',
      signal: 'buy',
      label: '33변곡 매수',
      description: '바닥권 시간변곡 — RSI 과매도 탈출 + MA 골든크로스 + 20일선·이격도 돌파',
      build: build33InflectionBuyTree,
    },
    {
      kind: 'composite',
      signal: 'sell',
      label: '33변곡 매도',
      description: '상승 5파 끝 변곡 — RSI 과매수 + MA 데드크로스 + 20일선·이격도 이탈',
      build: build33InflectionSellTree,
    },
    {
      kind: 'composite',
      signal: 'buy',
      label: '돈천 채널(20일) 매수',
      description: '종가가 직전 20거래일 최고가(상단선)를 상향 돌파 — 한 달 박스권 돌파',
      build: () => donchianBreakoutBuy(20),
    },
    {
      kind: 'composite',
      signal: 'sell',
      label: '돈천 채널(20일) 매도',
      description: '종가가 직전 20거래일 최저가(하단선)를 하향 이탈 — 추세 이탈 청산',
      build: () => donchianBreakdownSell(20),
    },
    {
      kind: 'composite',
      signal: 'buy',
      label: '터틀 S1 매수',
      description: '단기 시스템 — 20일 최고가 돌파 진입 (리처드 데니스 터틀 트레이딩)',
      build: () => donchianBreakoutBuy(20),
    },
    {
      kind: 'composite',
      signal: 'sell',
      label: '터틀 S1 청산',
      description: '단기 시스템 — 10일 최저가 이탈 시 즉시 청산 (진입보다 짧은 손절)',
      build: () => donchianBreakdownSell(10),
    },
    {
      kind: 'composite',
      signal: 'buy',
      label: '터틀 S2 매수',
      description: '장기 시스템 — 55일 최고가 돌파 진입 (큰 추세 포착)',
      build: () => donchianBreakoutBuy(55),
    },
    {
      kind: 'composite',
      signal: 'sell',
      label: '터틀 S2 청산',
      description: '장기 시스템 — 20일 최저가 이탈 시 청산 (S1보다 여유, S2보다 빠른 탈출)',
      build: () => donchianBreakdownSell(20),
    },
    {
      kind: 'composite',
      signal: 'buy',
      label: '일목 전환/기준선 매수',
      description: '전환선(9일 중간값)이 기준선(26일 중간값)을 상향 돌파 — 골든크로스',
      build: () => ichimokuTenkanKijunCross('buy'),
    },
    {
      kind: 'composite',
      signal: 'sell',
      label: '일목 전환/기준선 매도',
      description: '전환선(9일)이 기준선(26일)을 하향 이탈 — 데드크로스',
      build: () => ichimokuTenkanKijunCross('sell'),
    },
  ];
}

export function simpleTemplateToNode(tmpl: SimpleStrategyTemplate): LogicNode {
  return condition(tmpl.ind, tmpl.cond, tmpl.l, tmpl.r);
}
