// Detail content cho 1 phiếu Duyệt NCC. Flat render (no tabs): Thông tin +
// NCC + Hạng mục + Báo giá stack vertically trong 1 màn hình.
// Duyệt history + Lịch sử thay đổi → moved to Panel 3 (xem PeWorkflowPanel
// → PeApprovalsSection + PeHistorySection).
import { useRef, useState } from 'react'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { useNavigate } from 'react-router-dom'
import { toast } from 'sonner'
import { Check, Paperclip, Pencil, Plus, Trash2, Upload } from 'lucide-react'
import { Button } from '@/components/ui/Button'
import { Dialog } from '@/components/ui/Dialog'
import { Input } from '@/components/ui/Input'
import { Label } from '@/components/ui/Label'
import { Select } from '@/components/ui/Select'
import { api } from '@/lib/api'
import { getErrorMessage } from '@/lib/apiError'
import { cn } from '@/lib/cn'
import {
  PeAttachmentPurpose,
  PeAttachmentPurposeLabel,
  PurchaseEvaluationPhase,
  PurchaseEvaluationPhaseColor,
  PurchaseEvaluationPhaseLabel,
  PurchaseEvaluationTypeLabel,
  type PeAttachment,
  type PeChangelog,
  type PeDetailBundle,
  type PeDetailRow,
  type PeQuote,
  type PeSupplier,
} from '@/types/purchaseEvaluation'
import type { Supplier } from '@/types/master'

const fmtMoney = (v: number) => v.toLocaleString('vi-VN')

// Main detail content — flat render 3 section không tabs.
// Tên giữ PeDetailTabs để không break callsite (rename gây churn).
export function PeDetailTabs({
  evaluation,
  onBack,
  onDelete,
  readOnly = false,
}: {
  evaluation: PeDetailBundle
  onBack: () => void
  onDelete: () => void
  /** Menu "Duyệt" (pendingMe=1) — ẩn mọi action thêm/sửa/xóa, chỉ xem + duyệt phase. */
  readOnly?: boolean
}) {
  const navigate = useNavigate()
  const isDraft = evaluation.phase === PurchaseEvaluationPhase.DangSoanThao

  return (
    <div className="rounded-lg border border-slate-200 bg-white shadow-sm">
      <div className="flex flex-wrap items-center justify-between gap-2 border-b border-slate-200 px-5 py-3">
        <div>
          <div className="flex items-center gap-2">
            <h2 className="text-base font-semibold text-slate-900">{evaluation.tenGoiThau}</h2>
            <span
              className={cn(
                'rounded px-1.5 py-0.5 text-[11px] font-medium',
                PurchaseEvaluationPhaseColor[evaluation.phase],
              )}
            >
              {PurchaseEvaluationPhaseLabel[evaluation.phase]}
            </span>
            {readOnly && (
              <span className="rounded bg-slate-100 px-1.5 py-0.5 text-[11px] font-medium text-slate-600">
                chế độ duyệt
              </span>
            )}
          </div>
          <div className="mt-0.5 flex flex-wrap items-center gap-2 text-[12px] text-slate-500">
            <span className="font-mono">{evaluation.maPhieu ?? '—'}</span>
            <span>·</span>
            <span>{PurchaseEvaluationTypeLabel[evaluation.type]}</span>
            <span>·</span>
            <span>{evaluation.projectName}</span>
            {evaluation.drafterName && <><span>·</span><span>Soạn: {evaluation.drafterName}</span></>}
          </div>
        </div>
        <div className="flex gap-2">
          {isDraft && !readOnly && (
            <>
              <Button variant="ghost" onClick={() => navigate(`/purchase-evaluations/new?id=${evaluation.id}`)} className="gap-1.5 text-xs">
                <Pencil className="h-3.5 w-3.5" /> Sửa header
              </Button>
              <Button variant="danger" onClick={onDelete} className="gap-1.5 text-xs">
                <Trash2 className="h-3.5 w-3.5" /> Xóa
              </Button>
            </>
          )}
          <Button variant="ghost" onClick={onBack} className="text-xs">← Đóng</Button>
        </div>
      </div>

      <div className="divide-y divide-slate-200">
        <Section title="Thông tin">
          <InfoTab ev={evaluation} readOnly={readOnly} />
        </Section>
        <Section title={`NCC tham gia (${evaluation.suppliers.length})`}>
          <SuppliersTab ev={evaluation} readOnly={readOnly} />
        </Section>
        <Section title={`Hạng mục + Báo giá (${evaluation.details.length})`}>
          <ItemsTab ev={evaluation} readOnly={readOnly} />
        </Section>
      </div>
    </div>
  )
}

function Section({ title, children }: { title: string; children: React.ReactNode }) {
  return (
    <section className="px-5 py-4">
      <h3 className="mb-3 text-xs font-semibold uppercase tracking-wide text-slate-500">{title}</h3>
      {children}
    </section>
  )
}

// ===== Exports cho Panel 3 — Approvals history + Changelog =====

