// HRM Configs CRUD — 1 page handle 4 kind: leave-types / holidays / shifts / ot-policies.
// URL `/hrm/configs/:kind` driven, mỗi kind có fields config riêng + columns table riêng.
// Sub-tabs hiển thị 4 kind trên cùng để chuyển nhanh.
// Pattern 12-bis × 16-bis cookie-cutter mirror Master/Catalogs/CatalogsPage.tsx
// (9th cumulative S35 — declarative KIND_CONFIG Record + URL `:kind` param).
import { useState, type ComponentType, type FormEvent } from 'react'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { useParams, useNavigate } from 'react-router-dom'
import { Settings2, Calendar, Clock, Pencil, Plus, Plane, Repeat, Trash2, Search, Car, IdCard } from 'lucide-react'
import { toast } from 'sonner'
import { PageHeader } from '@/components/PageHeader'
import { Button } from '@/components/ui/Button'
import { Input } from '@/components/ui/Input'
import { Label } from '@/components/ui/Label'
import { Textarea } from '@/components/ui/Textarea'
import { Dialog } from '@/components/ui/Dialog'
import { api } from '@/lib/api'
import { getErrorMessage } from '@/lib/apiError'
import { cn } from '@/lib/cn'
import type { HrmConfigKind } from '@/types/hrm-config'

type Kind = HrmConfigKind

type FieldType = 'text' | 'textarea' | 'checkbox' | 'number' | 'date' | 'time' | 'multiselect-weekday'

type FieldDef = {
  key: string
  label: string
  type: FieldType
  required?: boolean
  placeholder?: string
  step?: number  // for number type
}

const WEEKDAY_OPTIONS: Array<{ value: string; label: string }> = [
  { value: 'Mon', label: 'T2' },
  { value: 'Tue', label: 'T3' },
  { value: 'Wed', label: 'T4' },
  { value: 'Thu', label: 'T5' },
  { value: 'Fri', label: 'T6' },
  { value: 'Sat', label: 'T7' },
  { value: 'Sun', label: 'CN' },
]

