import React, { createContext, useContext, useState, useCallback, useEffect, useRef } from 'react';
import {
  getUserCustomReferenceLines,
  saveUserCustomReferenceLines,
  getGuestCustomReferenceLines,
  saveGuestCustomReferenceLines,
  getUserIndicatorPeriods,
  saveUserIndicatorPeriods,
  getGuestIndicatorPeriods,
  saveGuestIndicatorPeriods,
} from '../services/indicatorSettingsApi';

// 사용자 정의 기준선 타입
export interface CustomReferenceLine {
  id: string;
  name: string;
  value: number;
  color: string;
  lineStyle?: 'solid' | 'dashed' | 'dotted';
}

// 보조지표별 사용자 정의 기준선 맵
export interface CustomReferenceLines {
  [indicatorType: string]: CustomReferenceLine[];
}

// 보조지표 설정값 타입 정의 (15가지 보조지표)
export interface IndicatorSettings {
  // 지표 활성화 여부
  macdEnabled: boolean;
  stochasticEnabled: boolean;
  rsiEnabled: boolean;
  cciEnabled: boolean;
  adxEnabled: boolean;
  
  // 1. 신심리도 설정
  newPsychologicalPeriod: number;  // 기본값: 5
  newPsychologicalOverbought: number;  // 과매수 기준, 기본값: 75
  newPsychologicalMiddle: number;      // 중앙값, 기본값: 50
  newPsychologicalOversold: number;    // 과매도 기준, 기본값: 25
  newPsychologicalEnabled: boolean;    // 신심리도 활성화
  newPsychologicalOverboughtEnabled: boolean;  // 과열선 활성화
  newPsychologicalMiddleEnabled: boolean;      // 중앙선 활성화
  newPsychologicalOversoldEnabled: boolean;    // 침체선 활성화
  
  // 2. 투자심리도 설정
  investPsychologicalPeriod: number;  // 기본값: 10
  investPsychologicalEnabled: boolean; // 투자심리도 활성화
  investPsychologicalOverbought: number;  // 과열 기준, 기본값: 75
  investPsychologicalMiddle: number;      // 중앙값, 기본값: 50
  investPsychologicalOversold: number;    // 침체 기준, 기본값: 25
  investPsychologicalOverboughtEnabled: boolean;  // 과열선 활성화
  investPsychologicalMiddleEnabled: boolean;      // 중앙선 활성화
  investPsychologicalOversoldEnabled: boolean;    // 침체선 활성화
  
  // 3. MACD 설정 (12, 26, 9)
  macdFastPeriod: number;
  macdSlowPeriod: number;
  macdSignalPeriod: number;
  macdZeroLineEnabled: boolean;  // 0선 활성화
  histogramPositiveEnabled: boolean;  // 히스토그램(상승) 활성화
  histogramNegativeEnabled: boolean;  // 히스토그램(하락) 활성화
  
  // 4. CCI 설정 (13, 10)
  cciPeriod: number;
  cciSignalPeriod: number;
  cciOversold: number;
  cciMiddle: number;
  cciOverbought: number;
  cciSignalEnabled: boolean;      // 신호선 활성화
  cciOverboughtEnabled: boolean;  // 과매수선 활성화
  cciMiddleEnabled: boolean;      // 중앙선 활성화
  cciOversoldEnabled: boolean;    // 과매도선 활성화
  
  // 5. ADX 설정 (11)
  adxPeriod: number;
  adxStrongThreshold: number;
  adxWeakThreshold: number;      // 약한 추세 기준값
  adxStrongEnabled: boolean;     // 강한 추세선 활성화
  adxWeakEnabled: boolean;       // 약한 추세선 활성화
  
  // 6. BWI 설정 (20)
  bwiPeriod: number;
  bwiOverbought: number;         // 과매수 기준값
  bwiMiddle: number;             // 중립 기준값
  bwiOversold: number;           // 과매도 기준값
  bwiEnabled: boolean;           // BWI 활성화
  bwiOverboughtEnabled: boolean; // 과매수선 활성화
  bwiMiddleEnabled: boolean;     // 중립선 활성화
  bwiOversoldEnabled: boolean;   // 과매도선 활성화
  
  // 7. DMI 설정 (14)
  dmiPeriod: number;
  adxSmoothing: number;  // ADX 스무딩 기간 (기본값: 14)
  dmiEnabled: boolean;  // DMI 활성화
  plusDiEnabled: boolean;  // +DI 활성화
  minusDiEnabled: boolean; // -DI 활성화
  dxEnabled: boolean;  // DX 활성화
  dmiAdxEnabled: boolean;  // DMI 차트 내 ADX 라인 활성화 (DMI 전용)
  adxrEnabled: boolean;  // ADXR 활성화
  dmiOverbought: number;  // DMI 과열 기준선
  dmiMiddle: number;  // DMI 중간값 기준선
  dmiOversold: number;  // DMI 침체 기준선
  dmiOverboughtEnabled: boolean;  // 과열선 활성화
  dmiMiddleEnabled: boolean;  // 중간값선 활성화
  dmiOversoldEnabled: boolean;  // 침체선 활성화
  
  // 8. OBV 설정 (기간: 9, 신호: 9)
  obvPeriod: number;
  obvSignalPeriod: number;
  obvEnabled: boolean;         // OBV 활성화
  obvSignalEnabled: boolean;   // OBV 신호선 활성화
  
  // 9. RSI 설정 (기간: 9, 신호: 9, 급등: 70, 급락: 30)
  rsiPeriod: number;
  rsiSignalPeriod: number;
  rsiOversold: number;
  rsiMiddle: number;
  rsiOverbought: number;
  rsiSignalEnabled: boolean;      // 신호선 활성화
  rsiOverboughtEnabled: boolean;  // 과매수선 활성화
  rsiMiddleEnabled: boolean;      // 중앙선 활성화
  rsiOversoldEnabled: boolean;    // 과매도선 활성화
  
  // 10. Stochastic Slow 설정 (12, 5, 5)
  stochasticKPeriod: number;
  stochasticDPeriod: number;
  stochasticSlowing: number;
  stochasticOversold: number;
  stochasticOverbought: number;
  stochasticNeutral: number;
  stochasticOversoldEnabled: boolean;   // 과매도선 활성화
  stochasticNeutralEnabled: boolean;    // 중앙선 활성화
  stochasticOverboughtEnabled: boolean; // 과매수선 활성화
  
  // 11. Williams %R 설정 (11)
  williamsRPeriod: number;
  williamsREnabled: boolean;            // Williams %R 활성화 (항상 true, 비활성화 불가)
  williamsROversold: number;  // 침체
  williamsRMiddle: number;     // 중간값
  williamsROverbought: number; // 과열
  williamsROversoldEnabled: boolean;    // 침체선 활성화
  williamsRMiddleEnabled: boolean;      // 중간선 활성화
  williamsROverboughtEnabled: boolean;  // 과열선 활성화
  
  // 12. TRIX 설정 (12, 9)
  trixPeriod: number;
  trixSignalPeriod: number;
  trixOversold: number;
  trixMiddle: number;
  trixOverbought: number;
  trixEnabled: boolean;           // TRIX 활성화
  trixOverboughtEnabled: boolean; // 과매수선 활성화
  trixMiddleEnabled: boolean;     // 중앙선 활성화
  trixOversoldEnabled: boolean;   // 과매도선 활성화
  
  // 13. VolumeOSC 설정 (10, 20)
  volumeOscShortPeriod: number;
  volumeOscLongPeriod: number;
  volumeOscEnabled: boolean;          // VolumeOSC 활성화
  volumeOscZeroLineEnabled: boolean;  // 0선 활성화
  
  // 14. VR 설정 (10)
  vrPeriod: number;
  vrOverbought: number;         // 과열 기준값
  vrBaseLine: number;           // 기준선 값
  vrOversold: number;           // 침체 기준값
  vrEnabled: boolean;           // VR 활성화
  vrOverboughtEnabled: boolean; // 과열선 활성화
  vrBaseLineEnabled: boolean;   // 기준선 활성화
  vrOversoldEnabled: boolean;   // 침체선 활성화
  // VR2 통합 설정 (VR 설정 내부에서 관리)
  vr2Enabled: boolean;          // VR2 활성화 여부
  vr2Period: number;            // VR2 기간 (VR2가 활성화될 때 사용)
  
  // 15. 이격도 설정
  disparityUltraShortPeriod: number;  // 초단기
  disparityShortPeriod: number;        // 단기
  disparityMidPeriod: number;          // 중기
  disparityLongPeriod: number;         // 장기
  disparityEnabled: boolean;              // 이격도 활성화
  disparityUltraShortEnabled: boolean;    // 초단기선 활성화
  disparityShortEnabled: boolean;         // 단기선 활성화
  disparityMidEnabled: boolean;           // 중기선 활성화
  disparityLongEnabled: boolean;          // 장기선 활성화
  disparityBaseLineEnabled: boolean;      // 기준선 활성화
  