export function PeApprovalsSection({ ev }: { ev: PeDetailBundle }) {
  return (
    <div>
      <h3 className="mb-2 text-sm font-semibold text-slate-900">Lịch sử duyệt ({ev.approvals.length})</h3>
      <ApprovalsTab ev={ev} />
    </div>
  )
}

export function PeHistorySection({ ev }: { ev: PeDetailBundle }) {
  return (
    <div>
      <h3 className="mb-2 text-sm font-semibold text-slate-900">Lịch sử thay đổi</h3>
      <HistoryTab ev={ev} />
    </div>
  )
}

// ===== Tab: Thông tin =====
function InfoTab({ ev, readOnly = false }: { ev: PeDetailBundle; readOnly?: boolean }) {
  const canCreateContract = !readOnly && ev.phase === PurchaseEvaluationPhase.DaDuyet && !ev.contractId && ev.selectedSupplierId
  const [createOpen, setCreateOpen] = useState(false)
  return (
    <div className="space-y-4">
      <dl className="grid grid-cols-2 gap-x-6 gap-y-3 text-sm">
        <Field label="Tên gói thầu" value={ev.tenGoiThau} />
        <Field label="Dự án" value={ev.projectName} />
        <Field label="Địa điểm" value={ev.diaDiem ?? '—'} />
        <Field label="Mô tả" value={ev.moTa ?? '—'} />
        <Field label="NCC được chọn" value={ev.selectedSupplierName ?? '—'} />
        <Field label="Điều khoản thanh toán" value={ev.paymentTerms ?? '—'} />
        {ev.contractId && (
          <Field label="HĐ kế thừa" value={<a href={`/contracts/${ev.contractId}`} className="text-brand-600 hover:underline">✓ Xem HĐ</a>} />
        )}
      </dl>
      {canCreateContract && (
        <div className="rounded border border-emerald-200 bg-emerald-50 p-3">
          <div className="flex items-center justify-between gap-3">
            <div className="text-sm text-emerald-800">
              ✓ Phiếu đã duyệt. Bấm để tạo HĐ mới kế thừa NCC + hạng mục.
            </div>
            <Button onClick={() => setCreateOpen(true)} className="gap-1.5 text-xs">
              <Plus className="h-3.5 w-3.5" /> Tạo HĐ từ phiếu
            </Button>
          </div>
        </div>
      )}
      {createOpen && <CreateContractDialog evaluation={ev} onClose={() => setCreateOpen(false)} />}
    </div>
  )
}

function CreateContractDialog({ evaluation, onClose }: { evaluation: PeDetailBundle; onClose: () => void }) {
  const navigate = useNavigate()
  const [form, setForm] = useState({
    contractType: 1,
    tenHopDong: evaluation.tenGoiThau,
    bypassProcurementAndCCM: false,
  })
  const mut = useMutation({
    mutationFn: async () =>
      api.post<{ contractId: string }>(`/purchase-evaluations/${evaluation.id}/create-contract`, form),
    onSuccess: res => {
      toast.success('Đã tạo HĐ từ phiếu.')
      navigate(`/contracts/${res.data.contractId}`)
    },
    onError: e => toast.error(getErrorMessage(e)),
  })
  const typeOptions = [
    [1, 'HĐ Thầu phụ'],
    [2, 'HĐ Giao khoán'],
    [3, 'HĐ Nhà cung cấp'],
    [4, 'HĐ Dịch vụ'],
    [5, 'HĐ Mua bán'],
    [6, 'HĐ Nguyên tắc NCC'],
    [7, 'HĐ Nguyên tắc DV'],
  ] as const
  return (
    <Dialog
      open
      onClose={onClose}
      title="Tạo HĐ từ phiếu Duyệt NCC"
      footer={<>
        <Button variant="ghost" onClick={onClose}>Hủy</Button>
        <Button onClick={() => mut.mutate()} disabled={mut.isPending}>Tạo</Button>
      </>}
    >
      <div className="space-y-3">
        <p className="text-sm text-slate-500">
          NCC: <strong>{evaluation.selectedSupplierName}</strong> · Dự án: {evaluation.projectName}
        </p>
        <div>
          <Label>Loại HĐ</Label>
          <Select value={form.contractType} onChange={e => setForm({ ...form, contractType: Number(e.target.value) })}>
            {typeOptions.map(([v, lbl]) => <option key={v} value={v}>{lbl}</option>)}
          </Select>
        </div>
        <div>
          <Label>Tên HĐ</Label>
          <Input value={form.tenHopDong} onChange={e => setForm({ ...form, tenHopDong: e.target.value })} />
        </div>
        <label className="flex items-center gap-2 text-sm">
          <input
            type="checkbox"
            checked={form.bypassProcurementAndCCM}
            onChange={e => setForm({ ...form, bypassProcurementAndCCM: e.target.checked })}
          />
          Bypass CCM (áp dụng HĐ với Chủ đầu tư)
        </label>
      </div>
    </Dialog>
  )
}

function Field({ label, value }: { label: string; value: React.ReactNode }) {
  return (
    <div>
      <dt className="text-[11px] uppercase tracking-wide text-slate-400">{label}</dt>
      <dd className="mt-0.5 text-slate-800">{value}</dd>
    </div>
  )
}