const KIND_CONFIG: Record<Kind, {
  label: string
  description: string
  icon: ComponentType<{ className?: string }>
  fields: FieldDef[]
  columns: string[]
}> = {
  'leave-types': {
    label: 'Loại phép',
    description: 'Danh mục loại phép (phép năm, ốm, không lương...) — dùng khi nhân viên đăng ký nghỉ.',
    icon: Plane,
    fields: [
      { key: 'code', label: 'Mã *', type: 'text', required: true, placeholder: 'ANNUAL, SICK, UNPAID...' },
      { key: 'name', label: 'Tên *', type: 'text', required: true, placeholder: 'Phép năm, Phép ốm...' },
      { key: 'daysPerYear', label: 'Số ngày/năm', type: 'number', step: 0.5, placeholder: '12, 30...' },
      { key: 'isPaid', label: 'Có lương', type: 'checkbox' },
      { key: 'requiresAttachment', label: 'Yêu cầu giấy tờ đính kèm', type: 'checkbox' },
      { key: 'description', label: 'Mô tả', type: 'textarea' },
    ],
    columns: ['Mã', 'Tên', 'Ngày/năm', 'Có lương', 'Đính kèm', 'Trạng thái'],
  },
  'holidays': {
    label: 'Ngày lễ',
    description: 'Lịch nghỉ lễ theo năm — Tết Dương lịch, Tết Âm, 30/4, 1/5, 2/9...',
    icon: Calendar,
    fields: [
      { key: 'year', label: 'Năm *', type: 'number', required: true, placeholder: '2026' },
      { key: 'date', label: 'Ngày *', type: 'date', required: true },
      { key: 'name', label: 'Tên ngày lễ *', type: 'text', required: true, placeholder: 'Tết Dương lịch, 30/4...' },
      { key: 'isRecurring', label: 'Lặp lại hàng năm (vd 1/1)', type: 'checkbox' },
      { key: 'isPaid', label: 'Có lương', type: 'checkbox' },
      { key: 'description', label: 'Mô tả', type: 'textarea' },
    ],
    columns: ['Năm', 'Ngày', 'Tên', 'Lặp lại', 'Có lương', 'Trạng thái'],
  },
  'shifts': {
    label: 'Ca làm việc',
    description: 'Cấu hình ca làm việc (hành chính, ca sáng, ca chiều...) — dùng cho timesheet + chấm công.',
    icon: Clock,
    fields: [
      { key: 'code', label: 'Mã *', type: 'text', required: true, placeholder: 'HC, CA1, CA2...' },
      { key: 'name', label: 'Tên *', type: 'text', required: true, placeholder: 'Hành chính, Ca sáng...' },
      { key: 'startTime', label: 'Giờ bắt đầu *', type: 'time', required: true },
      { key: 'endTime', label: 'Giờ kết thúc *', type: 'time', required: true },
      { key: 'breakMinutes', label: 'Nghỉ giữa ca (phút)', type: 'number', placeholder: '60' },
      { key: 'workDays', label: 'Ngày làm việc trong tuần *', type: 'multiselect-weekday', required: true },
      { key: 'description', label: 'Mô tả', type: 'textarea' },
    ],
    columns: ['Mã', 'Tên', 'Thời gian', 'Nghỉ', 'Ngày làm', 'Trạng thái'],
  },
  'ot-policies': {
    label: 'Chính sách OT',
    description: 'Cấu hình hệ số OT + giới hạn giờ/ngày, giờ/tháng, giờ/năm.',
    icon: Repeat,
    fields: [
      { key: 'code', label: 'Mã *', type: 'text', required: true, placeholder: 'STANDARD' },
      { key: 'name', label: 'Tên *', type: 'text', required: true, placeholder: 'Chính sách OT chuẩn' },
      { key: 'multiplierWeekday', label: 'Hệ số ngày thường *', type: 'number', required: true, step: 0.1, placeholder: '1.5' },
      { key: 'multiplierWeekend', label: 'Hệ số cuối tuần *', type: 'number', required: true, step: 0.1, placeholder: '2.0' },
      { key: 'multiplierHoliday', label: 'Hệ số ngày lễ *', type: 'number', required: true, step: 0.1, placeholder: '3.0' },
      { key: 'maxHoursPerDay', label: 'Max giờ/ngày *', type: 'number', required: true, placeholder: '4' },
      { key: 'maxHoursPerMonth', label: 'Max giờ/tháng *', type: 'number', required: true, placeholder: '40' },
      { key: 'maxHoursPerYear', label: 'Max giờ/năm *', type: 'number', required: true, placeholder: '200' },
      { key: 'description', label: 'Mô tả', type: 'textarea' },
    ],
    columns: ['Mã', 'Tên', 'Hệ số WD/WE/HL', 'Max h/year', 'Trạng thái'],
  },
  'vehicles': {
    label: 'Xe công',
    description: 'Danh mục xe công ty — dùng khi đăng ký đặt xe.',
    icon: Car,
    fields: [
      { key: 'code', label: 'Mã *', type: 'text', required: true, placeholder: 'XE-01...' },
      { key: 'name', label: 'Tên xe *', type: 'text', required: true, placeholder: 'Toyota Innova 7 chỗ' },
      { key: 'licensePlate', label: 'Biển số *', type: 'text', required: true, placeholder: '30A-12345' },
      { key: 'seatCount', label: 'Số chỗ', type: 'number', placeholder: '7' },
      { key: 'description', label: 'Mô tả', type: 'textarea' },
    ],
    columns: ['Mã', 'Tên xe', 'Biển số', 'Số chỗ', 'Trạng thái'],
  },
  'drivers': {
    label: 'Tài xế',
    description: 'Danh mục tài xế — dùng khi đăng ký đặt xe.',
    icon: IdCard,
    fields: [
      { key: 'code', label: 'Mã *', type: 'text', required: true, placeholder: 'TX-01...' },
      { key: 'name', label: 'Họ tên *', type: 'text', required: true, placeholder: 'Nguyễn Văn Tài' },
      { key: 'phoneNumber', label: 'SĐT *', type: 'text', required: true, placeholder: '0901xxxxxx' },
      { key: 'licenseNumber', label: 'Số GPLX *', type: 'text', required: true, placeholder: '012345678' },
      { key: 'licenseClass', label: 'Hạng *', type: 'text', required: true, placeholder: 'B2, C, D, E' },
      { key: 'description', label: 'Mô tả', type: 'textarea' },
    ],
    columns: ['Mã', 'Họ tên', 'SĐT', 'Số GPLX', 'Hạng', 'Trạng thái'],
  },
}

const KINDS: Kind[] = ['leave-types', 'holidays', 'shifts', 'ot-policies', 'vehicles', 'drivers']

type ConfigRow = Record<string, unknown> & { id: string; isActive?: boolean }

