// Generic master catalogs CRUD — 1 page handle 5 kind: units / materials /
// services / work-items / contract-catalog. URL `/master/catalogs/:kind` driven,
// mỗi kind có fields config riêng. Sub-tabs hiển thị 5 kind trên cùng để chuyển nhanh.
//
// [K1 — S164, Mig 70] kind thứ 5 `contract-catalog` = "Danh mục Hợp đồng"
// (SOL-CCM-SP-002, 86 dòng × 8 nhóm duyệt N1..N8). Endpoint BE
// `api/catalogs/contract-catalog` (ContractCatalogController) — cùng tiền tố
// `/catalogs/` nên tái dùng nguyên đường `/catalogs/${kind}` sẵn có, KHÔNG route mới.
import { useState, type FormEvent } from 'react'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { useParams, useNavigate } from 'react-router-dom'
import { Library, Pencil, Plus, Ruler, Package, Wrench, ListChecks, FileSpreadsheet, Trash2, Search } 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'

type Kind = 'units' | 'materials' | 'services' | 'work-items' | 'contract-catalog'

type FieldDef = {
  key: string
  label: string
  type: 'text' | 'textarea' | 'checkbox' | 'number' | 'select'
  required?: boolean
  placeholder?: string
  options?: { value: number; label: string }[]
  // Ép Number khi build payload — BE nhận `int` (ApprovalGroup / SortOrder),
  // gửi chuỗi "3" thì System.Text.Json bind fail.
  numeric?: boolean
}

// 8 nhóm duyệt N1..N8 (SOL-CCM-SP-002 — mục "Nhóm duyệt (8)").
const APPROVAL_GROUPS = [1, 2, 3, 4, 5, 6, 7, 8] as const
const APPROVAL_GROUP_OPTIONS = APPROVAL_GROUPS.map(n => ({ value: n, label: `N${n}` }))

// Pattern 14 (Tailwind JIT): KHÔNG interpolate `bg-${x}-50` — class bị purge.
// Full class literal, cycle theo (nhóm - 1) % length.
const APPROVAL_GROUP_BADGE = [
  'bg-sky-50 text-sky-700 border-sky-200',
  'bg-emerald-50 text-emerald-700 border-emerald-200',
  'bg-amber-50 text-amber-700 border-amber-200',
  'bg-violet-50 text-violet-700 border-violet-200',
  'bg-rose-50 text-rose-700 border-rose-200',
  'bg-teal-50 text-teal-700 border-teal-200',
  'bg-indigo-50 text-indigo-700 border-indigo-200',
  'bg-orange-50 text-orange-700 border-orange-200',
] as const

