// 3-panel "Hộp thư" — HĐ chờ role tôi xử lý. Stats row + Panel 1 (list
// pending) | Panel 2 (detail content) | Panel 3 (workflow + lịch sử duyệt).
// Selected qua URL ?id= để bookmarkable.
//
// Khác MyContractsPage: data từ /contracts/inbox (BE đã filter HĐ chờ role
// tôi), thêm 4-card stats overdue/dueSoon/total/totalValue ở header.
import { useMemo } from 'react'
import { useQuery } from '@tanstack/react-query'
import { useNavigate, useSearchParams } from 'react-router-dom'
import { Inbox, AlertTriangle, Clock, FileText, Search, ClipboardList } from 'lucide-react'
import { ContractDetailContent } from '@/components/contracts/ContractDetailContent'
import { ContractWorkflowPanel } from '@/components/contracts/ContractWorkflowPanel'
import { WorkflowHistoryPanel } from '@/components/contracts/WorkflowHistoryPanel'
import { PhaseBadge } from '@/components/PhaseBadge'
import { SlaTimer } from '@/components/SlaTimer'
import { EmptyState } from '@/components/EmptyState'
import { Input } from '@/components/ui/Input'
import { useAuth } from '@/contexts/AuthContext'
import { api } from '@/lib/api'
import { cn } from '@/lib/cn'
import type { ContractDetail, ContractListItem } from '@/types/contracts'
import { ContractTypeLabel } from '@/types/forms'
import {
  PurchaseEvaluationPhaseColor,
  PurchaseEvaluationPhaseLabel,
  PurchaseEvaluationTypeLabel,
  type PeListItem,
} from '@/types/purchaseEvaluation'
import { PeUrgentChips } from '@/components/pe/PeUrgentChips'
import { PeFinalizeChip } from '@/components/pe/PeFinalizeChip'

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

function StatPill({
  icon: Icon,
  label,
  value,
  tone = 'default',
}: {
  icon: React.ComponentType<{ className?: string }>
  label: string
  value: React.ReactNode
  tone?: 'default' | 'warn' | 'danger'
}) {
  const toneClass =
    tone === 'danger' ? 'text-red-600 bg-red-50' :
    tone === 'warn' ? 'text-amber-600 bg-amber-50' :
    'text-brand-600 bg-brand-50'
  return (
    <div className="flex items-center gap-2 rounded-md border border-slate-200 bg-white px-3 py-1.5 text-xs">
      <span className={cn('flex h-5 w-5 items-center justify-center rounded', toneClass)}>
        <Icon className="h-3 w-3" />
      </span>
      <span className="text-slate-500">{label}</span>
      <span className="font-semibold text-slate-900">{value}</span>
    </div>
  )
}