export function HrmConfigsPage() {
  const navigate = useNavigate()
  const params = useParams<{ kind?: string }>()
  const kind = (KINDS.includes(params.kind as Kind) ? params.kind : 'leave-types') as Kind
  const config = KIND_CONFIG[kind]

  const qc = useQueryClient()
  const [search, setSearch] = useState('')
  const [open, setOpen] = useState(false)
  const [form, setForm] = useState<Record<string, unknown>>({})
  const isEdit = !!form.id

  const list = useQuery({
    queryKey: ['hrm-configs', kind, search],
    queryFn: async () => (await api.get<ConfigRow[]>(`/hrm-configs/${kind}`, { params: { q: search || undefined } })).data,
  })

  const save = useMutation({
    mutationFn: async () => {
      const body = buildBody(kind, form, isEdit)
      if (isEdit) await api.put(`/hrm-configs/${kind}/${form.id}`, { id: form.id, ...body })
      else await api.post(`/hrm-configs/${kind}`, body)
    },
    onSuccess: () => {
      toast.success(isEdit ? 'Đã lưu' : 'Đã thêm')
      qc.invalidateQueries({ queryKey: ['hrm-configs', kind] })
      setOpen(false)
      setForm({})
    },
    onError: err => toast.error(getErrorMessage(err)),
  })

  const remove = useMutation({
    mutationFn: async (id: string) => { await api.delete(`/hrm-configs/${kind}/${id}`) },
    onSuccess: () => {
      toast.success('Đã xóa')
      qc.invalidateQueries({ queryKey: ['hrm-configs', kind] })
    },
    onError: err => toast.error(getErrorMessage(err)),
  })

  function openCreate() {
    const init: Record<string, unknown> = {}
    config.fields.forEach(f => {
      if (f.type === 'checkbox') init[f.key] = false
      else if (f.type === 'number') init[f.key] = ''
      else init[f.key] = ''
    })
    // Per-kind smart defaults
    if (kind === 'leave-types') init.isPaid = true
    if (kind === 'holidays') {
      init.year = new Date().getFullYear()
      init.isPaid = true
    }
    if (kind === 'shifts') {
      init.startTime = '08:00'
      init.endTime = '17:00'
      init.breakMinutes = 60
      init.workDays = 'Mon,Tue,Wed,Thu,Fri'
    }
    if (kind === 'ot-policies') {
      init.multiplierWeekday = 1.5
      init.multiplierWeekend = 2.0
      init.multiplierHoliday = 3.0
      init.maxHoursPerDay = 4
      init.maxHoursPerMonth = 40
      init.maxHoursPerYear = 200
    }
    setForm(init)
    setOpen(true)
  }

  function openEdit(row: ConfigRow) {
    const init: Record<string, unknown> = { id: row.id, isActive: row.isActive ?? true }
    config.fields.forEach(f => {
      const raw = row[f.key]
      if (f.type === 'checkbox') init[f.key] = !!raw
      else if (f.type === 'time' && typeof raw === 'string') init[f.key] = raw.slice(0, 5)  // 'HH:mm:ss' → 'HH:mm'
      else init[f.key] = raw ?? (f.type === 'number' ? '' : '')
    })
    setForm(init)
    setOpen(true)
  }

  return (
    <div className="p-6">
      <PageHeader
        title={
          <span className="flex items-center gap-2">
            <Settings2 className="h-5 w-5" />
            Cấu hình HRM
          </span>
        }
        description="Catalog cấu hình dùng chung cho module Nhân sự — Loại phép / Ngày lễ / Ca làm việc / Chính sách OT."
      />

      {/* Sub-tabs cho 4 kind */}
      <div className="mb-4 flex flex-wrap gap-1 border-b border-slate-200">
        {KINDS.map(k => {
          const KIcon = KIND_CONFIG[k].icon
          const active = k === kind
          return (
            <button
              key={k}
              onClick={() => navigate(`/hrm/configs/${k}`)}
              className={cn(
                '-mb-px flex items-center gap-1.5 border-b-2 px-3 py-2 text-sm transition',
                active
                  ? 'border-brand-600 font-semibold text-brand-700'
                  : 'border-transparent text-slate-500 hover:text-slate-700',
              )}
            >
              <KIcon className="h-4 w-4" />
              {KIND_CONFIG[k].label}
            </button>
          )
        })}
      </div>

      <p className="mb-3 text-xs text-slate-500">{config.description}</p>

      <div className="mb-3 flex gap-2">
        <div className="relative max-w-md flex-1">
          <Search className="pointer-events-none absolute left-2.5 top-2.5 h-4 w-4 text-slate-400" />
          <Input
            value={search}
            onChange={e => setSearch(e.target.value)}
            placeholder={kind === 'holidays' ? 'Tìm theo tên ngày lễ…' : 'Tìm theo mã / tên…'}
            className="pl-8"
          />
        </div>
        <Button onClick={openCreate}>
          <Plus className="h-4 w-4" />
          Thêm {config.label.toLowerCase()}
        </Button>
      </div>

      <div className="overflow-x-auto rounded-lg border border-slate-200 bg-white">
        <table className="min-w-full text-sm">
          <thead className="bg-slate-50 text-[11px] uppercase tracking-wider text-slate-500">
            <tr>
              {config.columns.map(c => (
                <th key={c} className="px-3 py-2 text-left">{c}</th>
              ))}
              <th className="w-20 px-3 py-2"></th>
            </tr>
          </thead>
          <tbody className="divide-y divide-slate-100">
            {list.isLoading && (
              <tr><td colSpan={config.columns.length + 1} className="p-6 text-center text-slate-400">Đang tải…</td></tr>
            )}
            {!list.isLoading && (list.data?.length ?? 0) === 0 && (
              <tr><td colSpan={config.columns.length + 1} className="p-6 text-center text-slate-400">Chưa có dữ liệu — bấm Thêm để tạo mới.</td></tr>
            )}
            {list.data?.map(row => (
              <RowRenderer
                key={row.id}
                kind={kind}
                row={row}
                onEdit={() => openEdit(row)}
                onRemove={() => {
                  const label = (row.name as string) ?? (row.code as string) ?? row.id
                  if (confirm(`Xóa "${label}"?`)) remove.mutate(row.id)
                }}
                removing={remove.isPending}
              />
            ))}
          </tbody>
        </table>
      </div>

      <Dialog
        open={open}
        onClose={() => setOpen(false)}
        title={`${isEdit ? 'Sửa' : 'Thêm'} ${config.label.toLowerCase()}`}
        size="lg"
        footer={
          <>
            <Button variant="outline" onClick={() => setOpen(false)}>Hủy</Button>
            <Button
              onClick={(e: FormEvent) => { e.preventDefault(); save.mutate() }}
              disabled={save.isPending}
            >
              {save.isPending ? 'Đang lưu…' : (isEdit ? 'Lưu' : 'Thêm')}
            </Button>
          </>
        }
      >
        <form
          onSubmit={(e: FormEvent) => { e.preventDefault(); save.mutate() }}
          className="grid grid-cols-2 gap-3"
        >
          {config.fields.map(f => (
            <div
              key={f.key}
              className={cn(
                'space-y-1',
                (f.type === 'textarea' || f.type === 'multiselect-weekday') && 'col-span-2',
              )}
            >
              <Label>{f.label}</Label>
              {renderField(f, form[f.key], v => setForm(s => ({ ...s, [f.key]: v })))}
            </div>
          ))}
          {isEdit && (
            <div className="col-span-2 space-y-1">
              <Label>Trạng thái</Label>
              <div className="flex items-center gap-2 pt-1">
                <input
                  type="checkbox"
                  checked={!!form.isActive}
                  onChange={e => setForm(s => ({ ...s, isActive: e.target.checked }))}
                  className="h-4 w-4 accent-brand-600"
                />
                <span className="text-sm text-slate-600">Đang dùng</span>
              </div>
            </div>
          )}
        </form>
      </Dialog>
    </div>
  )
}