const KIND_CONFIG: Record<Kind, {
  label: string
  icon: React.ComponentType<{ className?: string }>
  fields: FieldDef[]
  columns: string[]
}> = {
  'units': {
    label: 'Đơn vị tính',
    icon: Ruler,
    fields: [
      { key: 'code', label: 'Mã *', type: 'text', required: true, placeholder: 'm2, kg, ngc...' },
      { key: 'name', label: 'Tên *', type: 'text', required: true, placeholder: 'Mét vuông, Kilogram...' },
      { key: 'description', label: 'Mô tả', type: 'textarea' },
    ],
    columns: ['Mã', 'Tên', 'Mô tả'],
  },
  'materials': {
    label: 'Vật tư / SP',
    icon: Package,
    fields: [
      { key: 'code', label: 'Mã SP *', type: 'text', required: true, placeholder: 'XM-PCB40' },
      { key: 'name', label: 'Tên SP *', type: 'text', required: true, placeholder: 'Xi măng PCB40' },
      { key: 'category', label: 'Nhóm', type: 'text', placeholder: 'Xi măng, Sắt thép...' },
      { key: 'defaultUnit', label: 'ĐVT mặc định', type: 'text', placeholder: 'kg, m3...' },
      { key: 'specification', label: 'Thông số kỹ thuật', type: 'textarea' },
      { key: 'originCountry', label: 'Xuất xứ', type: 'text' },
      { key: 'isActive', label: 'Đang dùng', type: 'checkbox' },
    ],
    columns: ['Mã', 'Tên', 'Nhóm', 'ĐVT', 'Trạng thái'],
  },
  'services': {
    label: 'Dịch vụ',
    icon: Wrench,
    fields: [
      { key: 'code', label: 'Mã DV *', type: 'text', required: true, placeholder: 'VC-OTO' },
      { key: 'name', label: 'Tên DV *', type: 'text', required: true, placeholder: 'Vận chuyển ô tô tải' },
      { key: 'category', label: 'Loại', type: 'text', placeholder: 'Vận chuyển, Bảo trì...' },
      { key: 'defaultUnit', label: 'ĐVT mặc định', type: 'text', placeholder: 'ca, h, lan...' },
      { key: 'description', label: 'Mô tả', type: 'textarea' },
      { key: 'isActive', label: 'Đang dùng', type: 'checkbox' },
    ],
    columns: ['Mã', 'Tên', 'Loại', 'ĐVT', 'Trạng thái'],
  },
  'work-items': {
    label: 'Hạng mục công việc',
    icon: ListChecks,
    fields: [
      { key: 'code', label: 'Mã CV *', type: 'text', required: true, placeholder: 'DAO-MONG' },
      { key: 'name', label: 'Tên CV *', type: 'text', required: true, placeholder: 'Đào móng công trình' },
      { key: 'category', label: 'Nhóm', type: 'text', placeholder: 'Phần thô, Hoàn thiện...' },
      { key: 'defaultUnit', label: 'ĐVT mặc định', type: 'text', placeholder: 'm3, m2, kg...' },
      { key: 'description', label: 'Mô tả + spec yêu cầu', type: 'textarea' },
      { key: 'isActive', label: 'Đang dùng', type: 'checkbox' },
    ],
    columns: ['Mã', 'Tên', 'Nhóm', 'ĐVT', 'Trạng thái'],
  },
  // [K1 — S164] Danh mục Hợp đồng SOL-CCM-SP-002. Shape KHÁC 4 kind cũ
  // (tenVi/tenEn thay `name`, thêm groupCode + approvalGroup + 2 cột vai ký)
  // ⇒ header + cell có nhánh riêng bên dưới, `columns` dưới đây là nguồn header.
  'contract-catalog': {
    label: 'Danh mục Hợp đồng',
    icon: FileSpreadsheet,
    fields: [
      { key: 'code', label: 'Mã *', type: 'text', required: true, placeholder: 'A1-01, B2-07, CEO-01…' },
      { key: 'groupCode', label: 'Nhóm mục *', type: 'text', required: true, placeholder: 'A1, A2, B1, C3, CEO…' },
      { key: 'tenVi', label: 'Tên tiếng Việt *', type: 'text', required: true, placeholder: 'Hợp đồng thi công xây dựng…' },
      { key: 'tenEn', label: 'Tên tiếng Anh', type: 'text', placeholder: 'Construction contract…' },
      { key: 'approvalGroup', label: 'Nhóm duyệt (N1–N8) *', type: 'select', required: true, numeric: true, options: APPROVAL_GROUP_OPTIONS },
      { key: 'sortOrder', label: 'Thứ tự trong nhóm', type: 'number', numeric: true, placeholder: '0' },
      { key: 'signerRole', label: 'Vai ký chính *', type: 'text', required: true, placeholder: 'TGĐ / GĐ Khối / TP…' },
      { key: 'initialsChain', label: 'Chuỗi ký nháy', type: 'text', placeholder: 'TBP.CCM→NV.CCM→TBP.EQU→NV.EQU' },
      { key: 'nduqNote', label: 'Ghi chú NĐUQ', type: 'textarea' },
      { key: 'isActive', label: 'Đang dùng', type: 'checkbox' },
    ],
    columns: ['Mã', 'Tên tiếng Việt', 'Tên tiếng Anh', 'Nhóm', 'Nhóm duyệt', 'Vai ký chính', 'Ký nháy', 'Trạng thái'],
  },
}

const KINDS: Kind[] = ['units', 'materials', 'services', 'work-items', 'contract-catalog']

type CatalogRow = Record<string, unknown> & { id: string; code: string; name?: string }

// Nhãn dòng dùng cho confirm xóa — kind `contract-catalog` không có `name`.
function rowLabel(row: CatalogRow): string {
  return (row.name as string) || (row.tenVi as string) || row.code
}

