import { useMemo, useState } from 'react'
import Modal from '../../components/DraggableModal'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import dayjs, { type Dayjs } from 'dayjs'
import {
  Button,
  Card,
  Checkbox,
  DatePicker,
  Form,
  Input,
  Radio,
  Select,
  Space,
  Tabs,
  Tooltip,
  message } from 'antd'
import CareTable from '../../components/CareTable'
import {
  CloseOutlined,
  DownloadOutlined,
  EditOutlined,
  MailOutlined,
  PlusSquareOutlined,
  ReloadOutlined,
  SearchOutlined,
  SettingOutlined,
  TeamOutlined } from '@ant-design/icons'
import client, { apiPrefix, unwrap, type ApiResponse } from '../../api/client'
import { options } from './homesShared'

const { RangePicker } = DatePicker

type CustomerRow = {
  id: number
  grade?: string
  customerType?: string
  name?: string
  phone?: string
  phoneAlt?: string
  zipcode?: string
  address?: string
  addressDetail?: string
  employee?: string
  memo?: string
  email?: string
  gender?: string
  nationality?: string
  birthYear?: string
  birthMonth?: string
  birthDay?: string
  registeredDate?: string
  contractCount?: number
  bookingCount?: number
}

type CustomerResult = {
  total: number
  list: CustomerRow[]
  counts?: Record<string, number>
  grades?: string[]
  employees?: string[]
}

const initial = { page: 0, size: 10, tab: 'ALL' } as Record<string, unknown>

const maskName = (name?: string) => {
  if (!name) return '-'
  if (name.length <= 1) return name
  if (name.length === 2) return `${name[0]}*`
  return `${name[0]}*${name.slice(2)}`
}

const maskPhone = (phone?: string) => {
  if (!phone) return '-'
  const digits = phone.replace(/\D/g, '')
  if (digits.length < 7) return phone
  if (digits.length === 10) return `${digits.slice(0, 3)}-****-${digits.slice(6)}`
  return `${digits.slice(0, 3)}-****-${digits.slice(-4)}`
}

const splitPhone = (phone?: string, fallbackFirst = '010') => {
  const digits = (phone || '').replace(/\D/g, '')
  if (digits.length >= 10) {
    return {
      p1: digits.slice(0, 3),
      p2: digits.slice(3, digits.length - 4),
      p3: digits.slice(-4) }
  }
  return { p1: fallbackFirst, p2: '', p3: '' }
}

const fullAddress = (row: CustomerRow) => {
  const parts = [row.zipcode ? `[${row.zipcode}]` : '', row.address, row.addressDetail].filter(Boolean)
  return parts.join(' ') || ''
}

