import React from 'react';
import type { IndicatorConfig, HlinesBackground, Timeframe } from '../types';
import type { PlotDef, HLineDef } from '../utils/indicatorRegistry';
import { getHLineLabel } from '../utils/indicatorRegistry';
import { getParamLabel, getPlotLabel, getSrcOptionLabel } from '../utils/indicatorLabels';
import { getIchimokuPlotTitle } from '../utils/ichimokuConfig';
import {
  getNumericParamSpec,
  getHlinePriceSpec,
} from '../utils/indicatorParamSpec';
import {
  getGlobalParamKeys,
  getPlotParamKeys,
  plotParamsOnGlobalRowOnly,
  plotRowHasNoInputs,
} from '../utils/indicatorSettingsLayout';
import NumericParamInput from './NumericParamInput';
import PlotLineStylePicker from './PlotLineStylePicker';
import ColorInput from './ColorInput';
import { colorToRgbaString, cloudColorOpacityPercent } from '../utils/ichimokuConfig';
import { resolveHistogramUpColor, resolveHistogramDownColor } from '../utils/plotColorUtils';
import type { IchimokuCloudColors } from '../utils/ichimokuConfig';

const SRC_OPTIONS = ['close', 'open', 'high', 'low', 'hl2', 'hlc3', 'ohlc4'];

const MA_TYPE_OPTIONS_CCI = ['None', 'SMA', 'EMA', 'WMA'] as const;
const MA_TYPE_OPTIONS_OBV = ['SMA', 'EMA', 'WMA'] as const;

/** 업비트 OBV 드롭다운 표기 */
const OBV_MA_TYPE_LABELS: Record<string, string> = {
  SMA: '단순이동평균',
  EMA: '지수 이동 평균',
  WMA: '가중이동평균',
};

const MA_TYPE_LABELS: Record<string, string> = {
  None: '없음 (None)',
  SMA:  '단순이동평균 (SMA)',
  EMA:  '지수이동평균 (EMA)',
  WMA:  '가중이동평균 (WMA)',
  'SMMA (RMA)': 'RMA (SMMA)',
  VWMA: '거래량가중이동평균 (VWMA)',
};

function isMaTypeParam(indicatorType: string, key: string, value: unknown): boolean {
  if (key !== 'maType' || typeof value !== 'string') return false;
  return indicatorType === 'CCI' || indicatorType === 'OBV' || indicatorType === 'RSI';
}

function maTypeOptionsFor(indicatorType: string): readonly string[] {
  if (indicatorType === 'OBV') return MA_TYPE_OPTIONS_OBV;
  return MA_TYPE_OPTIONS_CCI;
}

function isSrcParam(key: string, value: unknown): boolean {
  return (key === 'src' || key.toLowerCase().includes('src')) && typeof value === 'string';
}

export { ColorInput };

/* ── 단일 파라미터 컨트롤 ─────────────────────────────────────── */
export const ParamField: React.FC<{
  indicatorType: string;
  paramKey: string;
  value: number | string | boolean;
  disabled?: boolean;
  onChange: (key: string, raw: string | boolean) => void;
}> = ({ indicatorType, paramKey, value, disabled, onChange }) => {
  if (typeof value === 'boolean') {
    return (
      <label className="ism-toggle">
        <input
          type="checkbox"
          checked={value}
          disabled={disabled}
          onChange={e => onChange(paramKey, e.target.checked)}
        />
        <span className="ism-toggle-slider" />
      </label>
    );
  }
  if (isMaTypeParam(indicatorType, paramKey, value)) {
    return (
      <select
        className="ism-select ism-param-inline-select"
        value={value as string}
        disabled={disabled}
        onChange={e => onChange(paramKey, e.target.value)}
      >
        {maTypeOptionsFor(indicatorType).map(o => (
          <option key={o} value={o}>
            {indicatorType === 'OBV'
              ? (OBV_MA_TYPE_LABELS[o] ?? o)
              : (MA_TYPE_LABELS[o] ?? o)}
          </option>
        ))}
      </select>
    );
  }
  if (isSrcParam(paramKey, value)) {
    return (
      <select
        className="ism-select ism-param-inline-select"
        value={value as string}
        disabled={disabled}
        onChange={e => onChange(paramKey, e.target.value)}
      >
        {SRC_OPTIONS.map(o => (
          <option key={o} value={o}>{getSrcOptionLabel(o)}</option>
        ))}
      </select>
    );
  }
  if (typeof value === 'number') {
    return (
      <NumericParamInput
        className="ism-input ism-narrow ism-sma-period-input"
        value={value}
        spec={getNumericParamSpec(indicatorType, paramKey, value)}
        disabled={disabled}
        onChange={v => onChange(paramKey, String(v))}
      />
    );
  }
  return (
    <input
      type="text"
      className="ism-input ism-narrow"
      value={value as string}
      disabled={disabled}
      onChange={e => onChange(paramKey, e.target.value)}
    />
  );
};

