/* ============================================================================
 * 서명전에 — TDS NumericSpinner 컴포넌트
 *  · 정수 입력 — - / + 버튼으로 1 씩 증감.
 *  · 4 size: tiny / small / medium / large (CSS 에 별도 변형)
 *  · controlled (number + onNumberChange) / uncontrolled (defaultNumber)
 *  · min/max 도달 시 해당 버튼만 자동 비활성화
 *  · disable=true → 컴포넌트 전체 비활성
 *  · 숫자는 aria-live="polite" 로 변경 자동 안내
 *  · decreaseAriaLabel / increaseAriaLabel 로 상황 맞춤 라벨 (기본 "빼기"/"더하기")
 *
 *  · props (NumericSpinnerProps):
 *      size *           "tiny" | "small" | "medium" | "large"  (필수)
 *      number           number — controlled 현재 값
 *      defaultNumber    number — uncontrolled 초기 값
 *      minNumber        number — 최솟값 (기본 0)
 *      maxNumber        number — 최댓값 (기본 999)
 *      disable          boolean — true 면 전체 비활성 (기본 false)
 *      onNumberChange   (number: number) => void — 값 변경 콜백
 *      decreaseAriaLabel string — 감소 버튼 aria-label (기본 "빼기")
 *      increaseAriaLabel string — 증가 버튼 aria-label (기본 "더하기")
 *      className, style, id 패스스루
 * ========================================================================== */

const __NUMSPIN_VALID_SIZES = { tiny: 1, small: 1, medium: 1, large: 1 };

function NumericSpinner({
  size,
  number,
  defaultNumber,
  minNumber = 0,
  maxNumber = 999,
  disable = false,
  onNumberChange,
  decreaseAriaLabel = "빼기",
  increaseAriaLabel = "더하기",
  className = "",
  style,
  id,
  ...rest
}) {
  // size 필수 — 검증
  if (!__NUMSPIN_VALID_SIZES[size]) {
    if (window.console && console.warn) {
      console.warn(
        `[NumericSpinner] \`size\` 는 필수예요 — "tiny" | "small" | "medium" | "large" 중 하나. 받은 값: ${size}`
      );
    }
  }
  const safeSize = __NUMSPIN_VALID_SIZES[size] ? size : "medium";

  // min/max 정합성 보정
  const safeMin = Number.isFinite(minNumber) ? minNumber : 0;
  const safeMax = Number.isFinite(maxNumber) ? maxNumber : 999;
  const realMin = Math.min(safeMin, safeMax);
  const realMax = Math.max(safeMin, safeMax);

  const isControlled = typeof number === "number";
  // uncontrolled 초기값 — defaultNumber 가 있으면 그걸로, 없으면 realMin 으로
  const initial = (function () {
    const seed = typeof defaultNumber === "number" ? defaultNumber : realMin;
    return Math.min(realMax, Math.max(realMin, Math.round(seed)));
  })();

  const [internal, setInternal] = React.useState(initial);

  // 외부 number 가 범위 밖이어도 그대로 보여줘요 (단, 버튼은 clamp 후 emit)
  const current = isControlled ? number : internal;

  const setValue = function (next) {
    const clamped = Math.min(realMax, Math.max(realMin, Math.round(next)));
    if (typeof onNumberChange === "function") onNumberChange(clamped);
    if (!isControlled) setInternal(clamped);
  };

  const canDec = !disable && current > realMin;
  const canInc = !disable && current < realMax;

  const handleDec = function () { if (canDec) setValue(current - 1); };
  const handleInc = function () { if (canInc) setValue(current + 1); };

  const cls = [
    "tds-numspin",
    `tds-numspin--size-${safeSize}`,
    disable ? "tds-numspin--disabled" : "",
    className,
  ].filter(Boolean).join(" ");

  return (
    <div
      id={id}
      className={cls}
      style={style}
      role="group"
      aria-disabled={disable ? "true" : undefined}
      {...rest}
    >
      <button
        type="button"
        className="tds-numspin__btn tds-numspin__btn--dec"
        onClick={handleDec}
        disabled={!canDec}
        aria-label={decreaseAriaLabel}
      >
        <svg viewBox="0 0 24 24" focusable="false" aria-hidden="true">
          {/* 단순 - 선 */}
          <line x1="6" y1="12" x2="18" y2="12" />
        </svg>
      </button>
      <span
        className="tds-numspin__value"
        role="status"
        aria-live="polite"
        aria-atomic="true"
      >
        {current}
      </span>
      <button
        type="button"
        className="tds-numspin__btn tds-numspin__btn--inc"
        onClick={handleInc}
        disabled={!canInc}
        aria-label={increaseAriaLabel}
      >
        <svg viewBox="0 0 24 24" focusable="false" aria-hidden="true">
          {/* + 두 선 */}
          <line x1="12" y1="6" x2="12" y2="18" />
          <line x1="6" y1="12" x2="18" y2="12" />
        </svg>
      </button>
    </div>
  );
}

window.NumericSpinner = NumericSpinner;

Object.assign(window, { NumericSpinner });