// ========== Helper components / functions ==========

function RowRenderer({
  kind, row, onEdit, onRemove, removing,
}: {
  kind: Kind
  row: ConfigRow
  onEdit: () => void
  onRemove: () => void
  removing: boolean
}) {
  return (
    <tr className="hover:bg-slate-50">
      {renderCells(kind, row)}
      <td className="px-3 py-2">
        <div className="flex justify-end gap-1">
          <button
            onClick={onEdit}
            title="Sửa"
            className="rounded p-1 text-slate-500 hover:bg-slate-100 hover:text-brand-600"
          >
            <Pencil className="h-3.5 w-3.5" />
          </button>
          <button
            onClick={onRemove}
            title="Xóa"
            className="rounded p-1 text-slate-500 hover:bg-slate-100 hover:text-red-600"
            disabled={removing}
          >
            <Trash2 className="h-3.5 w-3.5" />
          </button>
        </div>
      </td>
    </tr>
  )
}

function renderCells(kind: Kind, row: ConfigRow) {
  const active = row.isActive as boolean | undefined
  const statusBadge = active ? (
    <span className="rounded-full bg-emerald-50 px-2 py-0.5 text-[10px] text-emerald-700">Đang dùng</span>
  ) : (
    <span className="rounded-full bg-slate-100 px-2 py-0.5 text-[10px] text-slate-500">Tạm tắt</span>
  )
  const checkBadge = (v: boolean | undefined) => v
    ? <span className="text-[11px] text-emerald-700">✓</span>
    : <span className="text-[11px] text-slate-400">—</span>

  if (kind === 'leave-types') {
    return (
      <>
        <td className="px-3 py-2 font-mono text-xs">{row.code as string}</td>
        <td className="px-3 py-2">{row.name as string}</td>
        <td className="px-3 py-2 text-xs text-slate-600">{Number(row.daysPerYear ?? 0)}</td>
        <td className="px-3 py-2">{checkBadge(row.isPaid as boolean)}</td>
        <td className="px-3 py-2">{checkBadge(row.requiresAttachment as boolean)}</td>
        <td className="px-3 py-2">{statusBadge}</td>
      </>
    )
  }
  if (kind === 'holidays') {
    const dateStr = row.date as string | null
    const formatted = dateStr ? formatDateVi(dateStr) : '—'
    return (
      <>
        <td className="px-3 py-2 text-xs">{row.year as number}</td>
        <td className="px-3 py-2 font-mono text-xs">{formatted}</td>
        <td className="px-3 py-2">{row.name as string}</td>
        <td className="px-3 py-2">{checkBadge(row.isRecurring as boolean)}</td>
        <td className="px-3 py-2">{checkBadge(row.isPaid as boolean)}</td>
        <td className="px-3 py-2">{statusBadge}</td>
      </>
    )
  }
  if (kind === 'shifts') {
    const start = (row.startTime as string ?? '').slice(0, 5)
    const end = (row.endTime as string ?? '').slice(0, 5)
    return (
      <>
        <td className="px-3 py-2 font-mono text-xs">{row.code as string}</td>
        <td className="px-3 py-2">{row.name as string}</td>
        <td className="px-3 py-2 font-mono text-xs text-slate-600">{start} – {end}</td>
        <td className="px-3 py-2 text-xs text-slate-600">{row.breakMinutes as number ?? 0}'</td>
        <td className="px-3 py-2 text-xs text-slate-600">{formatWorkDays(row.workDays as string ?? '')}</td>
        <td className="px-3 py-2">{statusBadge}</td>
      </>
    )
  }
  if (kind === 'vehicles') {
    return (
      <>
        <td className="px-3 py-2 font-mono text-xs">{row.code as string}</td>
        <td className="px-3 py-2">{row.name as string}</td>
        <td className="px-3 py-2 font-mono text-xs text-slate-600">{row.licensePlate as string}</td>
        <td className="px-3 py-2 text-xs text-slate-600">{(row.seatCount as number) ?? '—'}</td>
        <td className="px-3 py-2">{statusBadge}</td>
      </>
    )
  }
  if (kind === 'drivers') {
    return (
      <>
        <td className="px-3 py-2 font-mono text-xs">{row.code as string}</td>
        <td className="px-3 py-2">{row.name as string}</td>
        <td className="px-3 py-2 text-xs text-slate-600">{(row.phoneNumber as string) || '—'}</td>
        <td className="px-3 py-2 font-mono text-xs text-slate-600">{(row.licenseNumber as string) || '—'}</td>
        <td className="px-3 py-2 text-xs text-slate-600">{(row.licenseClass as string) || '—'}</td>
        <td className="px-3 py-2">{statusBadge}</td>
      </>
    )
  }
  // ot-policies
  const mw = Number(row.multiplierWeekday ?? 0)
  const me = Number(row.multiplierWeekend ?? 0)
  const mh = Number(row.multiplierHoliday ?? 0)
  return (
    <>
      <td className="px-3 py-2 font-mono text-xs">{row.code as string}</td>
      <td className="px-3 py-2">{row.name as string}</td>
      <td className="px-3 py-2 font-mono text-xs text-slate-600">x{mw} / x{me} / x{mh}</td>
      <td className="px-3 py-2 text-xs text-slate-600">{Number(row.maxHoursPerYear ?? 0)}h</td>
      <td className="px-3 py-2">{statusBadge}</td>
    </>
  )
}