/* ── 플롯 설정 행 (on/off · 이름 · 입력 · 색상·선) ─────────────── */
export const PlotSettingsRow: React.FC<{
  indicatorType: string;
  plot: PlotDef;
  plotIndex: number;
  plots: PlotDef[];
  params: Record<string, number | string | boolean>;
  enabled: boolean;
  inputsOnly?: boolean;
  onToggle: (plotId: string, on: boolean) => void;
  onParamChange: (key: string, raw: string | boolean) => void;
  onPlotStyle: (plotIndex: number, patch: Partial<PlotDef>) => void;
}> = ({
  indicatorType, plot, plotIndex, plots, params, enabled, inputsOnly,
  onToggle, onParamChange, onPlotStyle,
}) => {
  const paramKeys = getPlotParamKeys(indicatorType, plot.id, plotIndex, plots, params);
  const noInputs = plotRowHasNoInputs(indicatorType, plot.id, plotIndex, plots, params);
  const globalOnlyInputs = plotParamsOnGlobalRowOnly(indicatorType, plot.id);
  const label = indicatorType === 'IchimokuCloud'
    ? getIchimokuPlotTitle(plot.id)
    : getPlotLabel(plot.title);
  const isHistogram = plot.type === 'histogram';

  return (
    <div className={`ism-row ism-sma-ma-row${enabled ? '' : ' ism-sma-ma-off'}`}>
      <label className="ism-toggle ism-sma-ma-toggle">
        <input
          type="checkbox"
          checked={enabled}
          onChange={e => onToggle(plot.id, e.target.checked)}
        />
        <span className="ism-toggle-slider" />
      </label>
      <label className="ism-label ism-sma-ma-label">{label}</label>
      <div className="ism-control ism-sma-ma-control">
        {noInputs && globalOnlyInputs ? (
          <span className="ism-hlines-bg-spacer" aria-hidden />
        ) : noInputs ? (
          <span className="ism-ichimoku-auto-param" title="상위 설정 또는 자동 계산">자동</span>
        ) : (
          <div className="ism-plot-param-inputs">
            {paramKeys.map(key => (
              <ParamField
                key={key}
                indicatorType={indicatorType}
                paramKey={key}
                value={params[key]}
                disabled={!enabled}
                onChange={onParamChange}
              />
            ))}
          </div>
        )}
        {!inputsOnly && (
          isHistogram && indicatorType === 'MACD' ? (
            <div className="ism-hist-colors">
              <div className="ism-hist-color-field">
                <span className="ism-style-label">0선 위</span>
                <ColorInput
                  value={resolveHistogramUpColor(plot)}
                  disabled={!enabled}
                  onChange={v => onPlotStyle(plotIndex, { histogramUpColor: v, color: v })}
                />
              </div>
              <div className="ism-hist-color-field">
                <span className="ism-style-label">0선 아래</span>
                <ColorInput
                  value={resolveHistogramDownColor(plot)}
                  disabled={!enabled}
                  onChange={v => onPlotStyle(plotIndex, { histogramDownColor: v })}
                />
              </div>
            </div>
          ) : isHistogram ? (
            <ColorInput
              value={plot.color}
              disabled={!enabled}
              onChange={v => onPlotStyle(plotIndex, { color: v })}
            />
          ) : (
            <PlotLineStylePicker
              disabled={!enabled}
              title={label}
              value={{
                color: plot.color,
                lineWidth: plot.lineWidth,
                lineStyle: plot.lineStyle,
              }}
              onChange={patch => onPlotStyle(plotIndex, patch)}
            />
          )
        )}
      </div>
    </div>
  );
};