  // 16. Momentum 설정
  momentumPeriod: number;                 // Momentum 기간
  momentumEnabled: boolean;               // Momentum 활성화
  momentumZeroLineEnabled: boolean;       // 0선 활성화
  
  // 17. Volume 설정
  volumeRisingEnabled: boolean;           // 상승 거래량 활성화
  volumeFallingEnabled: boolean;          // 하락 거래량 활성화
}

// 기본값 (사용자 요청 파라미터 반영)
export const DEFAULT_INDICATOR_SETTINGS: IndicatorSettings = {
  // 지표 활성화 기본값
  macdEnabled: true,
  stochasticEnabled: true,
  rsiEnabled: true,
  cciEnabled: true,
  adxEnabled: true,
  
  // 1. 신심리도 기본값
  newPsychologicalPeriod: 5,
  newPsychologicalOverbought: 75,   // 과열
  newPsychologicalMiddle: 50,       // 중앙값
  newPsychologicalOversold: 25,     // 침체
  newPsychologicalEnabled: true,
  newPsychologicalOverboughtEnabled: true,
  newPsychologicalMiddleEnabled: true,
  newPsychologicalOversoldEnabled: true,
  
  // 2. 투자심리도 기본값
  investPsychologicalPeriod: 10,
  investPsychologicalEnabled: true,
  investPsychologicalOverbought: 75,   // 과열
  investPsychologicalMiddle: 50,       // 중앙값
  investPsychologicalOversold: 25,     // 침체
  investPsychologicalOverboughtEnabled: true,
  investPsychologicalMiddleEnabled: true,
  investPsychologicalOversoldEnabled: true,
  
  // 3. MACD 기본값 (12, 26, 9)
  macdFastPeriod: 12,
  macdSlowPeriod: 26,
  macdSignalPeriod: 9,
  macdZeroLineEnabled: true,
  histogramPositiveEnabled: true,
  histogramNegativeEnabled: true,
  
  // 4. CCI 기본값 (13, 10)
  cciPeriod: 13,
  cciSignalPeriod: 10,
  cciOversold: -100,
  cciMiddle: 0,
  cciOverbought: 100,
  cciSignalEnabled: true,
  cciOverboughtEnabled: true,
  cciMiddleEnabled: true,
  cciOversoldEnabled: true,
  
  // 5. ADX 기본값 (11)
  adxPeriod: 11,
  adxStrongThreshold: 25,   // 강한 추세
  adxWeakThreshold: 20,     // 약한 추세
  adxStrongEnabled: true,
  adxWeakEnabled: true,
  
  // 6. BWI 기본값 (20)
  bwiPeriod: 20,
  bwiOverbought: 1.0,       // 과매수
  bwiMiddle: 0.5,           // 중립
  bwiOversold: 0.0,         // 과매도
  bwiEnabled: true,
  bwiOverboughtEnabled: true,
  bwiMiddleEnabled: true,
  bwiOversoldEnabled: true,
  
  // 7. DMI 기본값 (14)
  dmiPeriod: 14,
  adxSmoothing: 14,  // ADX 스무딩 기본값
  dmiEnabled: true,
  plusDiEnabled: true,   // +DI 기본 ON
  minusDiEnabled: true,  // -DI 기본 ON
  dxEnabled: true,       // DX 기본 ON
  dmiAdxEnabled: true,   // DMI 차트 내 ADX 기본 ON
  adxrEnabled: true,     // ADXR 기본 ON
  dmiOverbought: 30,     // 과열 기준선 기본값
  dmiMiddle: 20,         // 중간값 기준선 기본값
  dmiOversold: 10,       // 침체 기준선 기본값
  dmiOverboughtEnabled: true,  // 과열선 기본 ON
  dmiMiddleEnabled: true,      // 중간값선 기본 ON
  dmiOversoldEnabled: true,    // 침체선 기본 ON
  
  // 8. OBV 기본값 (기간: 9, 신호: 9)
  obvPeriod: 9,
  obvSignalPeriod: 9,
  obvEnabled: true,
  obvSignalEnabled: true,
  
  // 9. RSI 기본값 (기간: 9, 신호: 9, 과매도: 30, 중앙값: 50, 과매수: 70)
  rsiPeriod: 9,
  rsiSignalPeriod: 9,
  rsiOversold: 30,
  rsiMiddle: 50,
  rsiOverbought: 70,
  rsiSignalEnabled: true,
  rsiOverboughtEnabled: true,
  rsiMiddleEnabled: true,
  rsiOversoldEnabled: true,
  
  // 10. Stochastic Slow 기본값 (12, 5, 5)
  stochasticKPeriod: 12,
  stochasticDPeriod: 5,
  stochasticSlowing: 5,
  stochasticOversold: 20,
  stochasticOversoldEnabled: true,
  stochasticNeutralEnabled: true,
  stochasticOverboughtEnabled: true,
  stochasticOverbought: 80,
  stochasticNeutral: 50,
  
  // 11. Williams %R 기본값 (11)
  williamsRPeriod: 11,
  williamsREnabled: true,             // Williams %R 항상 on
  williamsROversold: -80,    // 침체
  williamsRMiddle: -50,      // 중간값
  williamsROverbought: -20,  // 과열
  williamsROversoldEnabled: true,     // 침체선 기본 on
  williamsRMiddleEnabled: true,       // 중간선 기본 on
  williamsROverboughtEnabled: true,   // 과열선 기본 on
  
  // 12. TRIX 기본값 (12, 9)
  trixPeriod: 12,
  trixSignalPeriod: 9,
  trixOversold: -0.5,
  trixMiddle: 0,
  trixOverbought: 0.5,
  trixEnabled: true,
  trixOverboughtEnabled: true,
  trixMiddleEnabled: true,
  trixOversoldEnabled: true,
  
  // 13. VolumeOSC 기본값 (10, 20)
  volumeOscShortPeriod: 10,
  volumeOscLongPeriod: 20,
  volumeOscEnabled: true,
  volumeOscZeroLineEnabled: true,
  
  // 14. VR 기본값 (10, 150)
  vrPeriod: 10,
  vrOverbought: 150,      // 과열 기준
  vrBaseLine: 100,        // 기준선
  vrOversold: 70,         // 침체 기준
  vrEnabled: true,
  vrOverboughtEnabled: true,
  vrBaseLineEnabled: true,
  vrOversoldEnabled: true,
  // VR2 통합 설정 (기본적으로 비활성화)
  vr2Enabled: false,      // 기본적으로 VR2는 비활성화
  vr2Period: 10,          // VR2 기간
  
  // 15. 이격도 기본값 (5, 10, 20, 60)
  disparityUltraShortPeriod: 5,    // 초단기
  disparityShortPeriod: 10,        // 단기
  disparityMidPeriod: 20,          // 중기
  disparityLongPeriod: 60,         // 장기
  disparityEnabled: true,
  disparityUltraShortEnabled: true,
  disparityShortEnabled: true,
  disparityMidEnabled: true,
  disparityLongEnabled: true,
  disparityBaseLineEnabled: true,
  
  // 16. Momentum 기본값
  momentumPeriod: 10,               // Momentum 기간
  momentumEnabled: true,            // Momentum 활성화
  momentumZeroLineEnabled: true,    // 0선 활성화
  
  // 17. Volume 기본값
  volumeRisingEnabled: true,        // 상승 거래량 활성화
  volumeFallingEnabled: true,       // 하락 거래량 활성화
};