export function InboxPage() {
  const navigate = useNavigate()
  const { user } = useAuth()
  const [searchParams, setSearchParams] = useSearchParams()

  const typeFilter = searchParams.get('type') ? Number(searchParams.get('type')) : null
  const selectedId = searchParams.get('id')
  const search = searchParams.get('q') ?? ''

  // 🔴 [W7 S187 — BLOCKED, đừng "làm nốt"] Lọc loại HĐ ở màn này CỐ Ý CÒN Ở CLIENT.
  // `MyContractsPage`/`ContractsListPage` đã chuyển `?type=` lên server được vì
  // `GET /api/contracts` có param (`ContractsController.cs:25`). Endpoint NÀY thì KHÔNG:
  // `ContractsController.cs:41-43` là `Inbox(CancellationToken ct)` → `new GetMyInboxQuery()`,
  // và `ContractFeatures.cs:479` khai `public record GetMyInboxQuery : IRequest<...>;` —
  // KHÔNG THAM SỐ. Gửi `?type=` lên đây thì BE **nuốt im lặng**, còn gỡ vế lọc dưới kia sẽ
  // giết CÂM bộ lọc của 7 leaf `Ct_*_Pending` (`Layout.tsx:150` → `/inbox?type=N`).
  // ⚠️ Nợ THẬT chưa trả: `ContractFeatures.cs:550` có `q.Take(100)` ⇒ hộp thư >100 dòng thì
  // loại hiếm VẪN biến mất im lặng. Vá được CHỈ KHI BE thêm param cho inbox (lane backend);
  // xong bên đó thì mới bê nguyên khuôn `MyContractsPage` sang (nhớ chặn `NaN` + thêm `type`
  // vào `queryKey` — key ở đây đang là `['inbox']` trống, đổi nguồn mà quên là cache dùng
  // chung sai CÂM).
  const list = useQuery({
    queryKey: ['inbox'],
    queryFn: async () => (await api.get<ContractListItem[]>('/contracts/inbox')).data,
  })

  // PE inbox — phiếu Duyệt NCC chờ user xử lý (Optional polish §6.B HANDOFF).
  // Click row → navigate /purchase-evaluations/:id thay vì inline detail (đỡ
  // duplicate ContractDetailContent component cho PE entity khác shape).
  const peList = useQuery({
    queryKey: ['pe-inbox'],
    queryFn: async () => (await api.get<PeListItem[]>('/purchase-evaluations/inbox')).data,
  })

  const detail = useQuery({
    queryKey: ['contract', selectedId],
    queryFn: async () => (await api.get<ContractDetail>(`/contracts/${selectedId}`)).data,
    enabled: !!selectedId,
  })

  const allRows = list.data ?? []

  const rows = useMemo(() => {
    let items = allRows
    if (typeFilter != null) items = items.filter(c => c.type === typeFilter)
    if (search.trim()) {
      const q = search.toLowerCase()
      items = items.filter(c =>
        (c.maHopDong ?? '').toLowerCase().includes(q) ||
        (c.tenHopDong ?? '').toLowerCase().includes(q) ||
        (c.supplierName ?? '').toLowerCase().includes(q),
      )
    }
    return items
  }, [allRows, typeFilter, search])

  const peRows = useMemo(() => {
    let items = peList.data ?? []
    if (search.trim()) {
      const q = search.toLowerCase()
      items = items.filter(p =>
        (p.maPhieu ?? '').toLowerCase().includes(q) ||
        (p.tenGoiThau ?? '').toLowerCase().includes(q) ||
        (p.projectName ?? '').toLowerCase().includes(q),
      )
    }
    return items
  }, [peList.data, search])

  const stats = useMemo(() => {
    const now = Date.now()
    const dayMs = 24 * 60 * 60 * 1000
    let overdue = 0
    let dueSoon = 0
    let totalValue = 0
    for (const c of rows) {
      totalValue += c.giaTri ?? 0
      if (!c.slaDeadline) continue
      const diff = new Date(c.slaDeadline).getTime() - now
      if (diff < 0) overdue++
      else if (diff < dayMs) dueSoon++
    }
    // PE rows tham gia stats overdue/dueSoon (KHÔNG totalValue — PE không có giá trị HĐ)
    for (const p of peRows) {
      if (!p.slaDeadline) continue
      const diff = new Date(p.slaDeadline).getTime() - now
      if (diff < 0) overdue++
      else if (diff < dayMs) dueSoon++
    }
    return { total: rows.length + peRows.length, overdue, dueSoon, totalValue }
  }, [rows, peRows])

  function selectContract(id: string) {
    if (typeof window !== 'undefined' && window.matchMedia('(min-width: 1024px)').matches) {
      const next = new URLSearchParams(searchParams)
      next.set('id', id)
      setSearchParams(next, { replace: false })
    } else {
      navigate(`/contracts/${id}`)
    }
  }

  function clearSelection() {
    const next = new URLSearchParams(searchParams)
    next.delete('id')
    setSearchParams(next, { replace: false })
  }

  function updateSearch(value: string) {
    const next = new URLSearchParams(searchParams)
    if (value) next.set('q', value)
    else next.delete('q')
    setSearchParams(next, { replace: true })
  }

  const typeLabel = typeFilter != null ? ContractTypeLabel[typeFilter] : null

  return (
    <div className="flex h-[calc(100vh-4rem)] flex-col">
      {/* Header — title + stats inline để Panel 1 max chỗ */}
      <header className="flex shrink-0 flex-wrap items-center gap-3 border-b border-slate-200 bg-white px-6 py-3">
        <div className="flex items-center gap-2">
          <Inbox className="h-5 w-5 text-slate-500" />
          <h1 className="text-base font-semibold tracking-tight text-slate-900">
            Hộp thư {typeLabel && <span className="text-slate-500">· {typeLabel}</span>}
          </h1>
        </div>
        <div className="ml-auto flex flex-wrap gap-2">
          <StatPill icon={Inbox} label="Cần xử lý" value={stats.total} />
          <StatPill icon={Clock} label="Sắp quá hạn" value={stats.dueSoon} tone="warn" />
          <StatPill icon={AlertTriangle} label="Quá hạn" value={stats.overdue} tone="danger" />
          <StatPill icon={FileText} label="Giá trị" value={fmtMoney(stats.totalValue)} />
        </div>
      </header>

      {user?.roles.length ? (
        <div className="shrink-0 border-b border-slate-200 bg-amber-50 px-6 py-1.5 text-[11px] text-amber-700">
          Vai trò bạn đang xử lý: <span className="font-medium">{user.roles.join(', ')}</span>
        </div>
      ) : null}

      <div className="grid flex-1 grid-cols-1 overflow-hidden lg:grid-cols-[320px_1fr_360px]">
        {/* Panel 1 — Pending list */}
        <aside className="flex flex-col overflow-hidden border-r border-slate-200 bg-white">
          <div className="border-b border-slate-200 p-3">
            <div className="relative">
              <Search className="pointer-events-none absolute left-2.5 top-2.5 h-4 w-4 text-slate-400" />
              <Input
                value={search}
                onChange={e => updateSearch(e.target.value)}
                placeholder="Tìm theo mã / tên / NCC…"
                className="pl-8"
              />
            </div>
          </div>
          <div className="flex-1 overflow-y-auto">
            {list.isLoading && (
              <div className="space-y-2 p-3">
                {Array.from({ length: 5 }).map((_, i) => (
                  <div key={i} className="h-16 animate-pulse rounded-md bg-slate-100" />
                ))}
              </div>
            )}
            {!list.isLoading && rows.length === 0 && peRows.length === 0 && (
              <div className="p-6">
                <EmptyState
                  icon={Inbox}
                  title="Hộp thư trống"
                  description={
                    typeFilter != null
                      ? `Không có ${ContractTypeLabel[typeFilter]} nào đang chờ.`
                      : 'Không có HĐ hoặc Phiếu Duyệt NCC nào chờ bạn xử lý.'
                  }
                />
              </div>
            )}

            {/* Section 1 — Hợp đồng chờ tôi */}
            {rows.length > 0 && (
              <>
                <div className="sticky top-0 z-10 flex items-center gap-2 border-b border-slate-200 bg-slate-50 px-3 py-1.5 text-[11px] font-medium text-slate-600">
                  <FileText className="h-3 w-3" />
                  Hợp đồng <span className="text-slate-400">({rows.length})</span>
                </div>
                <ul className="divide-y divide-slate-100">
                  {rows.map(c => {
                    const overdue = c.slaDeadline && new Date(c.slaDeadline).getTime() < Date.now()
                    return (
                      <li key={c.id}>
                        <button
                          onClick={() => selectContract(c.id)}
                          className={cn(
                            'block w-full px-3 py-2.5 text-left transition hover:bg-slate-50',
                            selectedId === c.id && 'bg-brand-50 ring-1 ring-inset ring-brand-200',
                            overdue && selectedId !== c.id && 'border-l-2 border-l-red-400',
                          )}
                        >
                          <div className="flex items-start justify-between gap-2">
                            <div className="min-w-0 flex-1">
                              <div className="truncate text-[13px] font-medium text-slate-900">
                                {c.tenHopDong ?? '(chưa đặt tên)'}
                              </div>
                              <div className="mt-0.5 flex items-center gap-1.5 text-[11px] text-slate-500">
                                <span className="font-mono">{c.maHopDong ?? '—'}</span>
                                <span>·</span>
                                <span className="truncate">{c.supplierName}</span>
                              </div>
                            </div>
                            <PhaseBadge phase={c.phase} className="shrink-0 text-[10px]" />
                          </div>
                          <div className="mt-1 flex items-center justify-between text-[11px] text-slate-500">
                            <span>{fmtMoney(c.giaTri)}</span>
                            <SlaTimer deadline={c.slaDeadline} createdAt={c.createdAt} />
                          </div>
                        </button>
                      </li>
                    )
                  })}
                </ul>
              </>
            )}

            {/* Section 2 — Phiếu Duyệt NCC chờ tôi (PE) */}
            {peRows.length > 0 && (
              <>
                <div className="sticky top-0 z-10 flex items-center gap-2 border-b border-slate-200 bg-slate-50 px-3 py-1.5 text-[11px] font-medium text-slate-600">
                  <ClipboardList className="h-3 w-3" />
                  Phiếu Duyệt NCC <span className="text-slate-400">({peRows.length})</span>
                </div>
                <ul className="divide-y divide-slate-100">
                  {peRows.map(p => {
                    const overdue = p.slaDeadline && new Date(p.slaDeadline).getTime() < Date.now()
                    return (
                      <li key={p.id}>
                        <button
                          onClick={() => navigate(`/purchase-evaluations/${p.id}`)}
                          className={cn(
                            'block w-full px-3 py-2.5 text-left transition hover:bg-slate-50',
                            overdue && 'border-l-2 border-l-red-400',
                          )}
                        >
                          <div className="flex items-start justify-between gap-2">
                            <div className="min-w-0 flex-1">
                              <div className="flex min-w-0 items-center gap-1 text-[13px] font-medium text-slate-900">
                                <PeUrgentChips isUrgentByPro={p.isUrgentByPro} isUrgentByCcm={p.isUrgentByCcm} />
                                <PeFinalizeChip endsBeforeCeo={p.endsBeforeCeo} finalizeStepName={p.finalizeStepName} phase={p.phase} />
                                <span className="truncate">{p.tenGoiThau}</span>
                              </div>
                              <div className="mt-0.5 flex items-center gap-1.5 text-[11px] text-slate-500">
                                <span className="font-mono">{p.maPhieu ?? '—'}</span>
                                <span>·</span>
                                <span className="truncate">{p.projectName}</span>
                              </div>
                            </div>
                            <span className={cn(
                              'shrink-0 rounded px-1.5 py-0.5 text-[10px]',
                              PurchaseEvaluationPhaseColor[p.phase],
                            )}>
                              {PurchaseEvaluationPhaseLabel[p.phase]}
                            </span>
                          </div>
                          <div className="mt-1 flex items-center justify-between text-[11px] text-slate-500">
                            <span>{PurchaseEvaluationTypeLabel[p.type]}</span>
                            <SlaTimer deadline={p.slaDeadline} createdAt={p.createdAt} />
                          </div>
                        </button>
                      </li>
                    )
                  })}
                </ul>
              </>
            )}
          </div>
        </aside>

        {/* Panel 2 — Detail content */}
        <main className="hidden overflow-y-auto bg-slate-50 p-6 lg:block">
          {!selectedId && (
            <EmptyState
              icon={Inbox}
              title="Chọn 1 HĐ ở danh sách bên trái"
              description="Chi tiết HĐ + góp ý + đính kèm + nút Duyệt sẽ hiển thị ở đây."
            />
          )}
          {selectedId && detail.isLoading && (
            <div className="text-sm text-slate-500">Đang tải HĐ…</div>
          )}
          {selectedId && detail.data && (
            <ContractDetailContent contract={detail.data} onBack={clearSelection} />
          )}
        </main>

        {/* Panel 3 — Workflow + history */}
        <aside className="hidden overflow-y-auto border-l border-slate-200 bg-white p-4 lg:block">
          {/* [S174 owner] GỠ `PipelineTreePanel` khỏi Hộp thư — anh: "chỗ hộp thư vứt panel
              này vào làm j, tập trung vào KHKK thôi". Hộp thư là hàng-đợi-việc-của-tôi; cây
              toàn trình là bản-đồ-toàn-hệ ⇒ sai thể loại, và nó chiếm mất chỗ đáng ra để
              trống chờ quy trình duyệt của HĐ đang chọn.
              🧊 Lineage: panel này vào đây @S168 GĐ3-D theo owner slot (63) chốt D + "mở rộng
              = cả 3 trang". Nay owner thu lại ĐÚNG trang này. HAI trang GĐ3/GĐ4 còn lại
              (`MyContractsPage` · `HardCopiesPage`) GIỮ NGUYÊN — anh chỉ đích danh Hộp thư,
              không nói gỡ hết; đừng tự suy rộng. */}
          {!selectedId && (
            <div className="rounded-lg border border-dashed border-slate-200 p-6 text-center text-sm text-slate-400">
              Quy trình duyệt sẽ hiện khi chọn hợp đồng.
            </div>
          )}
          {selectedId && detail.data && (
            <div className="space-y-4">
              {/* [WQ3b S190 · YC-030 Q5] Máy duyệt V2 dời từ ContractDetailContent ra host. */}
              {detail.data.approvalWorkflowId != null && (
                <section className="rounded-lg border border-brand-200 bg-white p-5">
                  <ContractWorkflowPanel contract={detail.data} />
                </section>
              )}
              <WorkflowHistoryPanel contract={detail.data} />
            </div>
          )}
        </aside>
      </div>
    </div>
  )
}
