'use client';

import { useId, type ReactNode } from 'react';
import { FoxChip } from '@fox/core/components/fox-chip';
import { FoxChipArea } from '@fox/core/components/fox-chip-area';
import { FoxFormLabel } from '@fox/core/components/fox-form-label';
import { FoxPhoneNumber } from '@fox/core/components/fox-phone-number';
import { FoxSelect } from '@fox/core/components/fox-select';
import {
  ADMIN_MENU_OPTIONS,
  ADMIN_ROLE_OPTIONS,
} from '@/lib/domain/admin-member';
import type { AdminMemberFormErrors } from '@/lib/domain/admin-member-form';
import styles from './admin-member-modal.module.scss';

interface AdminMemberFormFieldsProps {
  /** 숫자만 담긴 휴대전화번호. 하이픈은 화면이 그리고 값에는 넣지 않는다. */
  phoneNumber: string;
  onPhoneNumberChange: (phoneNumber: string) => void;
  roleCode: string;
  onRoleCodeChange: (roleCode: string) => void;
  menuCodes: string[];
  onMenuCodesChange: (menuCodes: string[]) => void;
  /**
   * 휴대전화 번호와 역할 선택 **사이**에 들어가는 이메일 칸. 두 시안이 이 자리에 서로 다른 것을
   * 놓아(등록은 도메인 셀렉트가 붙은 form-email, 수정은 단일 input) 슬롯으로 받는다 — 자리 순서는
   * 두 시안이 같으므로 여기가 갖고, 무엇을 놓을지는 각 팝업이 정한다.
   */
  emailField: ReactNode;
  errors: AdminMemberFormErrors;
}

/**
 * 등록·수정 팝업이 공유하는 입력 항목 — 휴대전화 번호 / (이메일 슬롯) / 역할 선택 / 메뉴 선택.
 * 두 시안(ADM_ADM_102_p 5227:2035 / ADM_ADM_103_p 5227:3351)에서 자리와 순서가 같은 부분이다.
 * 이름·ID·비밀번호·잠김여부는 두 시안이 서로 달라 각 팝업이 직접 그린다.
 *
 * 세 칸 모두 @fox의 제어 위젯이라 값이 FormData에 실리지 않는다(`FoxSelect`는 네이티브 select가
 * 아니라 버튼+리스트박스, `FoxPhoneNumber`·칩도 마찬가지다). 그래서 값은 호출부가 들고, 제출용
 * hidden input을 여기서 함께 낸다 — 폼 제출 규약(Server Action + FormData)을 그대로 두기 위해서다.
 *
 * ⚠️ **메뉴 선택은 저장되지 않는다.** 백엔드에 관리자별 메뉴 권한이 테이블·VO·SQL 어디에도 없다
 * (`/api/v1/common/menu`는 개인 북마크용이다). 시안대로 자리는 유지하되 **필수 검증은 걸지 않는다**
 * (사용자 확정) — 저장되지도 않는 값 때문에 등록이 막히면 안 되기 때문이다. 권한 API가 생기면
 * 여기는 그대로 두고 Server Action이 값을 넘기기만 하면 된다.
 */
export function AdminMemberFormFields({
  phoneNumber,
  onPhoneNumberChange,
  roleCode,
  onRoleCodeChange,
  menuCodes,
  onMenuCodesChange,
  emailField,
  errors,
}: AdminMemberFormFieldsProps) {
  const phoneLabelId = useId();
  const menuLabelId = useId();

  const allMenuValues = ADMIN_MENU_OPTIONS.map((option) => option.value);
  const isAllSelected = menuCodes.length === allMenuValues.length;

  function toggleMenu(value: string) {
    onMenuCodesChange(
      menuCodes.includes(value)
        ? menuCodes.filter((code) => code !== value)
        : [...menuCodes, value]
    );
  }

  return (
    <>
      {/* 칸이 셋으로 나뉘어 있어 `<label htmlFor>`가 가리킬 대상이 하나가 아니다 — 이름 연결은
          감싼 group이 aria-labelledby로 한다(FoxFormLabel의 `as="span"`이 그 용도다). */}
      <div className={styles.field} role="group" aria-labelledby={phoneLabelId}>
        <FoxFormLabel as="span" id={phoneLabelId} requirement="required">
          휴대전화 번호
        </FoxFormLabel>
        <FoxPhoneNumber
          type="unit"
          value={phoneNumber}
          onChange={onPhoneNumberChange}
          message={errors.phoneNumber}
          invalid={Boolean(errors.phoneNumber)}
        />
      </div>
      <input type="hidden" name="phoneNumber" value={phoneNumber} />

      {emailField}

      <FoxSelect
        size="md"
        label="역할 선택"
        options={ADMIN_ROLE_OPTIONS.map((option) => ({
          value: option.value,
          label: option.label,
        }))}
        value={roleCode}
        onValueChange={onRoleCodeChange}
        error={Boolean(errors.roleCode)}
        hint={errors.roleCode}
      />
      <input type="hidden" name="roleCode" value={roleCode} />

      <div className={styles.field} role="group" aria-labelledby={menuLabelId}>
        <FoxFormLabel as="span" id={menuLabelId} requirement="required">
          메뉴 선택
        </FoxFormLabel>
        <FoxChipArea size="md" wrap labelledBy={menuLabelId}>
          {/* 시안의 첫 칩. 개별 메뉴가 아니라 나머지를 한 번에 켜고 끄는 조각이다. */}
          <FoxChip
            type="check"
            label="전체"
            checked={isAllSelected}
            onCheckedChange={(checked) =>
              onMenuCodesChange(checked ? allMenuValues : [])
            }
          />
          {ADMIN_MENU_OPTIONS.map((option) => (
            <FoxChip
              key={option.value}
              type="check"
              label={option.label}
              checked={menuCodes.includes(option.value)}
              onCheckedChange={() => toggleMenu(option.value)}
            />
          ))}
        </FoxChipArea>
      </div>
      {menuCodes.map((code) => (
        <input key={code} type="hidden" name="menuCodes" value={code} />
      ))}
    </>
  );
}