// localStorage에서 설정 불러오기
export const loadIndicatorSettingsFromStorage = (): IndicatorSettings => {
  // CCI 과매도는 음수이므로 특별 처리
  const cciOversoldStr = localStorage.getItem('cciOversold');
  const cciOversold = cciOversoldStr !== null ? Number(cciOversoldStr) : DEFAULT_INDICATOR_SETTINGS.cciOversold;
  
  // Williams %R 과매도/과매수는 음수
  const williamsROversoldStr = localStorage.getItem('williamsROversold');
  const williamsROversold = williamsROversoldStr !== null ? Number(williamsROversoldStr) : DEFAULT_INDICATOR_SETTINGS.williamsROversold;
  const williamsRMiddleStr = localStorage.getItem('williamsRMiddle');
  const williamsRMiddle = williamsRMiddleStr !== null ? Number(williamsRMiddleStr) : DEFAULT_INDICATOR_SETTINGS.williamsRMiddle;
  const williamsROverboughtStr = localStorage.getItem('williamsROverbought');
  const williamsROverbought = williamsROverboughtStr !== null ? Number(williamsROverboughtStr) : DEFAULT_INDICATOR_SETTINGS.williamsROverbought;
  
  // boolean 값 불러오기 헬퍼 함수
  const loadBoolean = (key: string, defaultValue: boolean): boolean => {
    const stored = localStorage.getItem(key);
    if (stored === null) return defaultValue;
    return stored === 'true';
  };
  
  return {
    // 지표 활성화 여부
    macdEnabled: loadBoolean('macdEnabled', DEFAULT_INDICATOR_SETTINGS.macdEnabled),
    stochasticEnabled: loadBoolean('stochasticEnabled', DEFAULT_INDICATOR_SETTINGS.stochasticEnabled),
    rsiEnabled: loadBoolean('rsiEnabled', DEFAULT_INDICATOR_SETTINGS.rsiEnabled),
    cciEnabled: loadBoolean('cciEnabled', DEFAULT_INDICATOR_SETTINGS.cciEnabled),
    adxEnabled: loadBoolean('adxEnabled', DEFAULT_INDICATOR_SETTINGS.adxEnabled),
    
    // 1. 신심리도
    newPsychologicalPeriod: Number(localStorage.getItem('newPsychologicalPeriod')) || DEFAULT_INDICATOR_SETTINGS.newPsychologicalPeriod,
    newPsychologicalOverbought: Number(localStorage.getItem('newPsychologicalOverbought')) || DEFAULT_INDICATOR_SETTINGS.newPsychologicalOverbought,
    newPsychologicalMiddle: Number(localStorage.getItem('newPsychologicalMiddle')) || DEFAULT_INDICATOR_SETTINGS.newPsychologicalMiddle,
    newPsychologicalOversold: Number(localStorage.getItem('newPsychologicalOversold')) || DEFAULT_INDICATOR_SETTINGS.newPsychologicalOversold,
    
    // 2. 투자심리도
    investPsychologicalPeriod: Number(localStorage.getItem('investPsychologicalPeriod')) || DEFAULT_INDICATOR_SETTINGS.investPsychologicalPeriod,
    investPsychologicalOverbought: Number(localStorage.getItem('investPsychologicalOverbought')) || DEFAULT_INDICATOR_SETTINGS.investPsychologicalOverbought,
    investPsychologicalMiddle: Number(localStorage.getItem('investPsychologicalMiddle')) || DEFAULT_INDICATOR_SETTINGS.investPsychologicalMiddle,
    investPsychologicalOversold: Number(localStorage.getItem('investPsychologicalOversold')) || DEFAULT_INDICATOR_SETTINGS.investPsychologicalOversold,
    
    // 3. MACD
    macdFastPeriod: Number(localStorage.getItem('macdFastPeriod')) || DEFAULT_INDICATOR_SETTINGS.macdFastPeriod,
    macdSlowPeriod: Number(localStorage.getItem('macdSlowPeriod')) || DEFAULT_INDICATOR_SETTINGS.macdSlowPeriod,
    macdSignalPeriod: Number(localStorage.getItem('macdSignalPeriod')) || DEFAULT_INDICATOR_SETTINGS.macdSignalPeriod,
    
    // 4. CCI
    cciPeriod: Number(localStorage.getItem('cciPeriod')) || DEFAULT_INDICATOR_SETTINGS.cciPeriod,
    cciSignalPeriod: Number(localStorage.getItem('cciSignalPeriod')) || DEFAULT_INDICATOR_SETTINGS.cciSignalPeriod,
    cciOversold: cciOversold,
    cciMiddle: Number(localStorage.getItem('cciMiddle')) || DEFAULT_INDICATOR_SETTINGS.cciMiddle,
    cciOverbought: Number(localStorage.getItem('cciOverbought')) || DEFAULT_INDICATOR_SETTINGS.cciOverbought,
    
    // 5. ADX
    adxPeriod: Number(localStorage.getItem('adxPeriod')) || DEFAULT_INDICATOR_SETTINGS.adxPeriod,
    adxStrongThreshold: Number(localStorage.getItem('adxStrongThreshold')) || DEFAULT_INDICATOR_SETTINGS.adxStrongThreshold,
    adxWeakThreshold: Number(localStorage.getItem('adxWeakThreshold')) || DEFAULT_INDICATOR_SETTINGS.adxWeakThreshold,
    
    // 6. BWI
    bwiPeriod: Number(localStorage.getItem('bwiPeriod')) || DEFAULT_INDICATOR_SETTINGS.bwiPeriod,
    bwiOverbought: Number(localStorage.getItem('bwiOverbought')) || DEFAULT_INDICATOR_SETTINGS.bwiOverbought,
    bwiMiddle: Number(localStorage.getItem('bwiMiddle')) || DEFAULT_INDICATOR_SETTINGS.bwiMiddle,
    bwiOversold: Number(localStorage.getItem('bwiOversold')) || DEFAULT_INDICATOR_SETTINGS.bwiOversold,
    
    // 7. DMI
    dmiPeriod: Number(localStorage.getItem('dmiPeriod')) || DEFAULT_INDICATOR_SETTINGS.dmiPeriod,
    adxSmoothing: Number(localStorage.getItem('adxSmoothing')) || DEFAULT_INDICATOR_SETTINGS.adxSmoothing,
    dmiEnabled: loadBoolean('dmiEnabled', DEFAULT_INDICATOR_SETTINGS.dmiEnabled),
    plusDiEnabled: loadBoolean('plusDiEnabled', DEFAULT_INDICATOR_SETTINGS.plusDiEnabled),
    minusDiEnabled: loadBoolean('minusDiEnabled', DEFAULT_INDICATOR_SETTINGS.minusDiEnabled),
    dxEnabled: loadBoolean('dxEnabled', DEFAULT_INDICATOR_SETTINGS.dxEnabled),
    dmiAdxEnabled: loadBoolean('dmiAdxEnabled', DEFAULT_INDICATOR_SETTINGS.dmiAdxEnabled),
    adxrEnabled: loadBoolean('adxrEnabled', DEFAULT_INDICATOR_SETTINGS.adxrEnabled),
    dmiOverbought: Number(localStorage.getItem('dmiOverbought')) || DEFAULT_INDICATOR_SETTINGS.dmiOverbought,
    dmiMiddle: Number(localStorage.getItem('dmiMiddle')) || DEFAULT_INDICATOR_SETTINGS.dmiMiddle,
    dmiOversold: Number(localStorage.getItem('dmiOversold')) || DEFAULT_INDICATOR_SETTINGS.dmiOversold,
    dmiOverboughtEnabled: loadBoolean('dmiOverboughtEnabled', DEFAULT_INDICATOR_SETTINGS.dmiOverboughtEnabled),
    dmiMiddleEnabled: loadBoolean('dmiMiddleEnabled', DEFAULT_INDICATOR_SETTINGS.dmiMiddleEnabled),
    dmiOversoldEnabled: loadBoolean('dmiOversoldEnabled', DEFAULT_INDICATOR_SETTINGS.dmiOversoldEnabled),
    
    // 8. OBV
    obvPeriod: Number(localStorage.getItem('obvPeriod')) || DEFAULT_INDICATOR_SETTINGS.obvPeriod,
    obvSignalPeriod: Number(localStorage.getItem('obvSignalPeriod')) || DEFAULT_INDICATOR_SETTINGS.obvSignalPeriod,
    
    // 9. RSI
    rsiPeriod: Number(localStorage.getItem('rsiPeriod')) || DEFAULT_INDICATOR_SETTINGS.rsiPeriod,
    rsiSignalPeriod: Number(localStorage.getItem('rsiSignalPeriod')) || DEFAULT_INDICATOR_SETTINGS.rsiSignalPeriod,
    rsiOversold: Number(localStorage.getItem('rsiOversold')) || DEFAULT_INDICATOR_SETTINGS.rsiOversold,
    rsiMiddle: Number(localStorage.getItem('rsiMiddle')) || DEFAULT_INDICATOR_SETTINGS.rsiMiddle,
    rsiOverbought: Number(localStorage.getItem('rsiOverbought')) || DEFAULT_INDICATOR_SETTINGS.rsiOverbought,
    
    // 10. Stochastic
    stochasticKPeriod: Number(localStorage.getItem('stochasticKPeriod')) || DEFAULT_INDICATOR_SETTINGS.stochasticKPeriod,
    stochasticDPeriod: Number(localStorage.getItem('stochasticDPeriod')) || DEFAULT_INDICATOR_SETTINGS.stochasticDPeriod,
    stochasticSlowing: Number(localStorage.getItem('stochasticSlowing')) || DEFAULT_INDICATOR_SETTINGS.stochasticSlowing,
    stochasticOversold: Number(localStorage.getItem('stochasticOversold')) || DEFAULT_INDICATOR_SETTINGS.stochasticOversold,
    stochasticOverbought: Number(localStorage.getItem('stochasticOverbought')) || DEFAULT_INDICATOR_SETTINGS.stochasticOverbought,
    stochasticNeutral: Number(localStorage.getItem('stochasticNeutral')) || DEFAULT_INDICATOR_SETTINGS.stochasticNeutral,
    
    // 11. Williams %R
    williamsRPeriod: Number(localStorage.getItem('williamsRPeriod')) || DEFAULT_INDICATOR_SETTINGS.williamsRPeriod,
    williamsREnabled: true,  // 항상 true
    williamsROversold: williamsROversold,
    williamsRMiddle: williamsRMiddle,
    williamsROverbought: williamsROverbought,
    williamsROversoldEnabled: localStorage.getItem('williamsROversoldEnabled') === 'true' || DEFAULT_INDICATOR_SETTINGS.williamsROversoldEnabled,
    williamsRMiddleEnabled: localStorage.getItem('williamsRMiddleEnabled') === 'true' || DEFAULT_INDICATOR_SETTINGS.williamsRMiddleEnabled,
    williamsROverboughtEnabled: localStorage.getItem('williamsROverboughtEnabled') === 'true' || DEFAULT_INDICATOR_SETTINGS.williamsROverboughtEnabled,
    
    // 12. TRIX
    trixPeriod: Number(localStorage.getItem('trixPeriod')) || DEFAULT_INDICATOR_SETTINGS.trixPeriod,
    trixSignalPeriod: Number(localStorage.getItem('trixSignalPeriod')) || DEFAULT_INDICATOR_SETTINGS.trixSignalPeriod,
    trixOversold: Number(localStorage.getItem('trixOversold')) || DEFAULT_INDICATOR_SETTINGS.trixOversold,
    trixMiddle: Number(localStorage.getItem('trixMiddle')) || DEFAULT_INDICATOR_SETTINGS.trixMiddle,
    trixOverbought: Number(localStorage.getItem('trixOverbought')) || DEFAULT_INDICATOR_SETTINGS.trixOverbought,
    
    // 13. VolumeOSC
    volumeOscShortPeriod: Number(localStorage.getItem('volumeOscShortPeriod')) || DEFAULT_INDICATOR_SETTINGS.volumeOscShortPeriod,
    volumeOscLongPeriod: Number(localStorage.getItem('volumeOscLongPeriod')) || DEFAULT_INDICATOR_SETTINGS.volumeOscLongPeriod,
    
    // 14. VR
    vrPeriod: Number(localStorage.getItem('vrPeriod')) || DEFAULT_INDICATOR_SETTINGS.vrPeriod,
    vrOverbought: Number(localStorage.getItem('vrOverbought')) || DEFAULT_INDICATOR_SETTINGS.vrOverbought,
    vrBaseLine: Number(localStorage.getItem('vrBaseLine')) || DEFAULT_INDICATOR_SETTINGS.vrBaseLine,
    vrOversold: Number(localStorage.getItem('vrOversold')) || DEFAULT_INDICATOR_SETTINGS.vrOversold,
    // VR2 통합 설정
    vr2Period: Number(localStorage.getItem('vr2Period')) || DEFAULT_INDICATOR_SETTINGS.vr2Period,
    
    // 15. 이격도
    disparityUltraShortPeriod: Number(localStorage.getItem('disparityUltraShortPeriod')) || DEFAULT_INDICATOR_SETTINGS.disparityUltraShortPeriod,
    disparityShortPeriod: Number(localStorage.getItem('disparityShortPeriod')) || DEFAULT_INDICATOR_SETTINGS.disparityShortPeriod,
    disparityMidPeriod: Number(localStorage.getItem('disparityMidPeriod')) || DEFAULT_INDICATOR_SETTINGS.disparityMidPeriod,
    disparityLongPeriod: Number(localStorage.getItem('disparityLongPeriod')) || DEFAULT_INDICATOR_SETTINGS.disparityLongPeriod,
    
    // 16. Momentum
    momentumPeriod: Number(localStorage.getItem('momentumPeriod')) || DEFAULT_INDICATOR_SETTINGS.momentumPeriod,
    
    // Enable/Disable flags for all indicator lines and reference lines
    // 1. 신심리도
    newPsychologicalEnabled: loadBoolean('newPsychologicalEnabled', DEFAULT_INDICATOR_SETTINGS.newPsychologicalEnabled),
    newPsychologicalOverboughtEnabled: loadBoolean('newPsychologicalOverboughtEnabled', DEFAULT_INDICATOR_SETTINGS.newPsychologicalOverboughtEnabled),
    newPsychologicalMiddleEnabled: loadBoolean('newPsychologicalMiddleEnabled', DEFAULT_INDICATOR_SETTINGS.newPsychologicalMiddleEnabled),
    newPsychologicalOversoldEnabled: loadBoolean('newPsychologicalOversoldEnabled', DEFAULT_INDICATOR_SETTINGS.newPsychologicalOversoldEnabled),
    
    // 2. 투자심리도
    investPsychologicalEnabled: loadBoolean('investPsychologicalEnabled', DEFAULT_INDICATOR_SETTINGS.investPsychologicalEnabled),
    investPsychologicalOverboughtEnabled: loadBoolean('investPsychologicalOverboughtEnabled', DEFAULT_INDICATOR_SETTINGS.investPsychologicalOverboughtEnabled),
    investPsychologicalMiddleEnabled: loadBoolean('investPsychologicalMiddleEnabled', DEFAULT_INDICATOR_SETTINGS.investPsychologicalMiddleEnabled),
    investPsychologicalOversoldEnabled: loadBoolean('investPsychologicalOversoldEnabled', DEFAULT_INDICATOR_SETTINGS.investPsychologicalOversoldEnabled),
    
    // 3. MACD
    macdZeroLineEnabled: loadBoolean('macdZeroLineEnabled', DEFAULT_INDICATOR_SETTINGS.macdZeroLineEnabled),
    histogramPositiveEnabled: loadBoolean('histogramPositiveEnabled', DEFAULT_INDICATOR_SETTINGS.histogramPositiveEnabled),
    histogramNegativeEnabled: loadBoolean('histogramNegativeEnabled', DEFAULT_INDICATOR_SETTINGS.histogramNegativeEnabled),
    
    // 4. CCI
    cciSignalEnabled: loadBoolean('cciSignalEnabled', DEFAULT_INDICATOR_SETTINGS.cciSignalEnabled),
    cciOverboughtEnabled: loadBoolean('cciOverboughtEnabled', DEFAULT_INDICATOR_SETTINGS.cciOverboughtEnabled),
    cciMiddleEnabled: loadBoolean('cciMiddleEnabled', DEFAULT_INDICATOR_SETTINGS.cciMiddleEnabled),
    cciOversoldEnabled: loadBoolean('cciOversoldEnabled', DEFAULT_INDICATOR_SETTINGS.cciOversoldEnabled),
    
    // 5. ADX
    adxStrongEnabled: loadBoolean('adxStrongEnabled', DEFAULT_INDICATOR_SETTINGS.adxStrongEnabled),
    adxWeakEnabled: loadBoolean('adxWeakEnabled', DEFAULT_INDICATOR_SETTINGS.adxWeakEnabled),
    
    // 6. BWI
    bwiEnabled: loadBoolean('bwiEnabled', DEFAULT_INDICATOR_SETTINGS.bwiEnabled),
    bwiOverboughtEnabled: loadBoolean('bwiOverboughtEnabled', DEFAULT_INDICATOR_SETTINGS.bwiOverboughtEnabled),
    bwiMiddleEnabled: loadBoolean('bwiMiddleEnabled', DEFAULT_INDICATOR_SETTINGS.bwiMiddleEnabled),
    bwiOversoldEnabled: loadBoolean('bwiOversoldEnabled', DEFAULT_INDICATOR_SETTINGS.bwiOversoldEnabled),
    
    // 8. OBV
    obvEnabled: loadBoolean('obvEnabled', DEFAULT_INDICATOR_SETTINGS.obvEnabled),
    obvSignalEnabled: loadBoolean('obvSignalEnabled', DEFAULT_INDICATOR_SETTINGS.obvSignalEnabled),
    
    // 9. RSI
    rsiSignalEnabled: loadBoolean('rsiSignalEnabled', DEFAULT_INDICATOR_SETTINGS.rsiSignalEnabled),
    rsiOverboughtEnabled: loadBoolean('rsiOverboughtEnabled', DEFAULT_INDICATOR_SETTINGS.rsiOverboughtEnabled),
    rsiMiddleEnabled: loadBoolean('rsiMiddleEnabled', DEFAULT_INDICATOR_SETTINGS.rsiMiddleEnabled),
    rsiOversoldEnabled: loadBoolean('rsiOversoldEnabled', DEFAULT_INDICATOR_SETTINGS.rsiOversoldEnabled),
    
    // 10. Stochastic
    stochasticOversoldEnabled: loadBoolean('stochasticOversoldEnabled', DEFAULT_INDICATOR_SETTINGS.stochasticOversoldEnabled),
    stochasticNeutralEnabled: loadBoolean('stochasticNeutralEnabled', DEFAULT_INDICATOR_SETTINGS.stochasticNeutralEnabled),
    stochasticOverboughtEnabled: loadBoolean('stochasticOverboughtEnabled', DEFAULT_INDICATOR_SETTINGS.stochasticOverboughtEnabled),
    
    // 12. TRIX
    trixEnabled: loadBoolean('trixEnabled', DEFAULT_INDICATOR_SETTINGS.trixEnabled),
    trixOverboughtEnabled: loadBoolean('trixOverboughtEnabled', DEFAULT_INDICATOR_SETTINGS.trixOverboughtEnabled),
    trixMiddleEnabled: loadBoolean('trixMiddleEnabled', DEFAULT_INDICATOR_SETTINGS.trixMiddleEnabled),
    trixOversoldEnabled: loadBoolean('trixOversoldEnabled', DEFAULT_INDICATOR_SETTINGS.trixOversoldEnabled),
    
    // 13. VolumeOSC
    volumeOscEnabled: loadBoolean('volumeOscEnabled', DEFAULT_INDICATOR_SETTINGS.volumeOscEnabled),
    volumeOscZeroLineEnabled: loadBoolean('volumeOscZeroLineEnabled', DEFAULT_INDICATOR_SETTINGS.volumeOscZeroLineEnabled),
    
    // 14. VR
    vrEnabled: loadBoolean('vrEnabled', DEFAULT_INDICATOR_SETTINGS.vrEnabled),
    vrOverboughtEnabled: loadBoolean('vrOverboughtEnabled', DEFAULT_INDICATOR_SETTINGS.vrOverboughtEnabled),
    vrBaseLineEnabled: loadBoolean('vrBaseLineEnabled', DEFAULT_INDICATOR_SETTINGS.vrBaseLineEnabled),
    vrOversoldEnabled: loadBoolean('vrOversoldEnabled', DEFAULT_INDICATOR_SETTINGS.vrOversoldEnabled),
    // VR2 통합 설정
    vr2Enabled: loadBoolean('vr2Enabled', DEFAULT_INDICATOR_SETTINGS.vr2Enabled),
    
    // 15. 이격도
    disparityEnabled: loadBoolean('disparityEnabled', DEFAULT_INDICATOR_SETTINGS.disparityEnabled),
    disparityUltraShortEnabled: loadBoolean('disparityUltraShortEnabled', DEFAULT_INDICATOR_SETTINGS.disparityUltraShortEnabled),
    disparityShortEnabled: loadBoolean('disparityShortEnabled', DEFAULT_INDICATOR_SETTINGS.disparityShortEnabled),
    disparityMidEnabled: loadBoolean('disparityMidEnabled', DEFAULT_INDICATOR_SETTINGS.disparityMidEnabled),
    disparityLongEnabled: loadBoolean('disparityLongEnabled', DEFAULT_INDICATOR_SETTINGS.disparityLongEnabled),
    disparityBaseLineEnabled: loadBoolean('disparityBaseLineEnabled', DEFAULT_INDICATOR_SETTINGS.disparityBaseLineEnabled),
    
    // 16. Momentum
    momentumEnabled: loadBoolean('momentumEnabled', DEFAULT_INDICATOR_SETTINGS.momentumEnabled),
    momentumZeroLineEnabled: loadBoolean('momentumZeroLineEnabled', DEFAULT_INDICATOR_SETTINGS.momentumZeroLineEnabled),
    
    // 17. Volume
    volumeRisingEnabled: loadBoolean('volumeRisingEnabled', DEFAULT_INDICATOR_SETTINGS.volumeRisingEnabled),
    volumeFallingEnabled: loadBoolean('volumeFallingEnabled', DEFAULT_INDICATOR_SETTINGS.volumeFallingEnabled),
  };
};

