/* ============================================================================
 * 서명전에 — TDS Checkbox 컴포넌트
 *  · 서브: Checkbox.Circle (원형 박스 + 체크) / Checkbox.Line (체크 아이콘만)
 *  · Controlled (checked + onCheckedChange) 또는
 *    Uncontrolled (defaultChecked 내부 state) 모드 지원.
 *  · inputType="radio" 로 주면 같은 시각으로 라디오 버튼처럼 사용 가능.
 *    라디오 모드에서는 onChange 의 e.target.value 로 그룹 상태를 관리해요.
 *  · disabled 인 상태에서 클릭하면 좌우로 살짝 흔들리는 애니메이션이 실행돼
 *    "여기선 선택할 수 없어요" 라는 힌트를 줘요.
 *  · aria-label 은 꼭 제공하세요 — 커스텀 시각과 텍스트 레이블이 분리되는
 *    구조라 스크린 리더가 용도를 설명해 줄 라벨이 필요해요.
 *
 *  · props (CheckboxProps):
 *      inputType    "checkbox" (기본) | "radio"
 *      size         number — px. 기본 24.
 *      checked      boolean — controlled 모드에서 쓰는 현재 선택 상태.
 *      onCheckedChange  (checked: boolean) => void
 *      defaultChecked   boolean — uncontrolled 초기 상태.
 *      disabled     boolean — true 면 클릭 불가 + shake.
 *      value        string — 주로 radio 에서 e.target.value 로 판별.
 *      onChange     원본 input onChange 이벤트 패스스루 (radio 패턴에서 활용).
 *      className, style, aria-*, name ... HTMLInputElement 속성 전부 패스스루.
 * ========================================================================== */

const { useState: __cbxUseState, useRef: __cbxUseRef } = React;

function __CheckboxBase({
  variant,          // "circle" | "line"  (내부 전용)
  inputType = "checkbox",
  size = 24,
  checked,
  defaultChecked,
  onCheckedChange,
  onChange,
  disabled = false,
  value,
  className = "",
  style,
  ...rest
}) {
  const isControlled = checked !== undefined;
  const [internalChecked, setInternalChecked] = __cbxUseState(!!defaultChecked);
  const currentChecked = isControlled ? !!checked : internalChecked;

  const [shake, setShake] = __cbxUseState(false);

  const handleInputChange = (e) => {
    // disabled 는 브라우저가 이미 막지만, radio 네이티브 동작을 우회하는 경우를
    // 대비해 한 번 더 차단.
    if (disabled) return;

    onChange?.(e);

    // 라디오는 항상 "선택됨" 으로만 이동 (같은 라디오를 또 눌러도 true).
    const next = inputType === "radio" ? true : !currentChecked;
    if (!isControlled) setInternalChecked(next);
    onCheckedChange?.(next);
  };

  const handleLabelClick = (e) => {
    // 라벨 클릭 → 네이티브는 input 으로 click 을 전달하지만 disabled 면 차단됨.
    // 우리는 여기서 shake 애니메이션만 트리거하고 기본 동작을 막는다.
    if (disabled) {
      e.preventDefault();
      setShake(true);
    }
  };

  const cls = [
    "tds-checkbox",
    `tds-checkbox--${variant}`,
    currentChecked && "is-checked",
    disabled && "is-disabled",
    shake && "is-shake",
    className,
  ]
    .filter(Boolean)
    .join(" ");

  const mergedStyle = {
    ...(style || {}),
    "--checkbox-size": `${size}px`,
  };

  // controlled / uncontrolled 에 따라 input 에 주는 prop 을 분기.
  const inputControlProps = isControlled
    ? { checked: !!checked }
    : { defaultChecked: !!defaultChecked };

  return (
    <label
      className={cls}
      style={mergedStyle}
      onClick={handleLabelClick}
    >
      <input
        type={inputType}
        className="tds-checkbox__input"
        disabled={disabled}
        onChange={handleInputChange}
        value={value}
        {...inputControlProps}
        {...rest}
      />
      <span
        className="tds-checkbox__visual"
        role={inputType === "radio" ? "radio" : "checkbox"}
        aria-checked={currentChecked}
        aria-disabled={disabled || undefined}
        onAnimationEnd={() => shake && setShake(false)}
      >
        <svg
          viewBox="0 0 24 24"
          className="tds-checkbox__icon"
          aria-hidden="true"
          focusable="false"
        >
          <path
            d="M5 12.5l4.5 4.5L19 7.5"
            stroke="currentColor"
            strokeWidth="2.6"
            fill="none"
            strokeLinecap="round"
            strokeLinejoin="round"
          />
        </svg>
      </span>
    </label>
  );
}

const Checkbox = {};

Checkbox.Circle = function CheckboxCircle(props) {
  return <__CheckboxBase variant="circle" {...props} />;
};
Checkbox.Line = function CheckboxLine(props) {
  return <__CheckboxBase variant="line" {...props} />;
};

window.Checkbox = Checkbox;

Object.assign(window, { Checkbox });