/* ── 전역 파라미터 행 (토글 없음) ─────────────────────────────── */
export const GlobalParamRow: React.FC<{
  indicatorType: string;
  paramKey: string;
  value: number | string | boolean;
  onChange: (key: string, raw: string | boolean) => void;
}> = ({ indicatorType, paramKey, value, onChange }) => (
  <div className="ism-row ism-global-param-row">
    <span className="ism-label ism-sma-ma-label">{getParamLabel(paramKey, indicatorType)}</span>
    <div className="ism-control ism-sma-ma-control">
      <ParamField
        indicatorType={indicatorType}
        paramKey={paramKey}
        value={value}
        onChange={onChange}
      />
    </div>
  </div>
);

/* ── 수평선 행 ───────────────────────────────────────────────── */
export const HLineSettingsRow: React.FC<{
  indicatorType: string;
  hl: HLineDef;
  idx: number;
  allPrices: number[];
  inputsOnly?: boolean;
  onVisible: (idx: number, v: boolean) => void;
  onPrice: (idx: number, v: number) => void;
  onStyle: (idx: number, patch: Partial<HLineDef>) => void;
}> = ({ indicatorType, hl, idx, allPrices, inputsOnly, onVisible, onPrice, onStyle }) => {
  const label = hl.label ?? getHLineLabel(hl.price, allPrices);
  const isOn = hl.visible !== false;
  return (
    <div className={`ism-row ism-sma-ma-row${isOn ? '' : ' ism-sma-ma-off'}`}>
      <label className="ism-toggle ism-sma-ma-toggle">
        <input type="checkbox" checked={isOn} onChange={e => onVisible(idx, e.target.checked)} />
        <span className="ism-toggle-slider" />
      </label>
      <label className="ism-label ism-sma-ma-label">{label}</label>
      <div className="ism-control ism-sma-ma-control">
        <NumericParamInput
          className="ism-input ism-narrow ism-sma-period-input"
          value={hl.price}
          spec={getHlinePriceSpec(indicatorType, hl.price)}
          disabled={!isOn}
          onChange={v => onPrice(idx, v)}
        />
        {!inputsOnly && (
          <PlotLineStylePicker
            disabled={!isOn}
            title={label}
            value={{
              color: hl.color,
              lineWidth: hl.lineWidth,
              lineStyle: hl.lineStyle ?? 'dashed',
            }}
            onChange={patch => onStyle(idx, patch)}
          />
        )}
      </div>
    </div>
  );
};