// localStorage에 설정 저장
export const saveIndicatorSettingsToStorage = (settings: IndicatorSettings): void => {
  // 지표 활성화 여부
  localStorage.setItem('macdEnabled', String(settings.macdEnabled));
  localStorage.setItem('stochasticEnabled', String(settings.stochasticEnabled));
  localStorage.setItem('rsiEnabled', String(settings.rsiEnabled));
  localStorage.setItem('cciEnabled', String(settings.cciEnabled));
  localStorage.setItem('adxEnabled', String(settings.adxEnabled));
  
  // 1. 신심리도
  localStorage.setItem('newPsychologicalPeriod', String(settings.newPsychologicalPeriod));
  localStorage.setItem('newPsychologicalOverbought', String(settings.newPsychologicalOverbought));
  localStorage.setItem('newPsychologicalMiddle', String(settings.newPsychologicalMiddle));
  localStorage.setItem('newPsychologicalOversold', String(settings.newPsychologicalOversold));
  
  // 2. 투자심리도
  localStorage.setItem('investPsychologicalPeriod', String(settings.investPsychologicalPeriod));
  localStorage.setItem('investPsychologicalOverbought', String(settings.investPsychologicalOverbought));
  localStorage.setItem('investPsychologicalMiddle', String(settings.investPsychologicalMiddle));
  localStorage.setItem('investPsychologicalOversold', String(settings.investPsychologicalOversold));
  
  // 3. MACD
  localStorage.setItem('macdFastPeriod', String(settings.macdFastPeriod));
  localStorage.setItem('macdSlowPeriod', String(settings.macdSlowPeriod));
  localStorage.setItem('macdSignalPeriod', String(settings.macdSignalPeriod));
  
  // 4. CCI
  localStorage.setItem('cciPeriod', String(settings.cciPeriod));
  localStorage.setItem('cciSignalPeriod', String(settings.cciSignalPeriod));
  localStorage.setItem('cciOversold', String(settings.cciOversold));
  localStorage.setItem('cciMiddle', String(settings.cciMiddle));
  localStorage.setItem('cciOverbought', String(settings.cciOverbought));
  
  // 5. ADX
  localStorage.setItem('adxPeriod', String(settings.adxPeriod));
  localStorage.setItem('adxStrongThreshold', String(settings.adxStrongThreshold));
  localStorage.setItem('adxWeakThreshold', String(settings.adxWeakThreshold));
  
  // 6. BWI
  localStorage.setItem('bwiPeriod', String(settings.bwiPeriod));
  localStorage.setItem('bwiOverbought', String(settings.bwiOverbought));
  localStorage.setItem('bwiMiddle', String(settings.bwiMiddle));
  localStorage.setItem('bwiOversold', String(settings.bwiOversold));
  
  // 7. DMI
  localStorage.setItem('dmiPeriod', String(settings.dmiPeriod));
  localStorage.setItem('dmiEnabled', String(settings.dmiEnabled));
  localStorage.setItem('plusDiEnabled', String(settings.plusDiEnabled));
  localStorage.setItem('minusDiEnabled', String(settings.minusDiEnabled));
  localStorage.setItem('dmiOverbought', String(settings.dmiOverbought));
  localStorage.setItem('dmiMiddle', String(settings.dmiMiddle));
  localStorage.setItem('dmiOversold', String(settings.dmiOversold));
  localStorage.setItem('dmiOverboughtEnabled', String(settings.dmiOverboughtEnabled));
  localStorage.setItem('dmiMiddleEnabled', String(settings.dmiMiddleEnabled));
  localStorage.setItem('dmiOversoldEnabled', String(settings.dmiOversoldEnabled));
  
  // 8. OBV
  localStorage.setItem('obvPeriod', String(settings.obvPeriod));
  localStorage.setItem('obvSignalPeriod', String(settings.obvSignalPeriod));
  
  // 9. RSI
  localStorage.setItem('rsiPeriod', String(settings.rsiPeriod));
  localStorage.setItem('rsiSignalPeriod', String(settings.rsiSignalPeriod));
  localStorage.setItem('rsiOversold', String(settings.rsiOversold));
  localStorage.setItem('rsiMiddle', String(settings.rsiMiddle));
  localStorage.setItem('rsiOverbought', String(settings.rsiOverbought));
  
  // 10. Stochastic
  localStorage.setItem('stochasticKPeriod', String(settings.stochasticKPeriod));
  localStorage.setItem('stochasticDPeriod', String(settings.stochasticDPeriod));
  localStorage.setItem('stochasticSlowing', String(settings.stochasticSlowing));
  localStorage.setItem('stochasticOversold', String(settings.stochasticOversold));
  localStorage.setItem('stochasticOverbought', String(settings.stochasticOverbought));
  localStorage.setItem('stochasticNeutral', String(settings.stochasticNeutral));
  
  // 11. Williams %R
  localStorage.setItem('williamsRPeriod', String(settings.williamsRPeriod));
  localStorage.setItem('williamsROversold', String(settings.williamsROversold));
  localStorage.setItem('williamsRMiddle', String(settings.williamsRMiddle));
  localStorage.setItem('williamsROverbought', String(settings.williamsROverbought));
  localStorage.setItem('williamsREnabled', String(settings.williamsREnabled));
  localStorage.setItem('williamsROversoldEnabled', String(settings.williamsROversoldEnabled));
  localStorage.setItem('williamsRMiddleEnabled', String(settings.williamsRMiddleEnabled));
  localStorage.setItem('williamsROverboughtEnabled', String(settings.williamsROverboughtEnabled));
  
  // 12. TRIX
  localStorage.setItem('trixPeriod', String(settings.trixPeriod));
  localStorage.setItem('trixSignalPeriod', String(settings.trixSignalPeriod));
  localStorage.setItem('trixOversold', String(settings.trixOversold));
  localStorage.setItem('trixMiddle', String(settings.trixMiddle));
  localStorage.setItem('trixOverbought', String(settings.trixOverbought));
  
  // 13. VolumeOSC
  localStorage.setItem('volumeOscShortPeriod', String(settings.volumeOscShortPeriod));
  localStorage.setItem('volumeOscLongPeriod', String(settings.volumeOscLongPeriod));
  
  // 14. VR
  localStorage.setItem('vrPeriod', String(settings.vrPeriod));
  localStorage.setItem('vrOverbought', String(settings.vrOverbought));
  localStorage.setItem('vrBaseLine', String(settings.vrBaseLine));
  localStorage.setItem('vrOversold', String(settings.vrOversold));
  // VR2 통합 설정
  localStorage.setItem('vr2Period', String(settings.vr2Period));
  
  // 15. 이격도
  localStorage.setItem('disparityUltraShortPeriod', String(settings.disparityUltraShortPeriod));
  localStorage.setItem('disparityShortPeriod', String(settings.disparityShortPeriod));
  localStorage.setItem('disparityMidPeriod', String(settings.disparityMidPeriod));
  localStorage.setItem('disparityLongPeriod', String(settings.disparityLongPeriod));
  
  // Enable/Disable flags for all indicator lines and reference lines
  // 1. 신심리도
  localStorage.setItem('newPsychologicalEnabled', String(settings.newPsychologicalEnabled));
  localStorage.setItem('newPsychologicalOverboughtEnabled', String(settings.newPsychologicalOverboughtEnabled));
  localStorage.setItem('newPsychologicalMiddleEnabled', String(settings.newPsychologicalMiddleEnabled));
  localStorage.setItem('newPsychologicalOversoldEnabled', String(settings.newPsychologicalOversoldEnabled));
  
  // 2. 투자심리도
  localStorage.setItem('investPsychologicalEnabled', String(settings.investPsychologicalEnabled));
  localStorage.setItem('investPsychologicalOverboughtEnabled', String(settings.investPsychologicalOverboughtEnabled));
  localStorage.setItem('investPsychologicalMiddleEnabled', String(settings.investPsychologicalMiddleEnabled));
  localStorage.setItem('investPsychologicalOversoldEnabled', String(settings.investPsychologicalOversoldEnabled));
  
  // 3. MACD
  localStorage.setItem('macdZeroLineEnabled', String(settings.macdZeroLineEnabled));
  
  // 4. CCI
  localStorage.setItem('cciSignalEnabled', String(settings.cciSignalEnabled));
  localStorage.setItem('cciOverboughtEnabled', String(settings.cciOverboughtEnabled));
  localStorage.setItem('cciMiddleEnabled', String(settings.cciMiddleEnabled));
  localStorage.setItem('cciOversoldEnabled', String(settings.cciOversoldEnabled));
  
  // 5. ADX
  localStorage.setItem('adxStrongEnabled', String(settings.adxStrongEnabled));
  localStorage.setItem('adxWeakEnabled', String(settings.adxWeakEnabled));
  
  // 6. BWI
  localStorage.setItem('bwiEnabled', String(settings.bwiEnabled));
  localStorage.setItem('bwiOverboughtEnabled', String(settings.bwiOverboughtEnabled));
  localStorage.setItem('bwiMiddleEnabled', String(settings.bwiMiddleEnabled));
  localStorage.setItem('bwiOversoldEnabled', String(settings.bwiOversoldEnabled));
  
  // 8. OBV
  localStorage.setItem('obvEnabled', String(settings.obvEnabled));
  localStorage.setItem('obvSignalEnabled', String(settings.obvSignalEnabled));
  
  // 9. RSI
  localStorage.setItem('rsiSignalEnabled', String(settings.rsiSignalEnabled));
  localStorage.setItem('rsiOverboughtEnabled', String(settings.rsiOverboughtEnabled));
  localStorage.setItem('rsiMiddleEnabled', String(settings.rsiMiddleEnabled));
  localStorage.setItem('rsiOversoldEnabled', String(settings.rsiOversoldEnabled));
  
  // 10. Stochastic
  localStorage.setItem('stochasticOversoldEnabled', String(settings.stochasticOversoldEnabled));
  localStorage.setItem('stochasticNeutralEnabled', String(settings.stochasticNeutralEnabled));
  localStorage.setItem('stochasticOverboughtEnabled', String(settings.stochasticOverboughtEnabled));
  
  // 12. TRIX
  localStorage.setItem('trixOverboughtEnabled', String(settings.trixOverboughtEnabled));
  localStorage.setItem('trixMiddleEnabled', String(settings.trixMiddleEnabled));
  localStorage.setItem('trixOversoldEnabled', String(settings.trixOversoldEnabled));
  
  // 13. VolumeOSC
  localStorage.setItem('volumeOscEnabled', String(settings.volumeOscEnabled));
  localStorage.setItem('volumeOscZeroLineEnabled', String(settings.volumeOscZeroLineEnabled));
  
  // 14. VR
  localStorage.setItem('vrEnabled', String(settings.vrEnabled));
  localStorage.setItem('vrOverboughtEnabled', String(settings.vrOverboughtEnabled));
  localStorage.setItem('vrBaseLineEnabled', String(settings.vrBaseLineEnabled));
  localStorage.setItem('vrOversoldEnabled', String(settings.vrOversoldEnabled));
  // VR2 통합 설정
  localStorage.setItem('vr2Enabled', String(settings.vr2Enabled));
  
  // 15. 이격도
  localStorage.setItem('disparityUltraShortEnabled', String(settings.disparityUltraShortEnabled));
  localStorage.setItem('disparityShortEnabled', String(settings.disparityShortEnabled));
  localStorage.setItem('disparityMidEnabled', String(settings.disparityMidEnabled));
  localStorage.setItem('disparityLongEnabled', String(settings.disparityLongEnabled));
  localStorage.setItem('disparityBaseLineEnabled', String(settings.disparityBaseLineEnabled));
  
  // 16. Momentum
  localStorage.setItem('momentumPeriod', String(settings.momentumPeriod));
  localStorage.setItem('momentumEnabled', String(settings.momentumEnabled));
  localStorage.setItem('momentumZeroLineEnabled', String(settings.momentumZeroLineEnabled));
  
  // 17. Volume
  localStorage.setItem('volumeRisingEnabled', String(settings.volumeRisingEnabled));
  localStorage.setItem('volumeFallingEnabled', String(settings.volumeFallingEnabled));
};

