// [W2 KHKK — S161 2026-07-29] Danh sách "Kế hoạch ký kết HĐ" (GĐ2).
// Khuôn `pages/office/ProposalsListPage.tsx` (PURO layout: ui/PageHeader + hàng
// KpiCard làm bộ lọc + bảng + phân trang). File MIRROR SHA256 identical với
// fe-admin counterpart.
//
// URL vào từ menu (Layout.tsx staticMap — chỗ thứ 4 của Pattern 16-bis):
//   Khkk_List     → /khkk/list
//   Khkk_Pending  → /khkk/list?filter=ChoDuyet
//   Khkk_Approved → /khkk/list?filter=DaDuyet
//   Khkk_Deleted  → /khkk/list?view=deleted
// 🔴 Chip lọc chỉ đổi STATE, KHÔNG ghi lại URL — giữ nguyên URL của leaf đang đứng
// nên menu không sáng nhầm (bug UAT S155 khi URL leaf trùng URL user tự lọc).
import { useMemo, useState, type ReactNode } from 'react'
import { useQuery } from '@tanstack/react-query'
import { useNavigate, useSearchParams } from 'react-router-dom'
import {
  Plus, Search, FileCheck, FileEdit, SendHorizontal,
  CheckCircle2, Undo2, XCircle, Layers, Inbox, Trash2,
} from 'lucide-react'
import { PageHeader } from '@/components/ui/PageHeader'
import { KpiCard } from '@/components/ui/KpiCard'
import { Button } from '@/components/ui/Button'
import { Input } from '@/components/ui/Input'
import { PipelineTreePanel } from '@/components/pipeline/PipelineTreePanel'
import { api } from '@/lib/api'
import { cn } from '@/lib/cn'
import {
  KHKK_PHASE_BADGE,
  KHKK_PHASE_LABELS,
  KhkkPhase,
  type KhkkListItemDto,
  type KhkkPhaseValue,
  type PagedResult,
} from '@/types/khkk'

const PAGE_SIZE = 20

// Tên phase trong query `?filter=` → int (URL đọc được, không dính số ma thuật).
const FILTER_TO_PHASE: Record<string, KhkkPhaseValue> = {
  DangSoanThao: KhkkPhase.DangSoanThao,
  ChoDuyet: KhkkPhase.ChoDuyet,
  DaDuyet: KhkkPhase.DaDuyet,
  TraLai: KhkkPhase.TraLai,
  TuChoi: KhkkPhase.TuChoi,
}

function formatVnd(n: number | null): string {
  if (n === null || n === undefined) return '—'
  return n.toLocaleString('vi-VN') + ' đ'
}

function formatDate(iso: string): string {
  const d = new Date(iso)
  return d.toLocaleDateString('vi-VN', { day: '2-digit', month: '2-digit', year: 'numeric' })
}