export function CatalogsPage() {
  const navigate = useNavigate()
  const params = useParams<{ kind?: string }>()
  const kind = (KINDS.includes(params.kind as Kind) ? params.kind : 'units') as Kind
  const config = KIND_CONFIG[kind]
  const isContractCatalog = kind === 'contract-catalog'
  const colCount = (isContractCatalog ? config.columns.length : kind === 'units' ? 2 : 5) + 1

  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: ['catalogs', kind, search],
    // kind-5: trang quản trị cần thấy CẢ dòng ngừng hiệu lực — BE List mặc định LOẠI (spec K1.c, gate-K1 F4)
    queryFn: async () => (await api.get<CatalogRow[]>(`/catalogs/${kind}`, {
      params: { q: search || undefined, includeInactive: isContractCatalog ? true : undefined },
    })).data,
  })

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

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

  function openCreate() {
    const init: Record<string, unknown> = {}
    config.fields.forEach(f => {
      // select mặc định option đầu (nhóm duyệt N1) — tránh gửi rỗng → BE
      // InclusiveBetween(1,8) reject.
      init[f.key] = f.type === 'checkbox' ? true : f.type === 'select' ? (f.options?.[0]?.value ?? '') : ''
    })
    setForm(init)
    setOpen(true)
  }
  function openEdit(row: CatalogRow) {
    const init: Record<string, unknown> = { id: row.id }
    config.fields.forEach(f => { init[f.key] = row[f.key] ?? (f.type === 'checkbox' ? false : '') })
    setForm(init)
    setOpen(true)
  }

  return (
    <div className="p-6">
      <PageHeader
        title={
          <span className="flex items-center gap-2">
            <Library className="h-5 w-5" />
            Danh mục chi tiết
          </span>
        }
        description={
          isContractCatalog
            ? 'Danh mục Hợp đồng (SOL-CCM-SP-002) — tên VN/EN, nhóm mục và nhóm duyệt N1–N8 dùng cho phiếu Kế hoạch ký kết.'
            : 'Master data dùng cho phần Chi tiết HĐ — autocomplete khi user nhập line items.'
        }
      />

      {/* Sub-tabs cho 5 kind */}
      <div className="mb-4 flex 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(`/master/catalogs/${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>

      <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="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>
              {isContractCatalog ? (
                config.columns.map(c => <th key={c} className="px-3 py-2 text-left">{c}</th>)
              ) : (
                <>
                  <th className="px-3 py-2 text-left">Mã</th>
                  <th className="px-3 py-2 text-left">Tên</th>
                  {kind !== 'units' && <th className="px-3 py-2 text-left">Nhóm/Loại</th>}
                  {kind !== 'units' && <th className="px-3 py-2 text-left">ĐVT</th>}
                  {kind !== 'units' && <th className="px-3 py-2 text-left">Trạng thái</th>}
                </>
              )}
              <th className="w-20 px-3 py-2"></th>
            </tr>
          </thead>
          <tbody className="divide-y divide-slate-100">
            {list.isLoading && (
              <tr><td colSpan={colCount} className="p-6 text-center text-slate-400">Đang tải…</td></tr>
            )}
            {!list.isLoading && (list.data?.length ?? 0) === 0 && (
              <tr><td colSpan={colCount} 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 => (
              <tr key={row.id} className="hover:bg-slate-50">
                {isContractCatalog ? (
                  <>
                    <td className="px-3 py-2 font-mono text-xs">{row.code}</td>
                    <td className="px-3 py-2">{(row.tenVi as string) || '—'}</td>
                    <td className="px-3 py-2 text-xs text-slate-600">{(row.tenEn as string) || '—'}</td>
                    <td className="px-3 py-2 font-mono text-xs text-slate-600">{(row.groupCode as string) || '—'}</td>
                    <td className="px-3 py-2">
                      <ApprovalGroupBadge value={row.approvalGroup as number} />
                    </td>
                    <td className="px-3 py-2 text-xs text-slate-600">{(row.signerRole as string) || '—'}</td>
                    <td className="px-3 py-2 text-[11px] text-slate-500">{(row.initialsChain as string) || '—'}</td>
                    <td className="px-3 py-2">
                      {(row.isActive as boolean) ? (
                        <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>
                      )}
                    </td>
                  </>
                ) : (
                  <>
                    <td className="px-3 py-2 font-mono text-xs">{row.code}</td>
                    <td className="px-3 py-2">{row.name}</td>
                    {kind !== 'units' && <td className="px-3 py-2 text-xs text-slate-600">{(row.category as string) ?? '—'}</td>}
                    {kind !== 'units' && <td className="px-3 py-2 text-xs text-slate-600">{(row.defaultUnit as string) ?? '—'}</td>}
                    {kind !== 'units' && (
                      <td className="px-3 py-2">
                        {(row.isActive as boolean) ? (
                          <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>
                        )}
                      </td>
                    )}
                  </>
                )}
                <td className="px-3 py-2">
                  <div className="flex justify-end gap-1">
                    <button
                      onClick={() => openEdit(row)}
                      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={() => {
                        if (confirm(`Xóa "${rowLabel(row)}"?`)) remove.mutate(row.id)
                      }}
                      title="Xóa"
                      className="rounded p-1 text-slate-500 hover:bg-slate-100 hover:text-red-600"
                      disabled={remove.isPending}
                    >
                      <Trash2 className="h-3.5 w-3.5" />
                    </button>
                  </div>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      <Dialog
        open={open}
        onClose={() => setOpen(false)}
        title={`${isEdit ? 'Sửa' : 'Thêm'} ${config.label.toLowerCase()}`}
        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' && 'col-span-2')}
            >
              <Label>{f.label}</Label>
              {f.type === 'text' && (
                <Input
                  value={(form[f.key] as string) ?? ''}
                  onChange={e => setForm(s => ({ ...s, [f.key]: e.target.value }))}
                  placeholder={f.placeholder}
                  required={f.required}
                />
              )}
              {f.type === 'number' && (
                <Input
                  type="number"
                  value={(form[f.key] as string | number) ?? ''}
                  onChange={e => setForm(s => ({ ...s, [f.key]: e.target.value }))}
                  placeholder={f.placeholder}
                  required={f.required}
                />
              )}
              {f.type === 'select' && (
                <select
                  value={String(form[f.key] ?? '')}
                  onChange={e => setForm(s => ({ ...s, [f.key]: e.target.value }))}
                  required={f.required}
                  className="h-9 w-full rounded-md border border-slate-300 bg-white px-2 text-sm text-slate-800 focus:border-brand-600 focus:outline-none"
                >
                  <option value="">— Chọn —</option>
                  {f.options?.map(o => (
                    <option key={o.value} value={o.value}>{o.label}</option>
                  ))}
                </select>
              )}
              {f.type === 'textarea' && (
                <Textarea
                  rows={3}
                  value={(form[f.key] as string) ?? ''}
                  onChange={e => setForm(s => ({ ...s, [f.key]: e.target.value }))}
                />
              )}
              {f.type === 'checkbox' && (
                <div className="flex items-center gap-2 pt-2">
                  <input
                    type="checkbox"
                    checked={!!form[f.key]}
                    onChange={e => setForm(s => ({ ...s, [f.key]: e.target.checked }))}
                    className="h-4 w-4 accent-brand-600"
                  />
                  <span className="text-sm text-slate-600">{f.label}</span>
                </div>
              )}
            </div>
          ))}
        </form>
      </Dialog>
    </div>
  )
}