export default function CustomerPage() {
  const [form] = Form.useForm()
  const [editForm] = Form.useForm()
  const [gradeForm] = Form.useForm()
  const [changeGradeForm] = Form.useForm()
  const qc = useQueryClient()
  const [filters, setFilters] = useState<Record<string, unknown>>(initial)
  const [selected, setSelected] = useState<number[]>([])
  const [editing, setEditing] = useState<CustomerRow | null>(null)
  const [creating, setCreating] = useState(false)
  const [gradeOpen, setGradeOpen] = useState(false)
  const [changeGradeOpen, setChangeGradeOpen] = useState(false)

  const query = useQuery({
    queryKey: ['homes-customers', filters],
    queryFn: async () => {
      const { data } = await client.get<ApiResponse<CustomerResult>>(`${apiPrefix()}/homes/customers`, {
        params: {
          ...filters,
          grade: filters.tab === 'ALL' ? undefined : filters.tab } })
      return unwrap(data)
    } })

  const members = useQuery({
    queryKey: ['homes/members-options'],
    queryFn: async () => {
      const { data } = await client.get<ApiResponse<{ list: { id: number; name?: string }[] }>>(`${apiPrefix()}/homes/members`, {
        params: { page: 0, size: 200 } })
      return unwrap(data)
    } })

  const refresh = () => {
    qc.invalidateQueries({ queryKey: ['homes-customers'] })
    setSelected([])
  }

  const staffOptions = useMemo(() => {
    const fromApi = query.data?.employees || []
    const fromMembers = (members.data?.list || []).map((m) => String(m.name || '')).filter(Boolean)
    return Array.from(new Set([...fromApi, ...fromMembers, '홍길동'])).map((v) => ({ value: v, label: v }))
  }, [query.data, members.data])

  const gradeList = useMemo(
    () => query.data?.grades || ['단골', '단골1', '단골2', '단골3', '단골4'],
    [query.data?.grades],
  )

  const gradeOptions = useMemo(
    () => [{ value: '분류없음', label: '분류없음' }, ...gradeList.map((g) => ({ value: g, label: g }))],
    [gradeList],
  )

  const tabs = useMemo(
    () => [
      { key: 'ALL', label: `전체 ${query.data?.counts?.ALL ?? query.data?.total ?? 0}` },
      ...gradeList.map((g) => ({ key: g, label: `${g} ${query.data?.counts?.[g] ?? 0}` })),
    ],
    [query.data, gradeList],
  )

  const save = useMutation({
    mutationFn: async (values: Record<string, unknown>) => {
      const payload: Record<string, unknown> = {
        employee: values.employee,
        customerType: values.customerType || '개인',
        name: values.name,
        grade: values.grade || '분류없음',
        phone1: values.phone1,
        phone2: values.phone2,
        phone3: values.phone3,
        altPhone1: values.altPhone1,
        altPhone2: values.altPhone2,
        altPhone3: values.altPhone3,
        birthYear: values.birthYear,
        birthMonth: values.birthMonth,
        birthDay: values.birthDay,
        gender: values.gender,
        nationality: values.nationality,
        email: values.email,
        zipcode: values.zipcode,
        address: values.address,
        addressDetail: values.addressDetail,
        memo: values.memo,
        registeredDate: values.registeredDate
          ? dayjs(values.registeredDate as Dayjs).format('YYYY-MM-DD')
          : dayjs().format('YYYY-MM-DD') }
      if (editing) {
        const { data } = await client.put(`${apiPrefix()}/homes/customers/${editing.id}`, payload)
        return unwrap(data as ApiResponse)
      }
      const { data } = await client.post(`${apiPrefix()}/homes/customers`, payload)
      return unwrap(data as ApiResponse)
    },
    onSuccess: () => {
      message.success(editing ? '수정했습니다.' : '고객을 등록했습니다.')
      setCreating(false)
      setEditing(null)
      editForm.resetFields()
      refresh()
    },
    onError: (e: Error) => message.error(e.message) })

  const deleteMut = useMutation({
    mutationFn: async (ids: number[]) => {
      const { data } = await client.post(`${apiPrefix()}/homes/customers/delete`, { ids })
      return unwrap(data as ApiResponse<{ deleted: number }>)
    },
    onSuccess: (data) => {
      message.success(`${data.deleted}건을 삭제했습니다.`)
      refresh()
    },
    onError: (e: Error) => message.error(e.message) })

  const changeGradeMut = useMutation({
    mutationFn: async (payload: { ids: number[]; grade: string }) => {
      const { data } = await client.post(`${apiPrefix()}/homes/customers/grade`, payload)
      return unwrap(data as ApiResponse<{ updated: number }>)
    },
    onSuccess: (data) => {
      message.success(`${data.updated}건의 분류를 변경했습니다.`)
      setChangeGradeOpen(false)
      refresh()
    },
    onError: (e: Error) => message.error(e.message) })

  const saveGrades = useMutation({
    mutationFn: async (grades: string[]) => {
      const { data } = await client.put(`${apiPrefix()}/homes/customers/grades`, { grades })
      return unwrap(data as ApiResponse<{ grades: string[] }>)
    },
    onSuccess: () => {
      message.success('분류를 저장했습니다.')
      setGradeOpen(false)
      refresh()
    },
    onError: (e: Error) => message.error(e.message) })

  const setPreset = (from: Dayjs, to: Dayjs) => form.setFieldsValue({ dates: [from, to] })

  const onSearch = (values: Record<string, unknown>) => {
    const dates = values.dates as [Dayjs, Dayjs] | undefined
    const searchType = String(values.searchType || '연락처(뒷4자리)')
    const keyword = String(values.keyword || '').trim()
    setFilters({
      ...initial,
      employee: values.employee || undefined,
      customerType: values.customerType || undefined,
      history: values.history || undefined,
      searchType,
      phoneTail: searchType.includes('뒷4') && keyword ? keyword : undefined,
      q: searchType.includes('뒷4') ? undefined : keyword || undefined,
      dateFrom: dates?.[0]?.format('YYYY-MM-DD'),
      dateTo: dates?.[1]?.format('YYYY-MM-DD'),
      page: 0,
      size: values.size ?? filters.size ?? 10,
      tab: filters.tab })
  }

  const reset = () => {
    form.resetFields()
    form.setFieldsValue({ size: 10, searchType: '연락처(뒷4자리)' })
    setFilters(initial)
  }

  const openCreate = () => {
    setEditing(null)
    setCreating(true)
    editForm.setFieldsValue({
      employee: staffOptions[0]?.value || '홍길동',
      customerType: '개인',
      name: undefined,
      grade: '분류없음',
      phone1: '010',
      phone2: '',
      phone3: '',
      altPhone1: '010',
      altPhone2: '',
      altPhone3: '',
      birthYear: undefined,
      birthMonth: undefined,
      birthDay: undefined,
      gender: undefined,
      nationality: undefined,
      email: undefined,
      zipcode: undefined,
      address: undefined,
      addressDetail: undefined,
      memo: undefined,
      registeredDate: dayjs() })
  }

  const openEdit = (row: CustomerRow) => {
    setCreating(false)
    setEditing(row)
    const phone = splitPhone(row.phone)
    const alt = splitPhone(row.phoneAlt, '010')
    editForm.setFieldsValue({
      employee: row.employee,
      customerType: row.customerType || '개인',
      name: row.name,
      grade: row.grade || '분류없음',
      phone1: phone.p1,
      phone2: phone.p2,
      phone3: phone.p3,
      altPhone1: alt.p1,
      altPhone2: alt.p2,
      altPhone3: alt.p3,
      birthYear: row.birthYear,
      birthMonth: row.birthMonth,
      birthDay: row.birthDay,
      gender: row.gender,
      nationality: row.nationality,
      email: row.email,
      zipcode: row.zipcode,
      address: row.address,
      addressDetail: row.addressDetail,
      memo: row.memo,
      registeredDate: row.registeredDate ? dayjs(row.registeredDate) : dayjs() })
  }

  const searchAddress = () => {
    message.info('주소검색(데모) — 직접 입력해 주세요.')
    editForm.setFieldsValue({
      zipcode: editForm.getFieldValue('zipcode') || '06236',
      address: editForm.getFieldValue('address') || '서울특별시 강남구' })
  }

  const download = async () => {
    try {
      const { data } = await client.get(`${apiPrefix()}/homes/customers/export`, {
        params: { ...filters, grade: filters.tab === 'ALL' ? undefined : filters.tab },
        responseType: 'blob' })
      const url = URL.createObjectURL(data)
      const a = document.createElement('a')
      a.href = url
      a.download = '고객관리.csv'
      a.click()
      URL.revokeObjectURL(url)
    } catch {
      message.error('엑셀 다운로드에 실패했습니다.')
    }
  }

  const openGradeSettings = () => {
    gradeForm.setFieldsValue({ gradesText: gradeList.join('\n') })
    setGradeOpen(true)
  }

  const columns = [
    {
      title: (
        <Checkbox
          checked={!!query.data?.list?.length && selected.length === query.data.list.length}
          indeterminate={selected.length > 0 && selected.length < (query.data?.list?.length || 0)}
          onChange={(e) => setSelected(e.target.checked ? (query.data?.list || []).map((r) => r.id) : [])}
        />
      ),
      width: 42,
      render: (_: unknown, row: CustomerRow) => (
        <Checkbox
          checked={selected.includes(row.id)}
          onChange={(e) => setSelected((prev) => (e.target.checked ? [...prev, row.id] : prev.filter((id) => id !== row.id)))}
        />
      ) },
    {
      title: '등록일',
      dataIndex: 'registeredDate',
      width: 110,
      sorter: (a: CustomerRow, b: CustomerRow) => String(a.registeredDate || '').localeCompare(String(b.registeredDate || '')) },
    {
      title: '분류',
      dataIndex: 'grade',
      width: 80,
      render: (v: string) => (v && v !== '분류없음' ? v : '-') },
    { title: '구분', dataIndex: 'customerType', width: 70 },
    {
      title: '고객명',
      dataIndex: 'name',
      width: 90,
      render: (v: string) => maskName(v) },
    {
      title: '연락처',
      dataIndex: 'phone',
      width: 130,
      render: (v: string) => maskPhone(v) },
    {
      title: '보조연락처',
      dataIndex: 'phoneAlt',
      width: 130,
      render: (v: string) => (v ? maskPhone(v) : '-') },
    {
      title: '주소',
      dataIndex: 'address',
      width: 70,
      align: 'center' as const,
      render: (_: string, row: CustomerRow) => {
        const addr = fullAddress(row)
        return addr ? (
          <Tooltip title={addr}>
            <MailOutlined className="memo-icon" />
          </Tooltip>
        ) : '-'
      } },
    {
      title: '메모',
      dataIndex: 'memo',
      width: 60,
      align: 'center' as const,
      render: (v: string) => (v ? (
        <Tooltip title={v}>
          <MailOutlined className="memo-icon" />
        </Tooltip>
      ) : '-') },
    {
      title: '계약',
      dataIndex: 'contractCount',
      width: 60,
      align: 'center' as const,
      render: (v: number) => (v ? v : '-') },
    {
      title: '예약',
      dataIndex: 'bookingCount',
      width: 60,
      align: 'center' as const,
      render: (v: number) => (v ? v : '-') },
    { title: '등록직원', dataIndex: 'employee', width: 90 },
    {
      title: '관리',
      width: 64,
      fixed: 'right' as const,
      align: 'center' as const,
      render: (_: unknown, row: CustomerRow) => (
        <Button
          size="small"
          type="primary"
          className="customer-manage-btn"
          icon={<EditOutlined />}
          onClick={() => openEdit(row)}
        />
      ) },
  ]

  const modalOpen = creating || Boolean(editing)

  return (
    <div className="stock-page customer-manage-page">
      <div className="stock-title">
        <div>
          <h2>
            <TeamOutlined className="product-title-icon" />
            고객관리
          </h2>
          <p>등록되어 있는 고객의 정보를 관리하실 수 있습니다.</p>
        </div>
        <Space className="stock-title-actions" wrap>
          <Button
            disabled={!selected.length}
            onClick={() => {
              if (!selected.length) {
                message.warning('분류를 변경할 고객을 선택하세요.')
                return
              }
              changeGradeForm.setFieldsValue({ grade: '단골' })
              setChangeGradeOpen(true)
            }}
          >
            분류변경
          </Button>
          <Button
            disabled={!selected.length}
            loading={deleteMut.isPending}
            onClick={() => {
              if (!selected.length) {
                message.warning('삭제할 고객을 선택하세요.')
                return
              }
              deleteMut.mutate(selected)
            }}
          >
            삭제
          </Button>
          <Button className="customer-register-btn" type="primary" icon={<PlusSquareOutlined />} onClick={openCreate}>
            고객 등록
          </Button>
        </Space>
      </div>

      <Card className="stock-filter-card" size="small">
        <Form
          form={form}
          layout="inline"
          className="balance-filter"
          initialValues={{ size: 10, searchType: '연락처(뒷4자리)' }}
          onFinish={onSearch}
        >
          <div className="stock-filter-row">
            <Form.Item name="dates">
              <RangePicker className="w-230" placeholder={['YYYY-MM-DD', 'YYYY-MM-DD']} />
            </Form.Item>
            <Space.Compact className="sheet-presets">
              <Button onClick={() => setPreset(dayjs(), dayjs())}>오늘</Button>
              <Button onClick={() => setPreset(dayjs().subtract(6, 'day'), dayjs())}>1주일</Button>
              <Button onClick={() => setPreset(dayjs().startOf('month'), dayjs().endOf('month'))}>당월</Button>
              <Button onClick={() => setPreset(dayjs().subtract(1, 'month').startOf('month'), dayjs().subtract(1, 'month').endOf('month'))}>전월</Button>
              <Button onClick={() => setPreset(dayjs().subtract(2, 'month').startOf('month'), dayjs().subtract(2, 'month').endOf('month'))}>전전월</Button>
            </Space.Compact>
            <Button className="sheet-clear" icon={<CloseOutlined />} onClick={() => form.setFieldValue('dates', undefined)} />
          </div>
          <div className="stock-filter-row">
            <Form.Item name="employee">
              <Select allowClear showSearch placeholder="등록직원" className="w-120" options={staffOptions} optionFilterProp="label" />
            </Form.Item>
            <Form.Item name="customerType">
              <Select allowClear placeholder="구분" className="w-110" options={options(['개인', '사업자'])} />
            </Form.Item>
            <Form.Item name="history">
              <Select allowClear placeholder="이력" className="w-110" options={options(['계약', '예약', '없음'])} />
            </Form.Item>
            <Form.Item name="searchType">
              <Select
                className="w-140"
                options={options(['연락처(뒷4자리)', '고객명', '연락처', '주소'])}
              />
            </Form.Item>
            <Form.Item name="keyword">
              <Input placeholder="검색어" className="w-140" allowClear />
            </Form.Item>
            <Button type="primary" htmlType="submit" icon={<SearchOutlined />}>검색</Button>
            <Button icon={<ReloadOutlined />} onClick={reset}>초기화</Button>
            <Form.Item name="size" className="sheet-size">
              <Select
                className="w-150"
                options={[10, 15, 30, 50, 100].map((n) => ({ value: n, label: `목록 ${n}개씩 보기` }))}
                onChange={(size) => {
                  form.setFieldValue('size', size)
                  setFilters((v) => ({ ...v, size, page: 0 }))
                }}
              />
            </Form.Item>
          </div>
        </Form>
      </Card>

      <Card className="stock-table-card" size="small">
        <div className="stock-table-actions">
          <Tabs
            activeKey={String(filters.tab)}
            onChange={(tab) => setFilters((v) => ({ ...v, tab, page: 0 }))}
            items={tabs}
          />
          <Space>
            <Button type="link" icon={<SettingOutlined />} onClick={openGradeSettings}>분류설정</Button>
            <Button type="link" icon={<DownloadOutlined />} onClick={download}>엑셀다운로드</Button>
          </Space>
        </div>
        <CareTable
          rowKey="id"
          size="small"
          loading={query.isLoading}
          dataSource={query.data?.list}
          columns={columns}
          scroll={{ x: 1200 }}
          pagination={{
            current: Number(filters.page) + 1,
            pageSize: Number(filters.size),
            total: query.data?.total,
            showSizeChanger: false,
            onChange: (page) => setFilters((v) => ({ ...v, page: page - 1 })) }}
          locale={{ emptyText: '등록된 자료가 없습니다.' }}
        />
      </Card>

      <Modal
        title={editing ? '고객 수정' : '고객 등록'}
        open={modalOpen}
        onCancel={() => { setCreating(false); setEditing(null) }}
        footer={null}
        destroyOnHidden
        width={620}
        className="customer-modal"
      >
        <Form
          form={editForm}
          layout="horizontal"
          labelCol={{ flex: '110px' }}
          wrapperCol={{ flex: 1 }}
          onFinish={(values) => save.mutate(values)}
          className="balance-edit-form"
        >
          <Form.Item name="employee" label="등록직원" rules={[{ required: true, message: '등록직원을 선택하세요' }]}>
            <Select options={staffOptions} showSearch optionFilterProp="label" />
          </Form.Item>
          <Form.Item name="customerType" label="고객구분" rules={[{ required: true, message: '고객구분을 선택하세요' }]}>
            <Radio.Group options={[{ value: '개인', label: '개인' }, { value: '사업자', label: '사업자' }]} />
          </Form.Item>
          <Form.Item name="name" label="고객명" rules={[{ required: true, message: '고객명을 입력하세요' }]}>
            <Input />
          </Form.Item>
          <Form.Item label="분류">
            <Space.Compact className="full-width">
              <Form.Item name="grade" noStyle>
                <Select options={gradeOptions} style={{ width: '100%' }} />
              </Form.Item>
              <Button icon={<SettingOutlined />} onClick={openGradeSettings}>설정</Button>
            </Space.Compact>
          </Form.Item>
          <Form.Item label="연락처" required>
            <Space.Compact>
              <Form.Item name="phone1" noStyle rules={[{ required: true, message: '연락처를 입력하세요' }]}>
                <Input style={{ width: 70 }} maxLength={3} />
              </Form.Item>
              <Form.Item name="phone2" noStyle rules={[{ required: true, message: '연락처를 입력하세요' }]}>
                <Input style={{ width: 80 }} maxLength={4} />
              </Form.Item>
              <Form.Item name="phone3" noStyle rules={[{ required: true, message: '연락처를 입력하세요' }]}>
                <Input style={{ width: 80 }} maxLength={4} />
              </Form.Item>
            </Space.Compact>
          </Form.Item>
          <Form.Item label="보조연락처">
            <Space.Compact>
              <Form.Item name="altPhone1" noStyle><Input style={{ width: 70 }} maxLength={3} /></Form.Item>
              <Form.Item name="altPhone2" noStyle><Input style={{ width: 80 }} maxLength={4} /></Form.Item>
              <Form.Item name="altPhone3" noStyle><Input style={{ width: 80 }} maxLength={4} /></Form.Item>
            </Space.Compact>
          </Form.Item>
          <Form.Item label="생년월일">
            <Space.Compact>
              <Form.Item name="birthYear" noStyle><Input style={{ width: 80 }} placeholder="생년" maxLength={4} /></Form.Item>
              <Form.Item name="birthMonth" noStyle><Input style={{ width: 70 }} placeholder="월" maxLength={2} /></Form.Item>
              <Form.Item name="birthDay" noStyle><Input style={{ width: 70 }} placeholder="일" maxLength={2} /></Form.Item>
            </Space.Compact>
          </Form.Item>
          <Form.Item label="성별/국적">
            <Space>
              <Form.Item name="gender" noStyle>
                <Select allowClear placeholder="- 성별 -" className="w-120" options={options(['남', '여'])} />
              </Form.Item>
              <Form.Item name="nationality" noStyle>
                <Select allowClear placeholder="- 국적 -" className="w-120" options={options(['내국인', '외국인'])} />
              </Form.Item>
            </Space>
          </Form.Item>
          <Form.Item name="email" label="이메일">
            <Input />
          </Form.Item>
          <Form.Item label="주소">
            <div className="booking-address-row">
              <Button onClick={searchAddress}>주소검색</Button>
              <Form.Item name="zipcode" noStyle>
                <Input className="booking-zip" placeholder="우편번호" />
              </Form.Item>
            </div>
            <Form.Item name="address" noStyle>
              <Input className="booking-addr-detail" placeholder="기본주소" style={{ marginBottom: 8 }} />
            </Form.Item>
            <Form.Item name="addressDetail" noStyle>
              <Input className="booking-addr-detail" placeholder="상세주소" />
            </Form.Item>
          </Form.Item>
          <Form.Item name="memo" label="메모">
            <Input.TextArea rows={3} />
          </Form.Item>
          <div className="balance-modal-footer">
            <Button className="customer-submit-btn" type="primary" htmlType="submit" loading={save.isPending}>
              {editing ? '수정합니다' : '등록'}
            </Button>
            <Button onClick={() => { setCreating(false); setEditing(null) }}>취소</Button>
          </div>
        </Form>
      </Modal>

      <Modal
        title="분류설정"
        open={gradeOpen}
        onCancel={() => setGradeOpen(false)}
        footer={null}
        destroyOnHidden
        width={420}
      >
        <Form
          form={gradeForm}
          layout="vertical"
          onFinish={(values) => {
            const grades = String(values.gradesText || '')
              .split(/\n|,/)
              .map((s) => s.trim())
              .filter(Boolean)
            saveGrades.mutate(grades)
          }}
        >
          <Form.Item name="gradesText" label="분류 (줄바꿈으로 구분)" rules={[{ required: true, message: '분류를 입력하세요' }]}>
            <Input.TextArea rows={6} placeholder={'단골\n단골1\n단골2\n단골3\n단골4'} />
          </Form.Item>
          <div className="balance-modal-footer">
            <Button className="customer-submit-btn" type="primary" htmlType="submit" loading={saveGrades.isPending}>저장</Button>
            <Button onClick={() => setGradeOpen(false)}>취소</Button>
          </div>
        </Form>
      </Modal>

      <Modal
        title="분류변경"
        open={changeGradeOpen}
        onCancel={() => setChangeGradeOpen(false)}
        footer={null}
        destroyOnHidden
        width={400}
      >
        <Form
          form={changeGradeForm}
          layout="vertical"
          onFinish={(values) => changeGradeMut.mutate({ ids: selected, grade: String(values.grade) })}
        >
          <Form.Item name="grade" label="변경할 분류" rules={[{ required: true, message: '분류를 선택하세요' }]}>
            <Select options={gradeOptions} />
          </Form.Item>
          <div className="balance-modal-footer">
            <Button className="customer-submit-btn" type="primary" htmlType="submit" loading={changeGradeMut.isPending}>변경</Button>
            <Button onClick={() => setChangeGradeOpen(false)}>취소</Button>
          </div>
        </Form>
      </Modal>
    </div>
  )
}