// 사용자 정의 기준선 localStorage 키
const CUSTOM_REFERENCE_LINES_KEY = 'customReferenceLines';

// 기본 기준선 정의 (업비트 스타일)
const DEFAULT_REFERENCE_LINES: CustomReferenceLines = {
  rsi: [
    { id: 'rsi_oversold', name: '과매도', value: 30, color: '#2196f3', lineStyle: 'dashed' },
    { id: 'rsi_middle', name: '중립', value: 50, color: '#9e9e9e', lineStyle: 'dotted' },
    { id: 'rsi_overbought', name: '과매수', value: 70, color: '#f44336', lineStyle: 'dashed' },
  ],
  stochastic: [
    { id: 'stoch_oversold', name: '과매도', value: 20, color: '#2196f3', lineStyle: 'dashed' },
    { id: 'stoch_middle', name: '중립', value: 50, color: '#9e9e9e', lineStyle: 'dotted' },
    { id: 'stoch_overbought', name: '과매수', value: 80, color: '#f44336', lineStyle: 'dashed' },
  ],
  cci: [
    { id: 'cci_oversold', name: '과매도', value: -100, color: '#2196f3', lineStyle: 'dashed' },
    { id: 'cci_middle', name: '중립', value: 0, color: '#9e9e9e', lineStyle: 'solid' },
    { id: 'cci_overbought', name: '과매수', value: 100, color: '#f44336', lineStyle: 'dashed' },
  ],
  williamsR: [
    { id: 'wr_overbought', name: '과매수', value: -20, color: '#f44336', lineStyle: 'dashed' },
    { id: 'wr_middle', name: '중립', value: -50, color: '#9e9e9e', lineStyle: 'dotted' },
    { id: 'wr_oversold', name: '과매도', value: -80, color: '#2196f3', lineStyle: 'dashed' },
  ],
  bwi: [
    { id: 'bwi_oversold', name: '과매도', value: 0, color: '#2196f3', lineStyle: 'dashed' },
    { id: 'bwi_middle', name: '중립', value: 0.5, color: '#9e9e9e', lineStyle: 'dotted' },
    { id: 'bwi_overbought', name: '과매수', value: 1, color: '#f44336', lineStyle: 'dashed' },
  ],
  adx: [
    { id: 'adx_weak', name: '약한 추세', value: 25, color: '#ff9800', lineStyle: 'dashed' },
    { id: 'adx_strong', name: '강한 추세', value: 40, color: '#4caf50', lineStyle: 'dashed' },
  ],
  newPsychological: [
    { id: 'newpsy_oversold', name: '침체', value: 25, color: '#2196f3', lineStyle: 'dashed' },
    { id: 'newpsy_middle', name: '중립', value: 50, color: '#9e9e9e', lineStyle: 'dotted' },
    { id: 'newpsy_overbought', name: '과열', value: 75, color: '#f44336', lineStyle: 'dashed' },
  ],
  investPsychological: [
    { id: 'invpsy_oversold', name: '침체', value: 25, color: '#2196f3', lineStyle: 'dashed' },
    { id: 'invpsy_middle', name: '중립', value: 50, color: '#9e9e9e', lineStyle: 'dotted' },
    { id: 'invpsy_overbought', name: '과열', value: 75, color: '#f44336', lineStyle: 'dashed' },
  ],
  trix: [
    { id: 'trix_zero', name: '0선', value: 0, color: '#9e9e9e', lineStyle: 'solid' },
  ],
  macd: [
    { id: 'macd_zero', name: '0선', value: 0, color: '#9e9e9e', lineStyle: 'solid' },
  ],
  dmi: [
    { id: 'dmi_low', name: '약세', value: 20, color: '#2196f3', lineStyle: 'dotted' },
    { id: 'dmi_middle', name: '중립', value: 40, color: '#9e9e9e', lineStyle: 'dotted' },
    { id: 'dmi_high', name: '강세', value: 60, color: '#f44336', lineStyle: 'dotted' },
  ],
  disparity: [
    { id: 'disp_oversold', name: '과매도', value: 98, color: '#2196f3', lineStyle: 'dashed' },
    { id: 'disp_middle', name: '중립', value: 100, color: '#9e9e9e', lineStyle: 'solid' },
    { id: 'disp_overbought', name: '과매수', value: 102, color: '#f44336', lineStyle: 'dashed' },
  ],
  obv: [],
  volumeOsc: [
    { id: 'volosc_zero', name: '0선', value: 0, color: '#9e9e9e', lineStyle: 'solid' },
  ],
  vr: [
    { id: 'vr_oversold', name: '침체', value: 70, color: '#2196f3', lineStyle: 'dashed' },
    { id: 'vr_low', name: '약세', value: 100, color: '#ff9800', lineStyle: 'dotted' },
    { id: 'vr_middle', name: '중립', value: 150, color: '#9e9e9e', lineStyle: 'dotted' },
    { id: 'vr_high', name: '강세', value: 200, color: '#4caf50', lineStyle: 'dotted' },
    { id: 'vr_overbought', name: '과열', value: 300, color: '#f44336', lineStyle: 'dashed' },
  ],
};