/* ── 출력 · 타임프레임 (하단 공통) ───────────────────────────── */
export const SettingsOutputFooter: React.FC<{
  lastValueVisible: boolean;
  onLastValueVisible: (v: boolean) => void;
  timeframeVis: Partial<Record<Timeframe, boolean>>;
  onTimeframeVis: (tf: Timeframe, v: boolean) => void;
  timeframes: { tf: Timeframe; label: string }[];
  /** 개별 설정 모달: 지표 전체 숨김 */
  chartHidden?: boolean;
  onChartHidden?: (showOnChart: boolean) => void;
}> = ({
  lastValueVisible, onLastValueVisible, timeframeVis, onTimeframeVis, timeframes,
  chartHidden, onChartHidden,
}) => (
  <>
    <div className="ism-ichimoku-cloud-divider" />
    <div className="ism-output-section-title">출력 · 표시</div>
    {onChartHidden != null && (
      <div className="ism-row ism-ichimoku-extra-row">
        <span className="ism-label">차트에 표시</span>
        <div className="ism-control">
          <label className="ism-toggle">
            <input
              type="checkbox"
              checked={chartHidden !== true}
              onChange={e => onChartHidden(e.target.checked)}
            />
            <span className="ism-toggle-slider" />
          </label>
        </div>
      </div>
    )}
    <div className="ism-row ism-ichimoku-extra-row">
      <span className="ism-label">가격축 라벨·설명</span>
      <div className="ism-control">
        <label className="ism-toggle" title="이 지표만 우측 가격축 금액·설명 표시 (해당 영역·차트 설정 전역 스위치가 켜져 있을 때 적용)">
          <input
            type="checkbox"
            checked={lastValueVisible}
            onChange={e => onLastValueVisible(e.target.checked)}
          />
          <span className="ism-toggle-slider" />
        </label>
      </div>
    </div>
    <div className="ism-tf-grid ism-ichimoku-tf-grid">
      {timeframes.map(({ tf, label }) => (
        <label key={tf} className="ism-tf-item">
          <input
            type="checkbox"
            checked={timeframeVis[tf] !== false}
            onChange={e => onTimeframeVis(tf, e.target.checked)}
          />
          <span className="ism-tf-label">{label}</span>
        </label>
      ))}
    </div>
  </>
);

/* ── 일목 구름 색상 ─────────────────────────────────────────── */
export const IchimokuCloudSection: React.FC<{
  cloudColors: IchimokuCloudColors;
  onChange: (patch: Partial<IchimokuCloudColors>) => void;
}> = ({ cloudColors, onChange }) => {
  const bullishOn = cloudColors.bullishVisible !== false;
  const bearishOn = cloudColors.bearishVisible !== false;

  return (
    <>
      <div className="ism-ichimoku-cloud-divider" />
      <div className="ism-ichimoku-cloud-section">
        <h4 className="ism-ichimoku-cloud-title">구름 영역</h4>
        <p className="ism-ichimoku-cloud-hint">
          선행스팬1·선행스팬2가 모두 켜져 있을 때만 구름을 그릴 수 있습니다. 상승·하락 구름은 각각 on/off 할 수 있습니다.
        </p>
        <div className="ism-ichimoku-cloud-grid">
          <div className={`ism-ichimoku-cloud-card${bullishOn ? '' : ' ism-ichimoku-cloud-card--off'}`}>
            <div className="ism-ichimoku-cloud-card-head">
              <label className="ism-toggle ism-ichimoku-cloud-toggle">
                <input
                  type="checkbox"
                  checked={bullishOn}
                  onChange={e => onChange({ bullishVisible: e.target.checked })}
                />
                <span className="ism-toggle-slider" />
              </label>
              <span className="ism-ichimoku-cloud-card-label">상승 구름 (선행1 &gt; 선행2)</span>
            </div>
            <div className="ism-ichimoku-cloud-card-row">
              <ColorInput
                value={cloudColors.bullishColor}
                disabled={!bullishOn}
                onChange={v => onChange({ bullishColor: v })}
              />
            </div>
            <div className="ism-ichimoku-cloud-meta">
              {colorToRgbaString(cloudColors.bullishColor)}
              {' · '}투명도 {cloudColorOpacityPercent(cloudColors.bullishColor)}%
            </div>
          </div>
          <div className={`ism-ichimoku-cloud-card${bearishOn ? '' : ' ism-ichimoku-cloud-card--off'}`}>
            <div className="ism-ichimoku-cloud-card-head">
              <label className="ism-toggle ism-ichimoku-cloud-toggle">
                <input
                  type="checkbox"
                  checked={bearishOn}
                  onChange={e => onChange({ bearishVisible: e.target.checked })}
                />
                <span className="ism-toggle-slider" />
              </label>
              <span className="ism-ichimoku-cloud-card-label">하락 구름 (선행1 &lt; 선행2)</span>
            </div>
            <div className="ism-ichimoku-cloud-card-row">
              <ColorInput
                value={cloudColors.bearishColor}
                disabled={!bearishOn}
                onChange={v => onChange({ bearishColor: v })}
              />
            </div>
            <div className="ism-ichimoku-cloud-meta">
              {colorToRgbaString(cloudColors.bearishColor)}
              {' · '}투명도 {cloudColorOpacityPercent(cloudColors.bearishColor)}%
            </div>
          </div>
        </div>
      </div>
    </>
  );
};