// ===== Tab: NCC =====
function SuppliersTab({ ev, readOnly = false }: { ev: PeDetailBundle; readOnly?: boolean }) {
  const qc = useQueryClient()
  const [open, setOpen] = useState(false)
  const [editRow, setEditRow] = useState<PeSupplier | null>(null)

  const remove = useMutation({
    mutationFn: async (rowId: string) => api.delete(`/purchase-evaluations/${ev.id}/suppliers/${rowId}`),
    onSuccess: () => { toast.success('Đã xóa NCC.'); qc.invalidateQueries({ queryKey: ['pe-detail', ev.id] }) },
    onError: e => toast.error(getErrorMessage(e)),
  })
  const setWinner = useMutation({
    mutationFn: async (supplierId: string) =>
      api.post(`/purchase-evaluations/${ev.id}/select-winner`, { supplierId }),
    onSuccess: () => { toast.success('Đã chọn NCC thắng.'); qc.invalidateQueries({ queryKey: ['pe-detail', ev.id] }) },
    onError: e => toast.error(getErrorMessage(e)),
  })

  return (
    <div>
      {!readOnly && (
        <div className="mb-3 flex justify-end">
          <Button onClick={() => setOpen(true)} className="gap-1.5 text-xs">
            <Plus className="h-3.5 w-3.5" /> Thêm NCC
          </Button>
        </div>
      )}
      {ev.suppliers.length === 0 ? (
        <p className="text-sm text-slate-500">
          {readOnly ? 'Chưa có NCC.' : 'Chưa có NCC. Thêm NCC để bắt đầu so sánh giá.'}
        </p>
      ) : (
        <div className="overflow-x-auto">
          <table className="min-w-full text-sm">
            <thead className="bg-slate-50 text-xs uppercase text-slate-500">
              <tr>
                <th className="px-3 py-2 text-left">NCC</th>
                <th className="px-3 py-2 text-left">Liên hệ</th>
                <th className="px-3 py-2 text-left">Điều khoản TT</th>
                <th className="px-3 py-2 text-left">File đính kèm</th>
                {!readOnly && <th className="px-3 py-2"></th>}
              </tr>
            </thead>
            <tbody className="divide-y divide-slate-100">
              {ev.suppliers.map(s => (
                <tr key={s.id} className={cn('align-top', ev.selectedSupplierId === s.supplierId && 'bg-emerald-50')}>
                  <td className="px-3 py-2">
                    <div className="font-medium text-slate-900">{s.supplierName}</div>
                    {s.displayName && <div className="text-[11px] text-slate-500">{s.displayName}</div>}
                    {s.note && <div className="mt-0.5 text-[11px] text-amber-600">{s.note}</div>}
                    {readOnly && ev.selectedSupplierId === s.supplierId && (
                      <div className="mt-0.5 text-[11px] font-medium text-emerald-700">✓ NCC được chọn</div>
                    )}
                  </td>
                  <td className="px-3 py-2 text-[12px] text-slate-600">
                    {s.contactName && <div>{s.contactName}</div>}
                    {s.contactPhone && <div>{s.contactPhone}</div>}
                    {s.contactEmail && <div className="truncate">{s.contactEmail}</div>}
                  </td>
                  <td className="px-3 py-2">{s.paymentTermText ?? '—'}</td>
                  <td className="px-3 py-2">
                    <SupplierAttachmentsCell
                      evaluationId={ev.id}
                      supplierRowId={s.id}
                      attachments={ev.attachments.filter(a => a.purchaseEvaluationSupplierId === s.id)}
                      readOnly={readOnly}
                    />
                  </td>
                  {!readOnly && (
                    <td className="px-3 py-2">
                      <div className="flex justify-end gap-1">
                        <button
                          onClick={() => setWinner.mutate(s.supplierId)}
                          className={cn(
                            'rounded px-1.5 py-0.5 text-[11px]',
                            ev.selectedSupplierId === s.supplierId
                              ? 'bg-emerald-100 text-emerald-700'
                              : 'text-slate-500 hover:bg-emerald-50 hover:text-emerald-700',
                          )}
                          title="Chọn NCC thắng"
                        >
                          <Check className="h-3.5 w-3.5" />
                        </button>
                        <button
                          onClick={() => setEditRow(s)}
                          className="rounded px-1.5 py-0.5 text-slate-500 hover:bg-slate-100"
                          title="Sửa"
                        >
                          <Pencil className="h-3.5 w-3.5" />
                        </button>
                        <button
                          onClick={() => { if (confirm('Xóa NCC này khỏi phiếu?')) remove.mutate(s.id) }}
                          className="rounded px-1.5 py-0.5 text-red-500 hover:bg-red-50"
                          title="Xóa"
                        >
                          <Trash2 className="h-3.5 w-3.5" />
                        </button>
                      </div>
                    </td>
                  )}
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}

      {open && <AddSupplierDialog evaluationId={ev.id} onClose={() => setOpen(false)} />}
      {editRow && <EditSupplierDialog evaluationId={ev.id} row={editRow} onClose={() => setEditRow(null)} />}
    </div>
  )
}

function AddSupplierDialog({ evaluationId, onClose }: { evaluationId: string; onClose: () => void }) {
  const qc = useQueryClient()
  const suppliers = useQuery({
    queryKey: ['all-suppliers'],
    queryFn: async () => (await api.get<{ items: Supplier[] }>('/suppliers', { params: { pageSize: 1000 } })).data.items,
  })
  const [form, setForm] = useState({
    supplierId: '',
    displayName: '',
    contactName: '',
    contactEmail: '',
    contactPhone: '',
    paymentTermText: '',
    note: '',
  })
  const mut = useMutation({
    mutationFn: async () => api.post(`/purchase-evaluations/${evaluationId}/suppliers`, form),
    onSuccess: () => { toast.success('Đã thêm NCC.'); qc.invalidateQueries({ queryKey: ['pe-detail', evaluationId] }); onClose() },
    onError: e => toast.error(getErrorMessage(e)),
  })

  return (
    <Dialog
      open
      onClose={onClose}
      title="Thêm NCC vào phiếu"
      footer={<>
        <Button variant="ghost" onClick={onClose}>Hủy</Button>
        <Button onClick={() => mut.mutate()} disabled={!form.supplierId || mut.isPending}>Thêm</Button>
      </>}
    >
      <div className="space-y-3">
        <div>
          <Label>NCC (master)</Label>
          <Select value={form.supplierId} onChange={e => setForm({ ...form, supplierId: e.target.value })}>
            <option value="">-- Chọn --</option>
            {suppliers.data?.map(s => (
              <option key={s.id} value={s.id}>{s.code} — {s.name}</option>
            ))}
          </Select>
        </div>
        <div className="grid grid-cols-2 gap-3">
          <div><Label>Hiển thị</Label><Input value={form.displayName} onChange={e => setForm({ ...form, displayName: e.target.value })} placeholder="vd TGN-30 ngày" /></div>
          <div><Label>Điều khoản TT</Label><Input value={form.paymentTermText} onChange={e => setForm({ ...form, paymentTermText: e.target.value })} placeholder="vd 30 ngày, 300tr" /></div>
          <div><Label>Người liên hệ</Label><Input value={form.contactName} onChange={e => setForm({ ...form, contactName: e.target.value })} /></div>
          <div><Label>Điện thoại</Label><Input value={form.contactPhone} onChange={e => setForm({ ...form, contactPhone: e.target.value })} /></div>
          <div className="col-span-2"><Label>Email</Label><Input value={form.contactEmail} onChange={e => setForm({ ...form, contactEmail: e.target.value })} /></div>
          <div className="col-span-2"><Label>Ghi chú</Label><Input value={form.note} onChange={e => setForm({ ...form, note: e.target.value })} placeholder="ĐÃ CHỐT SO SÁNH LẦN 1 / ĐÀM PHÁN THÊM..." /></div>
        </div>
      </div>
    </Dialog>
  )
}

function EditSupplierDialog({ evaluationId, row, onClose }: { evaluationId: string; row: PeSupplier; onClose: () => void }) {
  const qc = useQueryClient()
  const [form, setForm] = useState({
    supplierId: row.supplierId,
    displayName: row.displayName ?? '',
    contactName: row.contactName ?? '',
    contactEmail: row.contactEmail ?? '',
    contactPhone: row.contactPhone ?? '',
    paymentTermText: row.paymentTermText ?? '',
    note: row.note ?? '',
  })
  const mut = useMutation({
    mutationFn: async () => api.put(`/purchase-evaluations/${evaluationId}/suppliers/${row.id}`, form),
    onSuccess: () => { toast.success('Đã cập nhật.'); qc.invalidateQueries({ queryKey: ['pe-detail', evaluationId] }); onClose() },
    onError: e => toast.error(getErrorMessage(e)),
  })
  return (
    <Dialog
      open
      onClose={onClose}
      title={`Sửa NCC — ${row.supplierName}`}
      footer={<>
        <Button variant="ghost" onClick={onClose}>Hủy</Button>
        <Button onClick={() => mut.mutate()} disabled={mut.isPending}>Lưu</Button>
      </>}
    >
      <div className="grid grid-cols-2 gap-3">
        <div><Label>Hiển thị</Label><Input value={form.displayName} onChange={e => setForm({ ...form, displayName: e.target.value })} /></div>
        <div><Label>Điều khoản TT</Label><Input value={form.paymentTermText} onChange={e => setForm({ ...form, paymentTermText: e.target.value })} /></div>
        <div><Label>Liên hệ</Label><Input value={form.contactName} onChange={e => setForm({ ...form, contactName: e.target.value })} /></div>
        <div><Label>Điện thoại</Label><Input value={form.contactPhone} onChange={e => setForm({ ...form, contactPhone: e.target.value })} /></div>
        <div className="col-span-2"><Label>Email</Label><Input value={form.contactEmail} onChange={e => setForm({ ...form, contactEmail: e.target.value })} /></div>
        <div className="col-span-2"><Label>Ghi chú</Label><Input value={form.note} onChange={e => setForm({ ...form, note: e.target.value })} /></div>
      </div>
    </Dialog>
  )
}

// ===== Tab: Hạng mục + Báo giá (matrix) =====
function ItemsTab({ ev, readOnly = false }: { ev: PeDetailBundle; readOnly?: boolean }) {
  const qc = useQueryClient()
  const [addOpen, setAddOpen] = useState(false)
  const [editDetail, setEditDetail] = useState<PeDetailRow | null>(null)
  const [quoteEdit, setQuoteEdit] = useState<{ detail: PeDetailRow; supplier: PeSupplier; existing: PeQuote | null } | null>(null)

  const removeDetail = useMutation({
    mutationFn: async (id: string) => api.delete(`/purchase-evaluations/${ev.id}/details/${id}`),
    onSuccess: () => { toast.success('Đã xóa hạng mục.'); qc.invalidateQueries({ queryKey: ['pe-detail', ev.id] }) },
    onError: e => toast.error(getErrorMessage(e)),
  })

  const quoteKey = (detailId: string, supplierRowId: string) =>
    ev.details.find(d => d.id === detailId)?.quotes.find(q => q.purchaseEvaluationSupplierId === supplierRowId) ?? null

  return (
    <div>
      <div className="mb-3 flex items-center justify-between">
        <p className="text-xs text-slate-500">
          {ev.suppliers.length === 0
            ? (readOnly ? 'Chưa có NCC tham gia.' : 'Thêm NCC ở tab "NCC" trước khi nhập báo giá.')
            : readOnly
              ? `${ev.details.length} hạng mục × ${ev.suppliers.length} NCC`
              : `${ev.details.length} hạng mục × ${ev.suppliers.length} NCC — click ô để nhập báo giá.`}
        </p>
        {!readOnly && (
          <Button onClick={() => setAddOpen(true)} className="gap-1.5 text-xs">
            <Plus className="h-3.5 w-3.5" /> Thêm hạng mục
          </Button>
        )}
      </div>

      {ev.details.length === 0 ? (
        <p className="text-sm text-slate-500">Chưa có hạng mục.</p>
      ) : (
        <div className="overflow-x-auto">
          <table className="min-w-full border border-slate-200 text-xs">
            <thead className="bg-slate-50 text-slate-600">
              <tr>
                <th className="sticky left-0 z-10 border-r border-slate-200 bg-slate-50 px-2 py-2 text-left">Hạng mục</th>
                <th className="border-r border-slate-200 px-2 py-2 text-right">KL</th>
                <th className="border-r border-slate-200 px-2 py-2 text-right">ĐG ngân sách</th>
                <th className="border-r border-slate-200 px-2 py-2 text-right">TT ngân sách</th>
                {ev.suppliers.map(s => (
                  <th key={s.id} className="border-r border-slate-200 px-2 py-2 text-right">
                    {s.displayName ?? s.supplierName}
                  </th>
                ))}
                {!readOnly && <th className="px-2 py-2"></th>}
              </tr>
            </thead>
            <tbody className="divide-y divide-slate-100">
              {ev.details.map(d => (
                <tr key={d.id}>
                  <td className="sticky left-0 z-10 border-r border-slate-200 bg-white px-2 py-2">
                    <div className="font-medium text-slate-900">{d.groupCode} {d.noiDung}</div>
                    <div className="text-[10px] text-slate-500">{d.groupName} · {d.donViTinh ?? ''}</div>
                  </td>
                  <td className="border-r border-slate-200 px-2 py-2 text-right font-mono">{d.khoiLuongNganSach}</td>
                  <td className="border-r border-slate-200 px-2 py-2 text-right font-mono">{fmtMoney(d.donGiaNganSach)}</td>
                  <td className="border-r border-slate-200 px-2 py-2 text-right font-mono">{fmtMoney(d.thanhTienNganSach)}</td>
                  {ev.suppliers.map(s => {
                    const q = quoteKey(d.id, s.id)
                    return (
                      <td
                        key={s.id}
                        onClick={readOnly ? undefined : () => setQuoteEdit({ detail: d, supplier: s, existing: q })}
                        className={cn(
                          'border-r border-slate-200 px-2 py-2 text-right font-mono transition',
                          !readOnly && 'cursor-pointer hover:bg-brand-50',
                          q?.isSelected && 'bg-emerald-50 font-semibold text-emerald-700',
                        )}
                      >
                        {q ? fmtMoney(q.thanhTien) : <span className="text-slate-300">—</span>}
                      </td>
                    )
                  })}
                  {!readOnly && (
                    <td className="px-2 py-2">
                      <div className="flex gap-1">
                        <button onClick={() => setEditDetail(d)} className="rounded px-1 py-0.5 text-slate-500 hover:bg-slate-100">
                          <Pencil className="h-3 w-3" />
                        </button>
                        <button onClick={() => { if (confirm('Xóa hạng mục?')) removeDetail.mutate(d.id) }} className="rounded px-1 py-0.5 text-red-500 hover:bg-red-50">
                          <Trash2 className="h-3 w-3" />
                        </button>
                      </div>
                    </td>
                  )}
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}

      {addOpen && <DetailDialog evaluationId={ev.id} row={null} onClose={() => setAddOpen(false)} />}
      {editDetail && <DetailDialog evaluationId={ev.id} row={editDetail} onClose={() => setEditDetail(null)} />}
      {quoteEdit && (
        <QuoteDialog
          evaluationId={ev.id}
          detailId={quoteEdit.detail.id}
          supplierRowId={quoteEdit.supplier.id}
          supplierName={quoteEdit.supplier.supplierName}
          itemName={quoteEdit.detail.noiDung}
          khoiLuong={quoteEdit.detail.khoiLuongThiCong || quoteEdit.detail.khoiLuongNganSach}
          existing={quoteEdit.existing}
          onClose={() => setQuoteEdit(null)}
        />
      )}
    </div>
  )
}

function DetailDialog({ evaluationId, row, onClose }: { evaluationId: string; row: PeDetailRow | null; onClose: () => void }) {
  const qc = useQueryClient()
  const [form, setForm] = useState({
    groupCode: row?.groupCode ?? 'A.I',
    groupName: row?.groupName ?? '',
    itemCode: row?.itemCode ?? '',
    noiDung: row?.noiDung ?? '',
    donViTinh: row?.donViTinh ?? '',
    khoiLuongNganSach: row?.khoiLuongNganSach ?? 0,
    khoiLuongThiCong: row?.khoiLuongThiCong ?? 0,
    donGiaNganSach: row?.donGiaNganSach ?? 0,
    thanhTienNganSach: row?.thanhTienNganSach ?? 0,
    ghiChu: row?.ghiChu ?? '',
  })
  const mut = useMutation({
    mutationFn: async () =>
      row
        ? api.put(`/purchase-evaluations/${evaluationId}/details/${row.id}`, form)
        : api.post(`/purchase-evaluations/${evaluationId}/details`, form),
    onSuccess: () => { toast.success(row ? 'Đã sửa.' : 'Đã thêm.'); qc.invalidateQueries({ queryKey: ['pe-detail', evaluationId] }); onClose() },
    onError: e => toast.error(getErrorMessage(e)),
  })

  const updateAndRecalc = (patch: Partial<typeof form>) => {
    const next = { ...form, ...patch }
    // Auto-compute ThanhTien = KL ngân sách × ĐG ngân sách
    next.thanhTienNganSach = Number(next.khoiLuongNganSach) * Number(next.donGiaNganSach)
    setForm(next)
  }

  return (
    <Dialog
      open
      onClose={onClose}
      title={(row ? 'Sửa' : 'Thêm') + ' hạng mục'}
      size="lg"
      footer={<>
        <Button variant="ghost" onClick={onClose}>Hủy</Button>
        <Button onClick={() => mut.mutate()} disabled={mut.isPending}>{row ? 'Lưu' : 'Thêm'}</Button>
      </>}
    >
      <div className="space-y-3">
        <div className="grid grid-cols-3 gap-3">
          <div><Label>Nhóm (A.I/A.II...)</Label><Input value={form.groupCode} onChange={e => setForm({ ...form, groupCode: e.target.value })} /></div>
          <div className="col-span-2"><Label>Tên nhóm</Label><Input value={form.groupName} onChange={e => setForm({ ...form, groupName: e.target.value })} placeholder="Bê tông / Phụ gia..." /></div>
          <div><Label>Mã (tùy chọn)</Label><Input value={form.itemCode} onChange={e => setForm({ ...form, itemCode: e.target.value })} /></div>
          <div className="col-span-2"><Label>Nội dung</Label><Input value={form.noiDung} onChange={e => setForm({ ...form, noiDung: e.target.value })} /></div>
          <div><Label>ĐVT</Label><Input value={form.donViTinh} onChange={e => setForm({ ...form, donViTinh: e.target.value })} /></div>
          <div><Label>KL ngân sách</Label><Input type="number" value={form.khoiLuongNganSach} onChange={e => updateAndRecalc({ khoiLuongNganSach: Number(e.target.value) })} /></div>
          <div><Label>KL thi công</Label><Input type="number" value={form.khoiLuongThiCong} onChange={e => setForm({ ...form, khoiLuongThiCong: Number(e.target.value) })} /></div>
          <div><Label>Đơn giá ngân sách</Label><Input type="number" value={form.donGiaNganSach} onChange={e => updateAndRecalc({ donGiaNganSach: Number(e.target.value) })} /></div>
          <div className="col-span-2"><Label>Thành tiền ngân sách (auto)</Label><Input type="number" value={form.thanhTienNganSach} onChange={e => setForm({ ...form, thanhTienNganSach: Number(e.target.value) })} /></div>
          <div className="col-span-3"><Label>Ghi chú</Label><Input value={form.ghiChu} onChange={e => setForm({ ...form, ghiChu: e.target.value })} /></div>
        </div>
      </div>
    </Dialog>
  )
}

function QuoteDialog({
  evaluationId, detailId, supplierRowId, supplierName, itemName, khoiLuong, existing, onClose,
}: {
  evaluationId: string
  detailId: string
  supplierRowId: string
  supplierName: string
  itemName: string
  khoiLuong: number
  existing: PeQuote | null
  onClose: () => void
}) {
  const qc = useQueryClient()
  const [form, setForm] = useState({
    bgVat: existing?.bgVat ?? 0,
    chuaVat: existing?.chuaVat ?? 0,
    thanhTien: existing?.thanhTien ?? 0,
    isSelected: existing?.isSelected ?? false,
    note: existing?.note ?? '',
  })

  const updateAndRecalc = (patch: Partial<typeof form>) => {
    const next = { ...form, ...patch }
    next.thanhTien = Number(next.chuaVat) * khoiLuong
    setForm(next)
  }

  const mut = useMutation({
    mutationFn: async () =>
      api.post(`/purchase-evaluations/${evaluationId}/quotes`, {
        purchaseEvaluationDetailId: detailId,
        purchaseEvaluationSupplierId: supplierRowId,
        ...form,
      }),
    onSuccess: () => { toast.success('Đã lưu báo giá.'); qc.invalidateQueries({ queryKey: ['pe-detail', evaluationId] }); onClose() },
    onError: e => toast.error(getErrorMessage(e)),
  })
  const del = useMutation({
    mutationFn: async () =>
      existing ? api.delete(`/purchase-evaluations/${evaluationId}/quotes/${existing.id}`) : Promise.resolve(),
    onSuccess: () => { toast.success('Đã xóa báo giá.'); qc.invalidateQueries({ queryKey: ['pe-detail', evaluationId] }); onClose() },
    onError: e => toast.error(getErrorMessage(e)),
  })

  return (
    <Dialog
      open
      onClose={onClose}
      title={`Báo giá — ${supplierName}`}
      footer={<>
        {existing && <Button variant="danger" onClick={() => del.mutate()} disabled={del.isPending}>Xóa</Button>}
        <Button variant="ghost" onClick={onClose}>Hủy</Button>
        <Button onClick={() => mut.mutate()} disabled={mut.isPending}>Lưu</Button>
      </>}
    >
      <div className="space-y-3">
        <p className="text-sm text-slate-500">Hạng mục: <strong>{itemName}</strong> · KL {khoiLuong}</p>
        <div className="grid grid-cols-3 gap-3">
          <div><Label>Đơn giá chưa VAT</Label><Input type="number" value={form.chuaVat} onChange={e => updateAndRecalc({ chuaVat: Number(e.target.value) })} /></div>
          <div><Label>Đơn giá có VAT</Label><Input type="number" value={form.bgVat} onChange={e => setForm({ ...form, bgVat: Number(e.target.value) })} /></div>
          <div><Label>Thành tiền (auto)</Label><Input type="number" value={form.thanhTien} onChange={e => setForm({ ...form, thanhTien: Number(e.target.value) })} /></div>
        </div>
        <label className="flex items-center gap-2 text-sm">
          <input type="checkbox" checked={form.isSelected} onChange={e => setForm({ ...form, isSelected: e.target.checked })} />
          Chọn NCC này cho hạng mục
        </label>
        <div><Label>Ghi chú</Label><Input value={form.note} onChange={e => setForm({ ...form, note: e.target.value })} /></div>
      </div>
    </Dialog>
  )
}

// ===== Tab: Duyệt =====
function ApprovalsTab({ ev }: { ev: PeDetailBundle }) {
  if (ev.approvals.length === 0) return <p className="text-sm text-slate-500">Chưa có bước duyệt nào.</p>
  return (
    <ol className="space-y-2">
      {ev.approvals.map(a => (
        <li key={a.id} className="rounded border border-slate-200 bg-white p-3 text-sm">
          <div className="flex items-center justify-between">
            <div>
              <span className={cn('rounded px-1.5 py-0.5 text-[11px]', PurchaseEvaluationPhaseColor[a.fromPhase])}>
                {PurchaseEvaluationPhaseLabel[a.fromPhase]}
              </span>
              <span className="mx-2">→</span>
              <span className={cn('rounded px-1.5 py-0.5 text-[11px]', PurchaseEvaluationPhaseColor[a.toPhase])}>
                {PurchaseEvaluationPhaseLabel[a.toPhase]}
              </span>
            </div>
            <span className="text-xs text-slate-500">{new Date(a.approvedAt).toLocaleString('vi-VN')}</span>
          </div>
          <div className="mt-1 text-xs text-slate-500">
            {a.approverName ?? 'Hệ thống'}{a.comment && ` · ${a.comment}`}
          </div>
        </li>
      ))}
    </ol>
  )
}

// ===== Tab: Lịch sử =====
function HistoryTab({ ev }: { ev: PeDetailBundle }) {
  const logs = useQuery({
    queryKey: ['pe-changelog', ev.id],
    queryFn: async () => (await api.get<PeChangelog[]>(`/purchase-evaluations/${ev.id}/changelogs`)).data,
  })
  if (logs.isLoading) return <p className="text-sm text-slate-500">Đang tải…</p>
  if (!logs.data || logs.data.length === 0) return <p className="text-sm text-slate-500">Chưa có lịch sử.</p>
  return (
    <ol className="space-y-1.5 text-sm">
      {logs.data.map(l => (
        <li key={l.id} className="border-l-2 border-slate-200 pl-3 py-1">
          <div className="flex items-center justify-between text-xs text-slate-500">
            <span>{l.userName ?? 'Hệ thống'}</span>
            <span>{new Date(l.createdAt).toLocaleString('vi-VN')}</span>
          </div>
          <div className="text-slate-800">{l.summary}</div>
          {l.contextNote && <div className="text-xs text-slate-500">{l.contextNote}</div>}
        </li>
      ))}
    </ol>
  )
}

// ===== Cell upload file đính kèm per-NCC =====
// 1 row = 1 NCC. User upload file báo giá (purpose=QuoteDocument mặc định) →
// POST multipart với supplierRowId. List N file hiện có + Download/Delete inline.
// Storage path: wwwroot/uploads/purchase-evaluations/{id}/{attId}_{safeName}
function SupplierAttachmentsCell({
  evaluationId,
  supplierRowId,
  attachments,
  readOnly = false,
}: {
  evaluationId: string
  supplierRowId: string
  attachments: PeAttachment[]
  readOnly?: boolean
}) {
  const qc = useQueryClient()
  const fileInputRef = useRef<HTMLInputElement>(null)

  const upload = useMutation({
    mutationFn: async (file: File) => {
      const fd = new FormData()
      fd.append('file', file)
      fd.append('supplierRowId', supplierRowId)
      fd.append('purpose', String(PeAttachmentPurpose.QuoteDocument))
      return api.post(`/purchase-evaluations/${evaluationId}/attachments`, fd, {
        headers: { 'Content-Type': 'multipart/form-data' },
      })
    },
    onSuccess: () => {
      toast.success('Đã tải lên.')
      qc.invalidateQueries({ queryKey: ['pe-detail', evaluationId] })
    },
    onError: e => toast.error(getErrorMessage(e)),
  })

  const del = useMutation({
    mutationFn: async (attId: string) =>
      api.delete(`/purchase-evaluations/${evaluationId}/attachments/${attId}`),
    onSuccess: () => {
      toast.success('Đã xóa.')
      qc.invalidateQueries({ queryKey: ['pe-detail', evaluationId] })
    },
    onError: e => toast.error(getErrorMessage(e)),
  })

  async function download(att: PeAttachment) {
    try {
      const res = await api.get(
        `/purchase-evaluations/${evaluationId}/attachments/${att.id}/download`,
        { responseType: 'blob' },
      )
      const url = window.URL.createObjectURL(res.data as Blob)
      const a = document.createElement('a')
      a.href = url
      a.download = att.fileName
      a.click()
      window.URL.revokeObjectURL(url)
    } catch (e) {
      toast.error(getErrorMessage(e))
    }
  }

  function onPick(e: React.ChangeEvent<HTMLInputElement>) {
    const f = e.target.files?.[0]
    if (f) upload.mutate(f)
    e.target.value = ''
  }

  const fmtSize = (b: number) =>
    b > 1024 * 1024 ? `${(b / 1024 / 1024).toFixed(1)}MB` : `${Math.round(b / 1024)}KB`

  return (
    <div className="space-y-1">
      {attachments.length === 0 && (
        <div className="text-[11px] italic text-slate-400">Chưa có file</div>
      )}
      {attachments.map(a => (
        <div key={a.id} className="flex items-center gap-1.5 rounded bg-slate-50 px-1.5 py-1 text-[11px]">
          <Paperclip className="h-3 w-3 shrink-0 text-slate-400" />
          <button
            onClick={() => download(a)}
            className="min-w-0 flex-1 truncate text-left text-slate-700 hover:text-brand-700 hover:underline"
            title={a.fileName}
          >
            {a.fileName}
          </button>
          <span className="shrink-0 text-[10px] text-slate-400">{fmtSize(a.fileSize)}</span>
          <span className="shrink-0 rounded bg-slate-200 px-1 text-[9px] text-slate-600">
            {PeAttachmentPurposeLabel[a.purpose] ?? ''}
          </span>
          {!readOnly && (
            <button
              onClick={() => { if (confirm(`Xóa "${a.fileName}"?`)) del.mutate(a.id) }}
              className="shrink-0 rounded px-1 text-red-500 hover:bg-red-50"
              title="Xóa"
            >
              <Trash2 className="h-3 w-3" />
            </button>
          )}
        </div>
      ))}
      {!readOnly && (
        <div>
          <input
            ref={fileInputRef}
            type="file"
            accept=".pdf,.doc,.docx,.xls,.xlsx,.png,.jpg,.jpeg,.webp"
            onChange={onPick}
            className="hidden"
          />
          <button
            onClick={() => fileInputRef.current?.click()}
            disabled={upload.isPending}
            className="inline-flex items-center gap-1 rounded border border-dashed border-slate-300 px-2 py-0.5 text-[11px] text-slate-500 hover:border-brand-300 hover:text-brand-700 disabled:opacity-50"
          >
            <Upload className="h-3 w-3" />
            {upload.isPending ? 'Đang tải…' : '+ Thêm file'}
          </button>
        </div>
      )}
    </div>
  )
}