// 사용자 정의 기준선 불러오기
export const loadCustomReferenceLinesFromStorage = (): CustomReferenceLines => {
  try {
    const stored = localStorage.getItem(CUSTOM_REFERENCE_LINES_KEY);
    if (stored) {
      const parsed = JSON.parse(stored);
      // 기존 저장된 데이터가 있으면 반환 (사용자가 수정한 내용 유지)
      return parsed;
    }
  } catch (e) {
    console.error('사용자 정의 기준선 불러오기 실패:', e);
  }
  // 저장된 데이터가 없으면 기본 기준선 반환
  return DEFAULT_REFERENCE_LINES;
};

// 사용자 정의 기준선 저장
export const saveCustomReferenceLinesStorage = (lines: CustomReferenceLines): void => {
  try {
    localStorage.setItem(CUSTOM_REFERENCE_LINES_KEY, JSON.stringify(lines));
  } catch (e) {
    console.error('사용자 정의 기준선 저장 실패:', e);
  }
};

interface IndicatorSettingsContextType {
  indicatorSettings: IndicatorSettings;
  updateIndicatorSettings: (newSettings: Partial<IndicatorSettings>) => void;
  saveIndicatorSettings: (settings: IndicatorSettings) => void;
  resetIndicatorSettings: () => void;
  // ✅ 설정 변경 알림 메커니즘
  settingsVersion: number;  // 설정이 변경될 때마다 +1
  onSettingsChange: (callback: (settings: IndicatorSettings) => void) => () => void;
  // ✅ 최신 설정값을 동기적으로 읽기 위한 ref (API 호출 시 사용)
  getLatestSettings: () => IndicatorSettings;
  // 사용자 정의 기준선 관리
  customReferenceLines: CustomReferenceLines;
  addCustomReferenceLine: (indicatorType: string, line: Omit<CustomReferenceLine, 'id'>) => void;
  updateCustomReferenceLine: (indicatorType: string, lineId: string, updates: Partial<CustomReferenceLine>) => void;
  removeCustomReferenceLine: (indicatorType: string, lineId: string) => void;
  getCustomReferenceLines: (indicatorType: string) => CustomReferenceLine[];
  // 기준선 DB 저장
  saveCustomReferenceLinesDB: () => Promise<void>;
  loadCustomReferenceLinesDB: () => Promise<void>;
}