function renderField(field: FieldDef, value: unknown, onChange: (v: unknown) => void) {
  switch (field.type) {
    case 'text':
      return (
        <Input
          type="text"
          value={(value as string) ?? ''}
          onChange={e => onChange(e.target.value)}
          required={field.required}
          placeholder={field.placeholder}
        />
      )
    case 'date':
      return (
        <Input
          type="date"
          value={(value as string) ?? ''}
          onChange={e => onChange(e.target.value)}
          required={field.required}
        />
      )
    case 'time':
      return (
        <Input
          type="time"
          value={(value as string) ?? ''}
          onChange={e => onChange(e.target.value)}
          required={field.required}
        />
      )
    case 'number':
      return (
        <Input
          type="number"
          step={field.step ?? 1}
          value={value === '' || value === undefined || value === null ? '' : String(value)}
          onChange={e => onChange(e.target.value === '' ? '' : Number(e.target.value))}
          required={field.required}
          placeholder={field.placeholder}
        />
      )
    case 'textarea':
      return (
        <Textarea
          rows={3}
          value={(value as string) ?? ''}
          onChange={e => onChange(e.target.value)}
          placeholder={field.placeholder}
        />
      )
    case 'checkbox':
      return (
        <div className="flex items-center gap-2 pt-2">
          <input
            type="checkbox"
            checked={!!value}
            onChange={e => onChange(e.target.checked)}
            className="h-4 w-4 accent-brand-600"
          />
          <span className="text-sm text-slate-600">{field.label.replace(/ \*$/, '')}</span>
        </div>
      )
    case 'multiselect-weekday': {
      const selected = ((value as string) ?? '').split(',').map(s => s.trim()).filter(Boolean)
      return (
        <div className="flex flex-wrap gap-2 pt-1">
          {WEEKDAY_OPTIONS.map(o => {
            const checked = selected.includes(o.value)
            return (
              <label
                key={o.value}
                className={cn(
                  'flex items-center gap-1 rounded-md border px-2.5 py-1 text-xs cursor-pointer transition',
                  checked
                    ? 'border-brand-500 bg-brand-50 text-brand-700'
                    : 'border-slate-200 bg-white text-slate-600 hover:bg-slate-50',
                )}
              >
                <input
                  type="checkbox"
                  checked={checked}
                  onChange={e => {
                    const next = e.target.checked
                      ? [...selected, o.value]
                      : selected.filter(x => x !== o.value)
                    // Preserve canonical order (Mon→Sun) to keep DB string stable
                    const canonical = WEEKDAY_OPTIONS.map(opt => opt.value).filter(v => next.includes(v))
                    onChange(canonical.join(','))
                  }}
                  className="h-3.5 w-3.5 accent-brand-600"
                />
                <span>{o.label}</span>
              </label>
            )
          })}
        </div>
      )
    }
  }
}