function buildBody(kind: Kind, form: Record<string, unknown>): Record<string, unknown> {
  // Build payload tương ứng BE Create/Update command — strip empty strings → null
  const body: Record<string, unknown> = {}
  for (const f of KIND_CONFIG[kind].fields) {
    const v = form[f.key]
    // Field `numeric` map sang `int` NON-nullable ở BE (ApprovalGroup / SortOrder)
    // ⇒ rỗng phải là 0, KHÔNG được null (System.Text.Json ném khi null → int).
    if (f.numeric) {
      const n = Number(v)
      body[f.key] = v === '' || v === null || v === undefined || Number.isNaN(n) ? 0 : n
    } else if (v === '' || v === undefined) body[f.key] = null
    else body[f.key] = v
  }
  return body
}

// Badge nhóm duyệt N1..N8 — màu literal (Pattern 14), cycle theo chỉ số nhóm.
function ApprovalGroupBadge({ value }: { value: number | null | undefined }) {
  if (typeof value !== 'number' || value < 1) return <span className="text-xs text-slate-400">—</span>
  const tone = APPROVAL_GROUP_BADGE[(value - 1) % APPROVAL_GROUP_BADGE.length]
  return (
    <span className={cn('rounded-full border px-2 py-0.5 text-[10px] font-semibold', tone)}>
      N{value}
    </span>
  )
}