/* ── 볼린저밴드 백그라운드 (업비트 모습 탭) ───────────────────── */
export const BollingerBackgroundRow: React.FC<{
  value: HlinesBackground;
  onChange: (v: HlinesBackground) => void;
}> = ({ value, onChange }) => (
  <div className={`ism-row ism-sma-ma-row${value.visible ? '' : ' ism-sma-ma-off'}`}>
    <label className="ism-toggle ism-sma-ma-toggle">
      <input
        type="checkbox"
        checked={value.visible}
        onChange={e => onChange({ ...value, visible: e.target.checked })}
      />
      <span className="ism-toggle-slider" />
    </label>
    <span className="ism-label ism-sma-ma-label">백그라운드 그리기</span>
    <div className="ism-control ism-sma-ma-control">
      <span className="ism-ichimoku-auto-param ism-hlines-bg-spacer" aria-hidden />
      <ColorInput
        value={value.color}
        onChange={c => onChange({ ...value, color: c })}
      />
    </div>
  </div>
);

/* ── 수평선 배경 ─────────────────────────────────────────────── */
export const HlinesBackgroundRow: React.FC<{
  value: HlinesBackground;
  onChange: (v: HlinesBackground) => void;
}> = ({ value, onChange }) => (
  <>
    <div className="ism-ichimoku-cloud-divider" />
    <div className="ism-row ism-sma-ma-row">
      <label className="ism-toggle ism-sma-ma-toggle">
        <input
          type="checkbox"
          checked={value.visible}
          onChange={e => onChange({ ...value, visible: e.target.checked })}
        />
        <span className="ism-toggle-slider" />
      </label>
      <span className="ism-label ism-sma-ma-label">수평선 배경</span>
      <div className="ism-control ism-sma-ma-control">
        <span className="ism-ichimoku-auto-param ism-hlines-bg-spacer" aria-hidden />
        <ColorInput
          value={value.color}
          onChange={c => onChange({ ...value, color: c })}
        />
      </div>
    </div>
  </>
);

/* ── 볼린저밴드 심볼 (업비트 인풋) ───────────────────────────── */
export const BollingerSymbolSection: React.FC<{
  symbolMode: string;
  refSymbol: string;
  chartMarket: string;
  onChange: (patch: { symbolMode?: string; refSymbol?: string }) => void;
}> = ({ symbolMode, refSymbol, chartMarket, onChange }) => {
  const isOther = symbolMode === 'other';
  return (
    <div className="ism-bb-symbol-section">
      <div className="ism-output-section-title">심볼</div>
      <label className="ism-bb-symbol-option">
        <input
          type="radio"
          name="bb-symbol-mode"
          checked={!isOther}
          onChange={() => onChange({ symbolMode: 'main' })}
        />
        <span>메인 차트 심볼</span>
        {chartMarket ? <span className="ism-bb-symbol-hint">{chartMarket}</span> : null}
      </label>
      <label className="ism-bb-symbol-option ism-bb-symbol-other">
        <input
          type="radio"
          name="bb-symbol-mode"
          checked={isOther}
          onChange={() => onChange({ symbolMode: 'other' })}
        />
        <span>다른 심볼</span>
        <input
          type="text"
          className="ism-input ism-bb-ref-symbol"
          placeholder="KRW-BTC"
          value={refSymbol}
          disabled={!isOther}
          onChange={e => onChange({ refSymbol: e.target.value.toUpperCase() })}
        />
      </label>
    </div>
  );
};

