/* ============================================================================
 * 서명전에 — TDS SplitTextField 컴포넌트 (Task #168)
 *
 *  · 두 개의 입력을 가로로 나란히 배치한 split 입력 컨테이너.
 *    한국 주민등록번호처럼 "앞 6 - 뒤 7" 같은 정형 포맷에 사용.
 *
 *  · 서브 컴포넌트:
 *      SplitTextField.RRN13      — 13자리 주민번호 전체 (앞6 + 뒤7)
 *                                  · 첫 번째 필드 6자리 입력 완료 시 두 번째로 자동 포커스 이동
 *                                  · 두 번째 필드는 mask=true (기본) 면 ••• 로 마스킹
 *      SplitTextField.RRNFirst7  — 앞 7자리만 (앞6 + 성별 1자리)
 *                                  · 두 번째 필드는 1자리 (성별)
 *                                  · mask=false (기본) 라 성별 코드는 평문 표시
 *
 *  · 공통 props:
 *      value         13자리 (RRN13) 또는 7자리 (RRNFirst7) string
 *      defaultValue  uncontrolled 초기값
 *      onChange      (full: string) => void
 *      hasError, handleError, disabled, focused, label, help
 *      first         { placeholder, autoComplete, ... } — 앞 필드에 패스스루
 *      second        { placeholder, autoComplete, ... } — 뒤 필드에 패스스루
 *
 *  · ref API:
 *      focus()       첫 번째 필드 포커스
 *      focusSecond() 두 번째 필드 포커스
 *      clear()       두 필드 모두 비우기
 *      el()          { first, second } DOM 반환
 *
 *  · Babel Standalone 환경 호환: __stf 접두사 alias 사용.
 * ========================================================================== */

const __stfUseState           = (typeof React !== "undefined" && React.useState) || function (v) { return [v, function () {}]; };
const __stfUseRef             = (typeof React !== "undefined" && React.useRef) || function () { return { current: null }; };
const __stfUseEffect          = (typeof React !== "undefined" && React.useEffect) || function () {};
const __stfUseImperativeHandle= (typeof React !== "undefined" && React.useImperativeHandle) || function () {};
const __stfForwardRef         = (typeof React !== "undefined" && React.forwardRef) || function (fn) { return fn; };

function __stfJoin() {
  let out = "";
  for (let i = 0; i < arguments.length; i++) {
    const v = arguments[i];
    if (!v) continue;
    out = out ? out + " " + v : v;
  }
  return out;
}

// ----- 숫자만 추출 -----
function __stfDigits(s) {
  if (!s) return "";
  return String(s).replace(/[^0-9]/g, "");
}

// ----- bullet 문자열 만들기 -----
function __stfBullets(n) {
  let out = "";
  for (let i = 0; i < n; i++) out += "•";
  return out;
}

/* ----------------------------------------------------------------------------
 * 내부 공용 — split 본체
 *   firstLen : 앞 필드 자릿수 (6)
 *   secondLen: 뒤 필드 자릿수 (7 or 1)
 *   mask     : 뒤 필드를 ••• 로 가릴지
 *   sep      : 시각 구분자 ("-" 기본)
 *   first / second props : 패스스루
 * -------------------------------------------------------------------------- */