const IndicatorSettingsContext = createContext<IndicatorSettingsContextType | undefined>(undefined);

// UUID 생성 함수
const generateId = (): string => {
  return `ref_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
};

export const IndicatorSettingsProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  // ✅ 초기값은 localStorage 캐시에서 읽기 (DB 로드 전까지 사용)
  const [indicatorSettings, setIndicatorSettings] = useState<IndicatorSettings>(loadIndicatorSettingsFromStorage);
  const [customReferenceLines, setCustomReferenceLines] = useState<CustomReferenceLines>(loadCustomReferenceLinesFromStorage);
  const [isLoaded, setIsLoaded] = useState(false);
  
  // ✅ 설정 변경 알림 메커니즘
  const [settingsVersion, setSettingsVersion] = useState(0);
  const listenersRef = useRef<Set<(settings: IndicatorSettings) => void>>(new Set());
  
  // DB 저장 debounce를 위한 타이머
  const saveTimerRef = useRef<NodeJS.Timeout | null>(null);
  const periodsSaveTimerRef = useRef<NodeJS.Timeout | null>(null);
  
  // ✅ 최신 상태를 ref로 유지 (동기적 읽기 가능 - API 호출 시 사용)
  const customReferenceLinesRef = useRef<CustomReferenceLines>(customReferenceLines);
  const indicatorSettingsRef = useRef<IndicatorSettings>(indicatorSettings);
  
  useEffect(() => {
    customReferenceLinesRef.current = customReferenceLines;
  }, [customReferenceLines]);
  
  useEffect(() => {
    indicatorSettingsRef.current = indicatorSettings;
    // ref 업데이트 시 localStorage 캐시도 즉시 동기화
    saveIndicatorSettingsToStorage(indicatorSettings);
  }, [indicatorSettings]);

  // Auth 상태 확인 (localStorage 기반)
  const getIsAuthenticated = useCallback(() => {
    return !!localStorage.getItem('accessToken');
  }, []);

  // ✅ DB에서 IndicatorSettings 로드 (주 저장소)
  const loadIndicatorSettingsDB = useCallback(async () => {
    try {
      const isAuth = getIsAuthenticated();
      let data: string;
      if (isAuth) {
        data = await getUserIndicatorPeriods();
      } else {
        data = await getGuestIndicatorPeriods();
      }
      
      if (data && data !== '{}') {
        const parsed = JSON.parse(data);
        // VR2 설정이 포함된 데이터를 병합
        const merged = { ...loadIndicatorSettingsFromStorage(), ...parsed };
        setIndicatorSettings(merged);
        // localStorage에도 캐시 (동기 읽기용)
        saveIndicatorSettingsToStorage(merged);
        console.log('✅ [loadIndicatorSettingsDB] DB에서 로드 및 캐시 저장 완료');
      } else {
        console.log('ℹ️ [loadIndicatorSettingsDB] DB에 데이터 없음 - 기본값 또는 캐시 사용');
      }
    } catch (error) {
      console.error('❌ [IndicatorSettings DB 로드] 실패 - localStorage 캐시 사용:', error);
      // DB 로드 실패 시 localStorage(캐시)에서 읽기
      const cachedSettings = loadIndicatorSettingsFromStorage();
      setIndicatorSettings(cachedSettings);
    }
  }, [getIsAuthenticated]);

  // DB에서 기준선 로드
  const loadCustomReferenceLinesDB = useCallback(async () => {
    try {
      const isAuth = getIsAuthenticated();
      let data: string;
      if (isAuth) {
        data = await getUserCustomReferenceLines();
      } else {
        data = await getGuestCustomReferenceLines();
      }
      
      if (data && data !== '{}') {
        const parsed = JSON.parse(data);
        // 빈 객체가 아닌 경우에만 설정
        if (Object.keys(parsed).length > 0) {
          setCustomReferenceLines(parsed);
          // localStorage에도 동기화
          saveCustomReferenceLinesStorage(parsed);
        } else {
          // DB에 빈 객체가 저장되어 있으면 기본값 사용
          setCustomReferenceLines(DEFAULT_REFERENCE_LINES);
          saveCustomReferenceLinesStorage(DEFAULT_REFERENCE_LINES);
        }
      } else {
        // DB에 데이터가 없으면 기본값 사용
        setCustomReferenceLines(DEFAULT_REFERENCE_LINES);
        saveCustomReferenceLinesStorage(DEFAULT_REFERENCE_LINES);
      }
      setIsLoaded(true);
    } catch (error) {
      console.error('기준선 DB 로드 실패:', error);
      // 로드 실패 시에도 기본값 사용
      const currentLines = loadCustomReferenceLinesFromStorage();
      if (Object.keys(currentLines).length === 0) {
        setCustomReferenceLines(DEFAULT_REFERENCE_LINES);
        saveCustomReferenceLinesStorage(DEFAULT_REFERENCE_LINES);
      }
      setIsLoaded(true);
    }
  }, [getIsAuthenticated]);

  // DB에 기준선 저장
  const saveCustomReferenceLinesDB = useCallback(async () => {
    try {
      const isAuth = getIsAuthenticated();
      const data = JSON.stringify(customReferenceLinesRef.current);
      if (isAuth) {
        await saveUserCustomReferenceLines(data);
      } else {
        await saveGuestCustomReferenceLines(data);
      }
    } catch (error: any) {
      // 403 에러는 게스트 권한 문제로 정상 - 조용히 무시
      if (error?.response?.status === 403) {
        return;
      }
      console.error('기준선 DB 저장 실패:', error);
    }
  }, [getIsAuthenticated]);

  // 마운트 시 초기화: localStorage가 비어있으면 기본값 설정
  useEffect(() => {
    const currentLines = loadCustomReferenceLinesFromStorage();
    if (Object.keys(currentLines).length === 0) {
      console.log('📏 기준선이 비어있음 - 기본값 설정');
      setCustomReferenceLines(DEFAULT_REFERENCE_LINES);
      saveCustomReferenceLinesStorage(DEFAULT_REFERENCE_LINES);
    }
  }, []); // 최초 마운트 시에만 실행

  // 마운트 시 DB에서 로드
  useEffect(() => {
    if (!isLoaded) {
      // IndicatorSettings와 기준선 모두 로드
      loadIndicatorSettingsDB();
      loadCustomReferenceLinesDB();
    }
  }, [isLoaded, loadIndicatorSettingsDB, loadCustomReferenceLinesDB]);

  // 기준선 변경 시 DB에 저장 (debounce 500ms)
  useEffect(() => {
    if (isLoaded) {
      if (saveTimerRef.current) {
        clearTimeout(saveTimerRef.current);
      }
      saveTimerRef.current = setTimeout(() => {
        saveCustomReferenceLinesDB();
      }, 500);
    }
    
    return () => {
      if (saveTimerRef.current) {
        clearTimeout(saveTimerRef.current);
      }
    };
  }, [customReferenceLines, isLoaded, saveCustomReferenceLinesDB]);

  const updateIndicatorSettings = useCallback((newSettings: Partial<IndicatorSettings>) => {
    setIndicatorSettings(prev => {
      const updated = { ...prev, ...newSettings };
      
      // ✅ DB에 저장 (주 저장소)
      const saveToDBAsync = async () => {
        try {
          const isAuth = getIsAuthenticated();
          const jsonString = JSON.stringify(updated);
          
          if (isAuth) {
            await saveUserIndicatorPeriods(jsonString);
          } else {
            await saveGuestIndicatorPeriods(jsonString);
          }
          
          // DB 저장 성공 시 localStorage에도 캐시 (동기 읽기용)
          saveIndicatorSettingsToStorage(updated);
          console.log('✅ [updateIndicatorSettings] DB 및 캐시 저장 완료');
        } catch (error) {
          console.error('❌ 보조지표 설정 DB 저장 실패 - localStorage만 업데이트:', error);
          // DB 저장 실패해도 localStorage는 업데이트 (fallback)
          saveIndicatorSettingsToStorage(updated);
        }
      };
      
      saveToDBAsync();
      
      return updated;
    });
    
    // ✅ 설정 버전 증가 (다음 틱에서 실행하여 paramSettings 업데이트 보장)
    setTimeout(() => {
      setSettingsVersion(prev => {
        console.log(`🔢 [updateIndicatorSettings] settingsVersion 증가: ${prev} → ${prev + 1}`, newSettings);
        return prev + 1;
      });
    }, 0);
  }, [getIsAuthenticated]);

  const saveIndicatorSettings = useCallback((settings: IndicatorSettings) => {
    setIndicatorSettings(settings);
    
    // ✅ DB에 저장 (주 저장소)
    const saveToDBAsync = async () => {
      try {
        const isAuth = getIsAuthenticated();
        const jsonString = JSON.stringify(settings);
        
        if (isAuth) {
          await saveUserIndicatorPeriods(jsonString);
        } else {
          await saveGuestIndicatorPeriods(jsonString);
        }
        
        // DB 저장 성공 시 localStorage에도 캐시
        saveIndicatorSettingsToStorage(settings);
        console.log('✅ [saveIndicatorSettings] DB 및 캐시 저장 완료');
      } catch (error) {
        console.error('❌ 보조지표 설정 DB 저장 실패 - localStorage만 업데이트:', error);
        // DB 저장 실패해도 localStorage는 업데이트 (fallback)
        saveIndicatorSettingsToStorage(settings);
      }
    };
    
    saveToDBAsync();
    
    // ✅ 설정 버전 증가 (다음 틱에서 실행하여 paramSettings 업데이트 보장)
    setTimeout(() => {
      setSettingsVersion(prev => {
        console.log(`🔢 [saveIndicatorSettings] settingsVersion 증가: ${prev} → ${prev + 1}`);
        return prev + 1;
      });
    }, 0);
  }, [getIsAuthenticated]);

  const resetIndicatorSettings = useCallback(() => {
    setIndicatorSettings(DEFAULT_INDICATOR_SETTINGS);
    saveIndicatorSettingsToStorage(DEFAULT_INDICATOR_SETTINGS);
    // 기준선도 기본값으로 초기화
    setCustomReferenceLines(DEFAULT_REFERENCE_LINES);
    saveCustomReferenceLinesStorage(DEFAULT_REFERENCE_LINES);
    // ✅ 설정 버전 증가 (변경 감지용)
    setSettingsVersion(prev => prev + 1);
  }, []);

  // 사용자 정의 기준선 추가
  const addCustomReferenceLine = useCallback((indicatorType: string, line: Omit<CustomReferenceLine, 'id'>) => {
    setCustomReferenceLines(prev => {
      const newLine: CustomReferenceLine = {
        ...line,
        id: generateId(),
      };
      const updated = {
        ...prev,
        [indicatorType]: [...(prev[indicatorType] || []), newLine],
      };
      saveCustomReferenceLinesStorage(updated);
      return updated;
    });
  }, []);

  // 사용자 정의 기준선 수정
  const updateCustomReferenceLine = useCallback((indicatorType: string, lineId: string, updates: Partial<CustomReferenceLine>) => {
    setCustomReferenceLines(prev => {
      const lines = prev[indicatorType] || [];
      const updated = {
        ...prev,
        [indicatorType]: lines.map(line => 
          line.id === lineId ? { ...line, ...updates } : line
        ),
      };
      saveCustomReferenceLinesStorage(updated);
      return updated;
    });
  }, []);

  // 사용자 정의 기준선 삭제
  const removeCustomReferenceLine = useCallback((indicatorType: string, lineId: string) => {
    setCustomReferenceLines(prev => {
      const lines = prev[indicatorType] || [];
      const updated = {
        ...prev,
        [indicatorType]: lines.filter(line => line.id !== lineId),
      };
      saveCustomReferenceLinesStorage(updated);
      return updated;
    });
  }, []);

  // 특정 지표의 사용자 정의 기준선 가져오기
  const getCustomReferenceLines = useCallback((indicatorType: string): CustomReferenceLine[] => {
    return customReferenceLines[indicatorType] || [];
  }, [customReferenceLines]);

  // ✅ 설정 변경 리스너 등록/해제
  const onSettingsChange = useCallback((callback: (settings: IndicatorSettings) => void) => {
    listenersRef.current.add(callback);
    
    // 등록 해제 함수 반환
    return () => {
      listenersRef.current.delete(callback);
    };
  }, []);

  // ✅ 최신 설정값을 동기적으로 읽기 위한 함수 (API 호출 시 사용)
  const getLatestSettings = useCallback(() => {
    return indicatorSettingsRef.current;
  }, []);

  // ✅ 설정이 변경될 때 모든 리스너에게 알림
  useEffect(() => {
    listenersRef.current.forEach(listener => {
      listener(indicatorSettings);
    });
  }, [indicatorSettings, settingsVersion]);

  return (
    <IndicatorSettingsContext.Provider
      value={{
        indicatorSettings,
        updateIndicatorSettings,
        saveIndicatorSettings,
        resetIndicatorSettings,
        settingsVersion,
        onSettingsChange,
        getLatestSettings,
        customReferenceLines,
        addCustomReferenceLine,
        updateCustomReferenceLine,
        removeCustomReferenceLine,
        getCustomReferenceLines,
        saveCustomReferenceLinesDB,
        loadCustomReferenceLinesDB,
      }}
    >
      {children}
    </IndicatorSettingsContext.Provider>
  );
};

export const useIndicatorSettings = () => {
  const context = useContext(IndicatorSettingsContext);
  if (!context) {
    throw new Error('useIndicatorSettings must be used within IndicatorSettingsProvider');
  }
  return context;
};