export function KhkkListPage() {
  const navigate = useNavigate()
  const [searchParams] = useSearchParams()
  const initialFilter = searchParams.get('filter')
  const deletedView = searchParams.get('view') === 'deleted'

  const [phase, setPhase] = useState<KhkkPhaseValue | null>(
    initialFilter ? (FILTER_TO_PHASE[initialFilter] ?? null) : null,
  )
  const [search, setSearch] = useState('')
  const [page, setPage] = useState(1)

  const list = useQuery({
    queryKey: ['khkk-list', { phase, search, page, deletedView }],
    queryFn: async () => {
      // Phiếu xóa mềm bị HasQueryFilter che ở list thường — chỉ endpoint riêng
      // `/deleted` thấy (mirror PE `/purchase-evaluations/deleted`, S155).
      const url = deletedView ? '/contract-signing-plans/deleted' : '/contract-signing-plans'
      return (await api.get<PagedResult<KhkkListItemDto>>(url, {
        params: {
          phase: deletedView ? undefined : (phase ?? undefined),
          search: search.trim() || undefined,
          page,
          pageSize: PAGE_SIZE,
        },
      })).data
    },
  })

  const items = list.data?.items ?? []
  const total = list.data?.total ?? 0
  const totalPages = list.data?.totalPages ?? 1

  // Presentation-only: đếm trên trang đang tải (không fetch thêm). Card đang active
  // hiện `total` thật từ server; card khác chỉ là gợi ý nhìn nhanh.
  const countByPhase = useMemo(() => {
    const acc: Record<number, number> = { 1: 0, 2: 0, 3: 0, 98: 0, 99: 0 }
    for (const p of items) acc[p.phase] = (acc[p.phase] ?? 0) + 1
    return acc
  }, [items])

  const phaseCards: Array<{
    value: KhkkPhaseValue | null
    label: string
    icon: ReactNode
    accent: 'brand' | 'teal' | 'violet' | 'amberx' | 'greenx'
    count: number
  }> = [
    { value: null, label: 'Tất cả', icon: <Layers className="h-4 w-4" />, accent: 'brand', count: phase === null ? total : items.length },
    { value: KhkkPhase.DangSoanThao, label: KHKK_PHASE_LABELS[1], icon: <FileEdit className="h-4 w-4" />, accent: 'violet', count: phase === 1 ? total : countByPhase[1] },
    { value: KhkkPhase.ChoDuyet, label: KHKK_PHASE_LABELS[2], icon: <SendHorizontal className="h-4 w-4" />, accent: 'amberx', count: phase === 2 ? total : countByPhase[2] },
    { value: KhkkPhase.DaDuyet, label: KHKK_PHASE_LABELS[3], icon: <CheckCircle2 className="h-4 w-4" />, accent: 'greenx', count: phase === 3 ? total : countByPhase[3] },
    { value: KhkkPhase.TraLai, label: KHKK_PHASE_LABELS[98], icon: <Undo2 className="h-4 w-4" />, accent: 'violet', count: phase === 98 ? total : countByPhase[98] },
    { value: KhkkPhase.TuChoi, label: KHKK_PHASE_LABELS[99], icon: <XCircle className="h-4 w-4" />, accent: 'amberx', count: phase === 99 ? total : countByPhase[99] },
  ]

  return (
    <div className="space-y-5">
      <PageHeader
        eyebrow="Giai đoạn 2"
        title={deletedView ? 'Kế hoạch ký kết HĐ — đã xóa' : 'Kế hoạch ký kết HĐ'}
        subtitle={
          deletedView
            ? 'Phiếu đã xóa mềm — chỉ xem danh sách'
            : 'Chốt giá per-NCC trúng thầu + căn cứ hồ sơ trước khi ký hợp đồng'
        }
        icon={deletedView ? <Trash2 className="h-5 w-5" /> : <FileCheck className="h-5 w-5" />}
        accent="brand"
        actions={
          deletedView ? undefined : (
            <Button onClick={() => navigate('/khkk/create')}>
              <Plus className="mr-2 h-4 w-4" />
              Lập kế hoạch
            </Button>
          )
        }
      />

      {/* [S162] Cây toàn trình bám trái + nội dung cũ giữ nguyên bên phải (owner
          chốt AskUser 30-07: "áp cả các trang GĐ khác"). `minmax(0,1fr)` để bảng
          7 cột không thổi vỡ lưới ở 1366; `<lg` cây xếp trên và tự thu gọn. */}
      <div className="grid gap-5 lg:grid-cols-[19rem_minmax(0,1fr)] xl:grid-cols-[21rem_minmax(0,1fr)]">
        <PipelineTreePanel currentStage={2} />

        <div className="min-w-0 space-y-5">
      {!deletedView && (
        <div className="grid grid-cols-2 gap-3 sm:grid-cols-3 xl:grid-cols-6">
          {phaseCards.map((c) => (
            <KpiCard
              key={c.value ?? 'all'}
              label={c.label}
              value={c.count}
              icon={c.icon}
              accent={c.accent}
              active={phase === c.value}
              onClick={() => {
                setPhase(c.value)
                setPage(1)
              }}
            />
          ))}
        </div>
      )}

      <div className="card-accent flex items-center gap-3 px-4 py-3" style={{ ['--accent' as string]: 'var(--color-brand-500)' }}>
        <Search className="h-4 w-4 shrink-0 text-slate-400" />
        <Input
          value={search}
          onChange={(e) => {
            setSearch(e.target.value)
            setPage(1)
          }}
          placeholder="Tìm mã kế hoạch, mã phiếu hoặc tên gói thầu..."
          className="max-w-md border-0 bg-transparent px-0 shadow-none focus-visible:ring-0"
        />
      </div>

      <div className="card-accent overflow-hidden" style={{ ['--accent' as string]: 'var(--color-brand-500)' }}>
        {/* [S162] Cột trái ăn ~19rem ⇒ bảng 7 cột cuộn ngang trong thẻ thay vì
            tràn ra ngoài lưới trên laptop 1366. */}
        <div className="overflow-x-auto">
        <table className="w-full text-sm">
          <thead className="border-b border-slate-200 bg-slate-50/70">
            <tr>
              <th className="label-eyebrow px-4 py-2.5 text-left">Mã kế hoạch</th>
              <th className="label-eyebrow px-4 py-2.5 text-left">Gói thầu</th>
              <th className="label-eyebrow px-4 py-2.5 text-left">Dự án</th>
              <th className="label-eyebrow px-4 py-2.5 text-left">Trạng thái</th>
              <th className="label-eyebrow px-4 py-2.5 text-right">Tổng đề xuất</th>
              <th className="label-eyebrow px-4 py-2.5 text-left">Người soạn</th>
              <th className="label-eyebrow px-4 py-2.5 text-left">Ngày tạo</th>
            </tr>
          </thead>
          <tbody>
            {list.isLoading && (
              <tr>
                <td colSpan={7} className="px-4 py-8 text-center text-slate-500">
                  Đang tải...
                </td>
              </tr>
            )}
            {!list.isLoading && items.length === 0 && (
              <tr>
                <td colSpan={7} className="px-4 py-10 text-center text-slate-500">
                  <span
                    className="icon-chip mx-auto mb-2 flex"
                    style={{ ['--chip-bg' as string]: '#f1f5f9', ['--chip-fg' as string]: '#94a3b8' }}
                    aria-hidden
                  >
                    <Inbox className="h-4 w-4" />
                  </span>
                  {deletedView ? 'Không có phiếu đã xóa.' : 'Chưa có kế hoạch ký kết nào.'}
                </td>
              </tr>
            )}
            {items.map((k) => (
              <tr
                key={k.id}
                onClick={() => !deletedView && navigate(`/khkk/${k.id}`)}
                className={cn(
                  'border-b border-slate-100 transition last:border-0',
                  deletedView ? 'opacity-70' : 'cursor-pointer hover:bg-brand-50/50',
                )}
              >
                <td className="px-4 py-2.5">
                  <span className="inline-flex items-center gap-2">
                    <span
                      className="icon-chip h-7! w-7!"
                      style={{ ['--chip-bg' as string]: 'var(--color-brand-50)', ['--chip-fg' as string]: 'var(--color-brand-600)' }}
                      aria-hidden
                    >
                      <FileCheck className="h-3.5 w-3.5" />
                    </span>
                    <span className="font-mono text-xs text-brand-800">{k.maKeHoach ?? '—'}</span>
                  </span>
                </td>
                <td className="max-w-xs truncate px-4 py-2.5 font-medium text-brand-800">
                  {k.peTenGoiThau ?? '—'}
                  {k.peMaPhieu && <span className="ml-2 font-mono text-[11px] text-slate-400">{k.peMaPhieu}</span>}
                </td>
                <td className="max-w-[14rem] truncate px-4 py-2.5 text-xs text-slate-600">{k.projectName ?? '—'}</td>
                <td className="px-4 py-2.5">
                  <span
                    className={cn(
                      'inline-flex items-center rounded-md border px-2 py-0.5 text-xs font-medium',
                      KHKK_PHASE_BADGE[k.phase as KhkkPhaseValue],
                    )}
                  >
                    {KHKK_PHASE_LABELS[k.phase as KhkkPhaseValue]}
                  </span>
                  {k.currentApprovalLevelOrder && (
                    <span className="ml-2 text-xs text-slate-500">Cấp {k.currentApprovalLevelOrder}</span>
                  )}
                </td>
                <td className="px-4 py-2.5 text-right tabular-nums text-brand-800">{formatVnd(k.totalProposedAmount)}</td>
                <td className="px-4 py-2.5 text-xs text-slate-600">{k.drafterFullName ?? '—'}</td>
                <td className="px-4 py-2.5 text-xs text-slate-600">{formatDate(k.createdAt)}</td>
              </tr>
            ))}
          </tbody>
        </table>
        </div>
        {totalPages > 1 && (
          <div className="flex items-center justify-between border-t border-slate-200 px-4 py-2.5 text-sm">
            <div className="text-slate-500">
              {total} kế hoạch — Trang {page} / {totalPages}
            </div>
            <div className="flex gap-1">
              <Button variant="outline" size="sm" disabled={page <= 1} onClick={() => setPage((p) => p - 1)}>
                Trước
              </Button>
              <Button variant="outline" size="sm" disabled={page >= totalPages} onClick={() => setPage((p) => p + 1)}>
                Sau
              </Button>
            </div>
          </div>
        )}
      </div>
        </div>
      </div>
    </div>
  )
}