/* ── 통합 본문 (일반 지표) ───────────────────────────────────── */
export const UnifiedIndicatorBody: React.FC<{
  config: IndicatorConfig;
  params: Record<string, number | string | boolean>;
  plots: PlotDef[];
  plotVis: Record<string, boolean>;
  hlines: HLineDef[];
  hlinesBg: HlinesBackground;
  hasHLines: boolean;
  lastValueVisible: boolean;
  timeframeVis: Partial<Record<Timeframe, boolean>>;
  timeframes: { tf: Timeframe; label: string }[];
  onParamChange: (key: string, raw: string | boolean) => void;
  onPlotToggle: (plotId: string, on: boolean) => void;
  onPlotStyle: (idx: number, patch: Partial<PlotDef>) => void;
  onHLineVisible: (idx: number, v: boolean) => void;
  onHLinePrice: (idx: number, v: number) => void;
  onHLineStyle: (idx: number, patch: Partial<HLineDef>) => void;
  onHlinesBg: (v: HlinesBackground) => void;
  onLastValueVisible: (v: boolean) => void;
  onTimeframeVis: (tf: Timeframe, v: boolean) => void;
  cloudSection?: React.ReactNode;
  symbolSection?: React.ReactNode;
  /** 플롯 행 아래 추가 섹션 (BB 백그라운드 등) */
  afterPlotsSection?: React.ReactNode;
  /** false면 가격 스케일·타임프레임 보임 설정 숨김 (BB) */
  showOutputFooter?: boolean;
  inputsOnly?: boolean;
  chartHidden?: boolean;
  onChartHidden?: (showOnChart: boolean) => void;
}> = (props) => {
  const {
    config, params, plots, plotVis, hlines, hlinesBg, hasHLines,
    lastValueVisible, timeframeVis, timeframes,
    onParamChange, onPlotToggle, onPlotStyle,
    onHLineVisible, onHLinePrice, onHLineStyle, onHlinesBg,
    onLastValueVisible, onTimeframeVis, cloudSection, symbolSection,
    afterPlotsSection,
    showOutputFooter = true,
    inputsOnly = false,
    chartHidden,
    onChartHidden,
  } = props;

  const globalKeys = getGlobalParamKeys(config.type, params, plots);
  const hlinePrices = hlines.map(h => h.price);

  return (
    <div className="ism-section unified-settings-section">
      {symbolSection}
      {symbolSection && globalKeys.length > 0 && <div className="ism-sma-divider" />}
      {globalKeys.map(key => (
        <GlobalParamRow
          key={key}
          indicatorType={config.type}
          paramKey={key}
          value={params[key]}
          onChange={onParamChange}
        />
      ))}

      {globalKeys.length > 0 && plots.length > 0 && <div className="ism-sma-divider" />}

      {plots.map((plot, idx) => (
        <PlotSettingsRow
          key={plot.id}
          indicatorType={config.type}
          plot={plot}
          plotIndex={idx}
          plots={plots}
          params={params}
          enabled={plotVis[plot.id] !== false}
          onToggle={onPlotToggle}
          onParamChange={onParamChange}
          onPlotStyle={onPlotStyle}
          inputsOnly={inputsOnly}
        />
      ))}

      {cloudSection}

      {afterPlotsSection}

      {hlines.length > 0 && (
        <>
          <div className="ism-sma-divider" />
          <div className="ism-output-section-title">수평선</div>
          {hlines.map((hl, idx) => (
            <HLineSettingsRow
              key={idx}
              indicatorType={config.type}
              hl={hl}
              idx={idx}
              allPrices={hlinePrices}
              onVisible={onHLineVisible}
              onPrice={onHLinePrice}
              onStyle={onHLineStyle}
              inputsOnly={inputsOnly}
            />
          ))}
        </>
      )}

      {hasHLines && !inputsOnly && <HlinesBackgroundRow value={hlinesBg} onChange={onHlinesBg} />}

      {showOutputFooter && (
        <SettingsOutputFooter
          lastValueVisible={lastValueVisible}
          onLastValueVisible={onLastValueVisible}
          timeframeVis={timeframeVis}
          onTimeframeVis={onTimeframeVis}
          timeframes={timeframes}
          chartHidden={chartHidden}
          onChartHidden={onChartHidden}
        />
      )}
    </div>
  );
};
