"use client";

import { type ChangeEvent, type ComponentPropsWithRef, type ReactNode } from "react";
import { cx } from "../../utils";

export type FoxSegmentedControlItemSize = "lg" | "md" | "sm" | "xsm";

/**
 * 네이티브 `<input type="radio">`가 받는 것을 그대로 넘겨받는다 — name·value·checked·
 * defaultChecked·disabled·required·form 등. 의미가 겹치는 것만 걷어내고 아래에서 다시 정의한다.
 */
type NativeRadioProps = Omit<
  ComponentPropsWithRef<"input">,
  "type" | "size" | "className" | "children" | "hidden" | "onChange"
>;

export interface FoxSegmentedControlItemProps extends NativeRadioProps {
  size?: FoxSegmentedControlItemSize;
  label: ReactNode;
  /** 글자 앞에 붙는 아이콘. 넘기지 않으면 자리를 만들지 않는다. */
  icon?: ReactNode;
  /**
   * 이 칸이 선택될 때 부른다. 값이 첫 인자다 — 네이티브 `onChange`를 `Omit`으로 걷어내고
   * 그 자리를 대신한다(`FoxRadio`와 같은 방식).
   */
  onChange?: (value: string, event: ChangeEvent<HTMLInputElement>) => void;
  /** 참이면 렌더하지 않는다(DOM에 남지 않는다). */
  hidden?: boolean;
  /** 배치 조정용. 모양이 달라야 하면 여기 말고 모디파이어를 추가한다. */
  className?: string;
}

/** `Record`로 고정해 크기를 추가하면 항목 누락이 타입 에러가 되게 한다. */
const SIZE_CLASS: Record<FoxSegmentedControlItemSize, string> = {
  lg: "fox-segmented-control-item--lg",
  md: "fox-segmented-control-item--md",
  sm: "fox-segmented-control-item--sm",
  xsm: "fox-segmented-control-item--xsm",
};

/**
 * @fox 세그먼티드 컨트롤의 칸 하나. 상태를 갖지 않는다 — 켜짐 여부는 네이티브
 * `<input type="radio">`가 소유한다.
 *
 * `name`이 같은 칸끼리는 브라우저가 그룹으로 묶어 단일 선택·화살표 이동·폼 전송을 처리한다.
 * `FoxSegmentedControl`이 하는 일은 그 `name`을 통일하고 테두리로 감싸는 것뿐이다.
 *
 * 루트가 `<label>`이라 글자나 아이콘 어디를 눌러도 선택된다. 배경·글자색은 CSS가 input의
 * `:checked`·`:disabled`를 보고 그리므로, 비제어로 써도 모양이 어긋나지 않는다.
 *
 * ⚠️ 스타일은 이 파일이 import하지 않는다 — 호스트 앱이 `@use "@fox/styles/components"`
 * (또는 개별 파티셜)로 한 번 불러와야 한다.
 */
export function FoxSegmentedControlItem({
  size = "lg",
  label,
  icon,
  onChange,
  hidden = false,
  className,
  ...rest
}: FoxSegmentedControlItemProps) {
  if (hidden) {
    return null;
  }

  // 라디오는 켜질 때만 change가 뛴다(꺼질 때는 안 뛴다). 그래도 명시적으로 걸러 두면
  // 브라우저가 달라져도 "선택될 때"라는 계약이 흔들리지 않는다(`FoxRadio`와 같은 근거).
  const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
    if (event.target.checked) {
      onChange?.(event.target.value, event);
    }
  };

  return (
    <label className={cx("fox-segmented-control-item", SIZE_CLASS[size], className)}>
      {/* `:has()`가 찾을 대상이고 형제 선택자의 기준이기도 하므로 맨 앞에 둔다. */}
      <input
        {...rest}
        type="radio"
        className="fox-segmented-control-item__input"
        onChange={handleChange}
      />
      {icon ? (
        <span className="fox-segmented-control-item__icon" aria-hidden="true">
          {icon}
        </span>
      ) : null}
      <span className="fox-segmented-control-item__label">{label}</span>
    </label>
  );
}