function buildBody(kind: Kind, form: Record<string, unknown>, isEdit: boolean): Record<string, unknown> {
  const fields = KIND_CONFIG[kind].fields.map(f => f.key)
  const body: Record<string, unknown> = {}
  for (const k of fields) {
    const f = KIND_CONFIG[kind].fields.find(x => x.key === k)!
    const v = form[k]
    if (f.type === 'checkbox') {
      body[k] = !!v
    } else if (f.type === 'number') {
      body[k] = v === '' || v === undefined || v === null ? 0 : Number(v)
    } else if (f.type === 'textarea' || f.type === 'text') {
      // Nullable text → null if empty (BE Description? expects null, not '')
      body[k] = v === '' || v === undefined ? null : v
    } else {
      body[k] = v ?? null
    }
  }
  if (isEdit) body.isActive = !!form.isActive
  return body
}

function formatDateVi(iso: string): string {
  // ISO 'YYYY-MM-DD' → 'DD/MM'
  const [, m, d] = iso.split('-')
  if (!m || !d) return iso
  return `${d}/${m}`
}

const WEEKDAY_LABEL_MAP: Record<string, string> = Object.fromEntries(
  WEEKDAY_OPTIONS.map(o => [o.value, o.label]),
)

function formatWorkDays(csv: string): string {
  return csv.split(',').map(s => s.trim()).filter(Boolean).map(v => WEEKDAY_LABEL_MAP[v] ?? v).join(', ')
}
