// Đề xuất danh sách — Phase 10.3 G-O3 (S37 2026-05-28).
// Re-skin S69 (2026-06-17): PURO layout + Hồ sơ Nhân sự visual language, REUSING
// the shared ui components (PageHeader + KpiCard). The status filter is rendered
// as a ROW of KpiCards (each = one status, value = count, onClick = the EXISTING
// setStatus/setInboxOnly setter). Table + pagination + every data hook unchanged.
// File MIRROR SHA256 identical với fe-user counterpart.
import { useMemo, useState, type ReactNode } from 'react'
import { useQuery } from '@tanstack/react-query'
import { useNavigate, useSearchParams } from 'react-router-dom'
import {
  Plus, Search, FileSignature, FileEdit, SendHorizontal,
  CheckCircle2, Undo2, XCircle, Layers, Inbox,
} 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 { api } from '@/lib/api'
import { cn } from '@/lib/cn'
import {
  PROPOSAL_STATUS_BADGE,
  PROPOSAL_STATUS_LABELS,
  type PagedResult,
  type ProposalListItemDto,
  type ProposalStatusValue,
} from '@/types/proposal'

const PAGE_SIZE = 20

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 ProposalsListPage() {
  const navigate = useNavigate()
  const [searchParams] = useSearchParams()
  const initialStatus = searchParams.get('status')
  const initialInbox = searchParams.get('inboxOnly') === 'true'

  const [status, setStatus] = useState<number | null>(initialStatus ? Number(initialStatus) : null)
  const [inboxOnly, setInboxOnly] = useState(initialInbox)
  const [search, setSearch] = useState('')
  const [page, setPage] = useState(1)

  const list = useQuery({
    queryKey: ['proposals', { status, inboxOnly, search, page }],
    queryFn: async () =>
      (await api.get<PagedResult<ProposalListItemDto>>('/proposals', {
        params: {
          status: status || undefined,
          inboxOnly: inboxOnly || 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: counts shown on the KpiCard filter chips. Derived from the
  // currently loaded page (no extra fetch). The active filter's own card shows the
  // authoritative server `total`; the others show how many of the loaded rows match
  // — an at-a-glance hint, not a query change.
  const countByStatus = useMemo(() => {
    const acc: Record<number, number> = { 1: 0, 2: 0, 3: 0, 4: 0, 5: 0 }
    for (const p of items) acc[p.status] = (acc[p.status] ?? 0) + 1
    return acc
  }, [items])

  // Status filter chips (presentation). Mirrors the OLD button row 1:1 — value=null
  // is "Tất cả" + the five ProposalStatus values, so every filter stays reachable.
  // Accent per status (playbook): amberx = đã gửi/pending, greenx = đã duyệt, violet
  // = trả lại/returned, brand = tất cả; nháp + từ chối reuse the nearest tone. The
  // inbox toggle below is the teal chip.
  // Count is a presentation hint only: the ACTIVE status card shows the server
  // `total`; the others show how many of the currently-loaded rows match.
  const statusCards: Array<{
    value: number | 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: status === null ? total : items.length },
    { value: 1, label: PROPOSAL_STATUS_LABELS[1], icon: <FileEdit className="h-4 w-4" />, accent: 'violet', count: status === 1 ? total : countByStatus[1] },
    { value: 2, label: PROPOSAL_STATUS_LABELS[2], icon: <SendHorizontal className="h-4 w-4" />, accent: 'amberx', count: status === 2 ? total : countByStatus[2] },
    { value: 5, label: PROPOSAL_STATUS_LABELS[5], icon: <CheckCircle2 className="h-4 w-4" />, accent: 'greenx', count: status === 5 ? total : countByStatus[5] },
    { value: 3, label: PROPOSAL_STATUS_LABELS[3], icon: <Undo2 className="h-4 w-4" />, accent: 'violet', count: status === 3 ? total : countByStatus[3] },
    { value: 4, label: PROPOSAL_STATUS_LABELS[4], icon: <XCircle className="h-4 w-4" />, accent: 'amberx', count: status === 4 ? total : countByStatus[4] },
  ]

  return (
    <div className="space-y-5">
      <PageHeader
        eyebrow="Văn phòng số"
        title="Đề xuất"
        subtitle="Quản lý đề xuất nội bộ — Workflow V2 dynamic theo Quy trình admin config"
        icon={<FileSignature className="h-5 w-5" />}
        accent="brand"
        actions={
          <Button onClick={() => navigate('/proposals/new')}>
            <Plus className="mr-2 h-4 w-4" />
            Tạo Đề xuất
          </Button>
        }
      />

      {/* Status filter — row of KpiCards (PURO). Each wires the EXISTING setter,
          same semantics as the old button row + inbox checkbox (status and inbox
          stay independent filter dimensions). */}
      <div className="grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-7">
        {statusCards.map((c) => (
          <KpiCard
            key={c.value ?? 'all'}
            label={c.label}
            value={c.count}
            icon={c.icon}
            accent={c.accent}
            active={status === c.value}
            onClick={() => {
              setStatus(c.value)
              setPage(1)
            }}
          />
        ))}
        <KpiCard
          label="Cần tôi duyệt"
          value={items.length}
          icon={<Inbox className="h-4 w-4" />}
          accent="teal"
          active={inboxOnly}
          onClick={() => {
            setInboxOnly((v) => !v)
            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ã hoặc tiê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)' }}>
        <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ã</th>
              <th className="label-eyebrow px-4 py-2.5 text-left">Tiêu đề</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">Số tiền dự kiến</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={6} className="px-4 py-8 text-center text-slate-500">
                  Đang tải...
                </td>
              </tr>
            )}
            {!list.isLoading && items.length === 0 && (
              <tr>
                <td colSpan={6} 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>
                  Chưa có đề xuất nào.
                </td>
              </tr>
            )}
            {items.map((p) => (
              <tr
                key={p.id}
                onClick={() => navigate(`/proposals/${p.id}`)}
                className="cursor-pointer border-b border-slate-100 transition last:border-0 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
                    >
                      <FileSignature className="h-3.5 w-3.5" />
                    </span>
                    <span className="font-mono text-xs text-brand-800">{p.maDeXuat ?? '—'}</span>
                  </span>
                </td>
                <td className="max-w-md truncate px-4 py-2.5 font-medium text-brand-800">{p.title}</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',
                      PROPOSAL_STATUS_BADGE[p.status as ProposalStatusValue],
                    )}
                  >
                    {PROPOSAL_STATUS_LABELS[p.status as ProposalStatusValue]}
                  </span>
                  {p.currentApprovalLevelOrder && (
                    <span className="ml-2 text-xs text-slate-500">Cấp {p.currentApprovalLevelOrder}</span>
                  )}
                </td>
                <td className="px-4 py-2.5 text-right tabular-nums text-brand-800">{formatVnd(p.amountEstimate)}</td>
                <td className="px-4 py-2.5 text-xs text-slate-600">{p.drafterFullName ?? '—'}</td>
                <td className="px-4 py-2.5 text-xs text-slate-600">{formatDate(p.createdAt)}</td>
              </tr>
            ))}
          </tbody>
        </table>
        {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} đề xuất — 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>
  )
}