const __SplitBase = __stfForwardRef(function __SplitBase(props, ref) {
  const {
    firstLen,
    secondLen,
    mask = false,
    sep = "-",
    label,
    help,
    hasError = false,
    handleError,
    disabled = false,
    focused: focusedProp,
    value,
    defaultValue,
    onChange,
    first,
    second,
    className = "",
    style,
    id,
  } = props;

  const isControlled = value !== undefined;

  const splitValue = function (full) {
    const digits = __stfDigits(full);
    return {
      first:  digits.slice(0, firstLen),
      second: digits.slice(firstLen, firstLen + secondLen),
    };
  };

  const initial = splitValue(typeof defaultValue === "string" ? defaultValue : "");
  const [internalFirst,  setInternalFirst]  = __stfUseState(initial.first);
  const [internalSecond, setInternalSecond] = __stfUseState(initial.second);

  const ext = isControlled ? splitValue(value) : null;
  const firstVal  = isControlled ? ext.first  : internalFirst;
  const secondVal = isControlled ? ext.second : internalSecond;

  const [focused, setFocused] = __stfUseState(false);
  const isFocused = focusedProp != null ? focusedProp : focused;

  const firstRef  = __stfUseRef(null);
  const secondRef = __stfUseRef(null);

  __stfUseImperativeHandle(ref, function () {
    return {
      focus:       function () { if (firstRef.current && firstRef.current.focus) firstRef.current.focus(); },
      focusSecond: function () { if (secondRef.current && secondRef.current.focus) secondRef.current.focus(); },
      clear:       function () {
        if (!isControlled) { setInternalFirst(""); setInternalSecond(""); }
        if (typeof onChange === "function") onChange("");
        if (firstRef.current && firstRef.current.focus) firstRef.current.focus();
      },
      el: function () { return { first: firstRef.current, second: secondRef.current }; },
    };
  }, [isControlled]);

  // ----- onChange emit -----
  function emitChange(nextFirst, nextSecond) {
    const full = (nextFirst || "") + (nextSecond || "");
    if (typeof onChange === "function") onChange(full);
  }

  // ----- 첫 번째 입력 -----
  const handleFirst = function (e) {
    let next = __stfDigits(e.target.value).slice(0, firstLen);
    if (!isControlled) setInternalFirst(next);
    emitChange(next, secondVal);
    // 자릿수 채워지면 두 번째로 자동 포커스
    if (next.length >= firstLen && secondRef.current && secondRef.current.focus) {
      secondRef.current.focus();
    }
  };

  // ----- 두 번째 입력 -----
  const handleSecond = function (e) {
    let next = __stfDigits(e.target.value).slice(0, secondLen);
    if (!isControlled) setInternalSecond(next);
    emitChange(firstVal, next);
  };

  // ----- 두 번째에서 백스페이스 + 비어있으면 첫 번째로 -----
  const handleSecondKeyDown = function (e) {
    if (e.key === "Backspace" && (!secondVal || secondVal.length === 0)) {
      if (firstRef.current && firstRef.current.focus) {
        e.preventDefault();
        firstRef.current.focus();
        // 커서를 끝으로
        setTimeout(function () {
          try {
            const len = (firstVal || "").length;
            firstRef.current.setSelectionRange(len, len);
          } catch (_e) {}
        }, 0);
      }
    }
  };

  const handleFocusIn  = function () { setFocused(true); };
  const handleFocusOut = function () { setFocused(false); };

  // ----- 클래스 -----
  const rootCls = __stfJoin(
    "tds-tf",
    "tds-tf--split",
    label ? "tds-tf--shown" : "",
    isFocused ? "tds-tf--focused" : "",
    hasError ? "tds-tf--error" : "",
    disabled ? "tds-tf--disabled" : "",
    className
  );

  const stfCls = __stfJoin(
    "tds-stf",
    isFocused ? "tds-stf--focused" : "",
    hasError ? "tds-stf--error" : "",
    disabled ? "tds-stf--disabled" : ""
  );

  // ----- first/second props 분해 (패스스루) -----
  const firstProps  = first  || {};
  const secondProps = second || {};

  // 두 번째 필드 마스킹 표시 — JSX 에서 절대 배치된 div 로 ••• 표시
  // input value 는 비워두지 않고 진짜 숫자를 유지 (form submit 시 사용)
  // 화면에는 마스크 div 가 덮음 (input 은 transparent)
  const showMaskOverlay = mask && (secondVal && secondVal.length > 0);

  return (
    <div id={id} className={rootCls} style={style}>
      {label != null && label !== "" ? (
        <label className="tds-tf__label">
          {label}
        </label>
      ) : null}

      <div className={stfCls} onFocus={handleFocusIn} onBlur={handleFocusOut}>
        {/* ----- 앞 필드 ----- */}
        <div className="tds-stf__half tds-stf__half--first">
          <input
            ref={firstRef}
            type="text"
            inputMode="numeric"
            pattern="[0-9]*"
            className="tds-stf__input"
            value={firstVal}
            onChange={handleFirst}
            disabled={disabled}
            maxLength={firstLen}
            placeholder={firstProps.placeholder != null ? firstProps.placeholder : (firstLen === 6 ? "YYMMDD" : "")}
            autoComplete={firstProps.autoComplete || "off"}
            aria-label={firstProps["aria-label"] || (label ? label + " 앞자리" : "주민번호 앞자리")}
            aria-invalid={hasError ? "true" : undefined}
          />
        </div>

        {/* ----- 구분자 ----- */}
        <span className="tds-stf__sep" aria-hidden="true">{sep}</span>

        {/* ----- 뒤 필드 ----- */}
        <div className="tds-stf__half tds-stf__half--second">
          <input
            ref={secondRef}
            type={mask ? "password" : "text"}
            inputMode="numeric"
            pattern="[0-9]*"
            className={__stfJoin("tds-stf__input", mask ? "tds-stf__input--masked" : "")}
            value={secondVal}
            onChange={handleSecond}
            onKeyDown={handleSecondKeyDown}
            disabled={disabled}
            maxLength={secondLen}
            placeholder={secondProps.placeholder != null ? secondProps.placeholder : (secondLen === 7 ? "•••••••" : "성별")}
            autoComplete={secondProps.autoComplete || "off"}
            aria-label={secondProps["aria-label"] || (label ? label + " 뒷자리" : "주민번호 뒷자리")}
            aria-invalid={hasError ? "true" : undefined}
          />
          {/* mask=true 일 때 type=password 가 이미 가리지만, font 가 ••• 로 보이게 추가 보강.
              브라우저 따라 password 글리프가 다를 수 있어 시각 통일. */}
          {showMaskOverlay && false ? (
            // 시각적 마스크 덧붙임은 type=password 와 중복되므로 비활성.
            // 향후 디자인 요구가 생기면 여기서 켜면 됨.
            <span className="tds-stf__mask" aria-hidden="true">{__stfBullets(secondVal.length)}</span>
          ) : null}
        </div>
      </div>

      {(hasError && handleError) || help ? (
        <p
          className="tds-tf__help"
          role={hasError ? "alert" : undefined}
        >
          {hasError && handleError ? handleError : help}
        </p>
      ) : null}
    </div>
  );
});

