/**
 * 전략 평가 — 좌측 패널 전략설정 탭 (지표 파라미터 테스트)
 */
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import type { StrategyDto } from '../../utils/backendApi';
import { getIndicatorDef } from '../../utils/indicatorRegistry';
import { getGlobalParamKeys, getPlotParamKeys } from '../../utils/indicatorSettingsLayout';
import { GlobalParamRow } from '../IndicatorSettingsSections';
import { collectStrategyRegistryTypes } from '../../utils/strategyToChartIndicators';
import {
  buildEvalParamsFromStrategy,
  hasEvalParamsDiff,
  type EvalIndicatorParams,
} from '../../utils/strategyEvaluationParams';
import { repairUtf8Mojibake } from '../../utils/textEncoding';

interface Props {
  strategy: StrategyDto | null;
  getParams: (type: string) => Record<string, number | string | boolean>;
  appliedParams: EvalIndicatorParams | null;
  onSave: (params: EvalIndicatorParams) => void;
  onReset: () => void;
  applying?: boolean;
}

function getEditableParamKeys(
  indicatorType: string,
  params: Record<string, number | string | boolean>,
): string[] {
  const def = getIndicatorDef(indicatorType);
  const plots = def?.plots ?? [];
  const keys = new Set<string>();
  for (const k of getGlobalParamKeys(indicatorType, params, plots)) keys.add(k);
  plots.forEach((p, i) => {
    for (const k of getPlotParamKeys(indicatorType, p.id, i, plots, params)) keys.add(k);
  });
  if (keys.size === 0) {
    Object.keys(params).forEach(k => {
      if (k !== 'symbolMode' && k !== 'refSymbol') keys.add(k);
    });
  }
  return [...keys];
}

const StrategyEvaluationSettingsTab: React.FC<Props> = ({
  strategy,
  getParams,
  appliedParams,
  onSave,
  onReset,
  applying = false,
}) => {
  const [draft, setDraft] = useState<EvalIndicatorParams>({});
  const [expanded, setExpanded] = useState<string | null>(null);

  const indicatorTypes = useMemo(
    () => collectStrategyRegistryTypes(strategy ?? undefined),
    [strategy],
  );

  const resolveBaseline = useCallback((): EvalIndicatorParams => {
    if (!strategy) return {};
    return appliedParams ?? buildEvalParamsFromStrategy(strategy, getParams);
  }, [strategy, appliedParams, getParams]);

  useEffect(() => {
    if (!strategy) {
      setDraft({});
      setExpanded(null);
      return;
    }
    setDraft(JSON.parse(JSON.stringify(resolveBaseline())) as EvalIndicatorParams);
    setExpanded(indicatorTypes[0] ?? null);
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [strategy?.id, appliedParams, indicatorTypes.join(',')]);

  const dirty = useMemo(
    () => hasEvalParamsDiff(draft, resolveBaseline()),
    [draft, resolveBaseline],
  );

  const handleApply = useCallback(() => {
    onSave(JSON.parse(JSON.stringify(draft)) as EvalIndicatorParams);
  }, [draft, onSave]);

  const patchParam = useCallback((type: string, key: string, raw: string | boolean) => {
    setDraft(prev => {
      const current = prev[type] ?? {};
      const oldVal = current[key];
      const defVal = getIndicatorDef(type)?.defaultParams?.[key];
      let nextVal: number | string | boolean;
      if (typeof oldVal === 'number' || typeof defVal === 'number') {
        const n = parseFloat(raw as string);
        const fallback = typeof oldVal === 'number' ? oldVal : (defVal as number);
        nextVal = Number.isNaN(n) ? fallback : n;
      } else if (typeof oldVal === 'boolean' || typeof defVal === 'boolean') {
        nextVal = raw as boolean;
      } else {
        nextVal = raw as string;
      }
      return {
        ...prev,
        [type]: { ...current, [key]: nextVal },
      };
    });
  }, []);

  const resetType = useCallback((type: string) => {
    setDraft(prev => ({
      ...prev,
      [type]: { ...getParams(type) },
    }));
  }, [getParams]);

  if (!strategy) {
    return <p className="btd-sidebar-empty">전략을 먼저 선택하세요</p>;
  }

  if (indicatorTypes.length === 0) {
    return <p className="btd-sidebar-empty">선택한 전략에 설정 가능한 보조지표가 없습니다</p>;
  }

  const strategyName = repairUtf8Mojibake(strategy.name ?? `전략 #${strategy.id}`);

  return (
    <div className="seval-settings-tab">
      <div className="seval-settings-head">
        <div className="seval-settings-head-row">
          <p className="seval-settings-strategy">{strategyName}</p>
          <button
            type="button"
            className="seval-settings-apply"
            disabled={!dirty || applying}
            onClick={handleApply}
            title="변경된 지표 값을 차트·일치율에 반영"
          >
            {applying ? '적용 중…' : '적용'}
          </button>
        </div>
        <p className="seval-settings-hint">지표 값을 변경한 뒤 적용을 누르면 차트·일치율이 갱신됩니다</p>
      </div>

      <div className="seval-settings-list">
        {indicatorTypes.map(type => {
          const def = getIndicatorDef(type);
          const params = draft[type] ?? {};
          const paramKeys = getEditableParamKeys(type, params);
          const isOpen = expanded === type;
          const label = def?.koreanName ?? def?.shortName ?? type;

          return (
            <div key={type} className={`seval-settings-card${isOpen ? ' seval-settings-card--open' : ''}`}>
              <button
                type="button"
                className="seval-settings-card-head"
                onClick={() => setExpanded(isOpen ? null : type)}
              >
                <span className="seval-settings-card-title">{label}</span>
                <span className="seval-settings-card-type">{type}</span>
              </button>
              {isOpen && (
                <div className="seval-settings-card-body">
                  {paramKeys.map(key => (
                    <GlobalParamRow
                      key={key}
                      indicatorType={type}
                      paramKey={key}
                      value={params[key] ?? getParams(type)[key]}
                      onChange={(k, raw) => patchParam(type, k, raw)}
                    />
                  ))}
                  <button
                    type="button"
                    className="seval-settings-reset-type"
                    onClick={() => resetType(type)}
                  >
                    이 지표 기본값
                  </button>
                </div>
              )}
            </div>
          );
        })}
      </div>

      <div className="seval-settings-actions">
        <button
          type="button"
          className="seval-settings-reset"
          disabled={(!appliedParams && !dirty) || applying}
          onClick={onReset}
        >
          초기화
        </button>
      </div>
    </div>
  );
};

export default StrategyEvaluationSettingsTab;