/* ----------------------------------------------------------------------------
 * 루트 SplitTextField — 직접 사용 가능 (firstLen/secondLen 직접 지정 시)
 * -------------------------------------------------------------------------- */
const SplitTextField = __stfForwardRef(function SplitTextField(props, ref) {
  return <__SplitBase ref={ref} {...props} />;
});

/* ----------------------------------------------------------------------------
 * SplitTextField.RRN13 — 13자리 주민번호 전체
 *   mask 기본 true (뒤 7자리 보안 마스킹)
 * -------------------------------------------------------------------------- */
const SplitTextFieldRRN13 = __stfForwardRef(function SplitTextFieldRRN13(props, ref) {
  const { mask, ...rest } = props;
  return (
    <__SplitBase
      ref={ref}
      firstLen={6}
      secondLen={7}
      mask={mask !== false}
      {...rest}
    />
  );
});

/* ----------------------------------------------------------------------------
 * SplitTextField.RRNFirst7 — 앞 7자리만 (생년월일 + 성별)
 *   mask 기본 false (성별 코드는 평문)
 * -------------------------------------------------------------------------- */
const SplitTextFieldRRNFirst7 = __stfForwardRef(function SplitTextFieldRRNFirst7(props, ref) {
  const { mask, ...rest } = props;
  return (
    <__SplitBase
      ref={ref}
      firstLen={6}
      secondLen={1}
      mask={mask === true}
      {...rest}
    />
  );
});

// ----- 서브 부착 -----
SplitTextField.RRN13 = SplitTextFieldRRN13;
SplitTextField.RRNFirst7 = SplitTextFieldRRNFirst7;

// ----- window 등록 -----
window.SplitTextField = SplitTextField;
Object.assign(window, { SplitTextField });
