// Plan AA Chunk B (S24, 2026-05-15) — User read-only matrix view của workflow
// V2 đã admin Designer ghim (`IsUserSelectable=true`, Mig 25). Hiển thị tất cả
// version ghim cho ApplicableType (1=DuyetNcc, 2=DuyetNccPhuongAn).
//
// [Plan AA redesign v2 S24 t1] Bro UAT request: dạng TABLE tận dụng full width
// thay vì stack vertical panel-per-NV. Cấu trúc 4 cột:
//   Bước (Phòng) | Cấp | NV duyệt | Quyền duyệt (grid 2-col 7 label tiếng Việt)
// rowSpan cho Bước (Step) + Cấp (Level order). Color coding 2 layer:
//   - Step bg + headerBg cycle 5 màu (blue/purple/emerald/amber/pink)
//   - Cấp badge ring cycle 5 màu (violet/sky/teal/orange/rose)
// Mỗi cell Quyền duyệt = 8 checkbox read-only label nguyên văn admin Designer
// (7 cũ Mig 29/30/31 + flag thứ 8 "Duyệt là KẾT THÚC" Mig 58 — S89).
//
// URL: /purchase-evaluations/workflow-matrix?type=1|2
// Mirror layout admin `fe-admin/src/pages/system/ApprovalWorkflowsV2Page.tsx`
// line 853-949 cho 7 checkbox label (read-only — drop input onChange).
import { useQuery } from '@tanstack/react-query'
import { Link, useLocation, useSearchParams } from 'react-router-dom'
import { Network, CheckCircle2, Pin, Layers } from 'lucide-react'
import { PageHeader } from '@/components/PageHeader'
import { api } from '@/lib/api'
import { khkkGroupMenuLabel, khkkGroupWorkflowCode } from '@/types/khkk'
import type { AwAdminOverviewDto, AwDefinitionDto, AwLevelDto } from '@/types/approvalWorkflowV2'

// Mig 23 ApplicableType enum mirror (BE Domain/ApprovalWorkflowsV2)
const TYPE_LABEL: Record<number, string> = {
  1: 'Duyệt NCC',
  2: 'Duyệt NCC + Giải pháp',
  3: 'Hợp đồng (chung mọi loại)', // [S159-đợt5]
}

// Color palette per Step (Phòng) — cycle 5 màu để phân biệt Bước. Tailwind JIT
// yêu cầu full class strings (không dynamic interpolation).
const STEP_PALETTE = [
  { bg: 'bg-blue-50/40',    border: 'border-blue-200',    headerBg: 'bg-blue-100',    headerText: 'text-blue-800' },
  { bg: 'bg-purple-50/40',  border: 'border-purple-200',  headerBg: 'bg-purple-100',  headerText: 'text-purple-800' },
  { bg: 'bg-emerald-50/40', border: 'border-emerald-200', headerBg: 'bg-emerald-100', headerText: 'text-emerald-800' },
  { bg: 'bg-amber-50/40',   border: 'border-amber-200',   headerBg: 'bg-amber-100',   headerText: 'text-amber-800' },
  { bg: 'bg-pink-50/40',    border: 'border-pink-200',    headerBg: 'bg-pink-100',    headerText: 'text-pink-800' },
] as const

// Color palette per Cấp (Level order) — cycle 5 màu để phân biệt Cấp trong cùng
// Bước. Badge ring + tone đậm.
const LEVEL_PALETTE = [
  'bg-violet-100 text-violet-800 ring-violet-300',
  'bg-sky-100 text-sky-800 ring-sky-300',
  'bg-teal-100 text-teal-800 ring-teal-300',
  'bg-orange-100 text-orange-800 ring-orange-300',
  'bg-rose-100 text-rose-800 ring-rose-300',
] as const

// [YC-029 W1 S190] ContractType (1..7) → MÃ quy trình duyệt HĐ của loại đó.
// 🔴 NGUỒN CHÉP: `src/Backend/SolutionErp.Domain/Contracts/ContractApprovalWorkflowFamily.cs:33-42`
//    (nhà DUY NHẤT của họ mã ở production). Đây là BẢN SAO THỨ 3 của họ này ở FE
//    (bản 2 = `fe-admin/src/lib/contractWorkflowFamily.ts`, tự khai fe-admin-ONLY nên KHÔNG
//    import chéo app được) ⇒ chép TỪNG KÝ TỰ, chú ý token gạch-nối `HD-NT-NCC` / `HD-NT-DV`.
//    Drift-check = ô C-9 (đếm 7 mã distinct trong chính file này).
const INT_TO_HD_CODE: Record<number, string> = {
  1: 'HD-TP', // HopDongThauPhu
  2: 'HD-GK', // HopDongGiaoKhoan
  3: 'HD-NCC', // HopDongNhaCungCap
  4: 'HD-DV', // HopDongDichVu
  5: 'HD-MB', // HopDongMuaBan
  6: 'HD-NT-NCC', // HopDongNguyenTacNCC
  7: 'HD-NT-DV', // HopDongNguyenTacDichVu
}

export function WorkflowMatrixViewPage() {
  const [searchParams] = useSearchParams()
  // Trang này gắn ở 3 route (/purchase-evaluations|/contracts|/khkk + /workflow-matrix)
  // ⇒ link "xem tất cả" phải bám đường dẫn ĐANG đứng, không hardcode một cái.
  const { pathname } = useLocation()
  const rawType = Number(searchParams.get('type'))
  // [S159-đợt5] +3 = Contract (ApplicableType.Contract) — 7 leaf 'Luồng duyệt' của 7 nhóm HĐ
  // đều trỏ về matrix này vì `ApplicableType` là HẰNG của cả họ, chỉ có MỘT giá trị cho HĐ.
  // 🔴 [YC-029 W1 S190 — vá comment stale] Từ S188 mỗi loại HĐ có QUY TRÌNH RIÊNG: 7 bộ
  // per-loại `HD-TP`/`HD-GK`/`HD-NCC`/`HD-DV`/`HD-MB`/`HD-NT-NCC`/`HD-NT-DV`
  // (`ContractApprovalWorkflowFamily.cs:33-42`) ⇒ 7 leaf KHÔNG còn hiện y hệt nhau: leaf nào
  // cũng mang thêm `&ct=N` (ContractType) và trang slice đúng bộ của loại đó (nhánh `ct` bên dưới).
  // [W2 KHKK S161] +10 (ContractSigningPlan) — leaf Khkk_WfView đi alias /khkk/workflow-matrix?type=10.
  const typeInt = rawType === 1 || rawType === 2 || rawType === 3 || rawType === 10 ? rawType : 1

  const { data, isLoading, isError } = useQuery({
    queryKey: ['workflow-matrix', typeInt],
    queryFn: async () => {
      const res = await api.get<AwAdminOverviewDto>('/approval-workflows-v2', {
        params: { applicableType: typeInt, isUserSelectable: true },
      })
      return res.data
    },
  })

  // Em chỉ render type được chọn — BE đã filter applicableType.
  const summary = data?.types.find(t => t.applicableType === typeInt)
  const allWorkflows: AwDefinitionDto[] = summary?.history ?? []
  const typeLabel = summary?.applicableTypeLabel ?? TYPE_LABEL[typeInt] ?? 'Quy trình duyệt'

  // ── [K4c S166] Lọc theo NHÓM DUYỆT KHKK ────────────────────────────────────
  // 8 leaf "Luồng duyệt" của 8 nhóm (K4b) đều trỏ về CÙNG trang này, chỉ khác
  // `?group=n`. Không lọc thì cả 8 leaf hiện y hệt nhau — mục menu nói dối tên nó.
  // 🔴 Chỉ áp cho type 10 (Kế hoạch ký kết): `group` là khái niệm của riêng KHKK.
  //    Type khác, hoặc `group` rác/thiếu ⇒ BỎ QUA hoàn toàn, hành vi cũ giữ nguyên
  //    (thà hiện đủ còn hơn lọc theo một con số vô nghĩa rồi ra trang trắng).
  const rawGroup = searchParams.get('group')
  const khkkGroup =
    typeInt === 10 && rawGroup !== null && /^[1-8]$/.test(rawGroup) ? Number(rawGroup) : null

  // 🔴 LỌC CLIENT-SIDE, CÓ CHỦ ĐÍCH: query trên kia đã tải TRỌN bộ quy trình của
  // type này rồi (`/approval-workflows-v2?applicableType=10`), nhóm chỉ là lát cắt
  // của đúng bộ đó ⇒ KHÔNG thêm trục `group` vào `queryKey`. Thêm vào sẽ đẻ 8 lần
  // gọi mạng cho cùng một payload, và 8 ô cache cùng nội dung.
  // Khớp bằng `code` (`AwDefinitionDto.code`) chứ không bằng tên/thứ tự: BE seed
  // `KHKK-N{n}` (`DbInitializer.cs:609`) và cũng chính `code` này là thứ BE dùng để
  // gác phiếu-pin-đúng-nhóm (`ContractSigningPlanFeatures.cs:420` regex `^KHKK-N([1-8])$`).
  // Một quy trình có thể có nhiều VERSION cùng `code` ⇒ lọc giữ đủ các version.
  // ── [YC-029 W1 S190] Lọc theo LOẠI HĐ (7 bộ quy trình per-loại từ S188) ────────────
  // Cùng bài với `group` ở trên: 7 leaf "Luồng duyệt" của 7 nhóm HĐ đều trỏ về CÙNG trang
  // này (`type=3` là ApplicableType — hằng của cả họ), chỉ khác `&ct=N`. Không lọc thì 7 leaf
  // hiện y hệt nhau — mục menu nói dối tên nó.
  // 🔴 Gate ĐỦ 3 VẾ: chỉ áp khi `typeInt === 3` (HĐ). Thiếu vế này thì `?type=1&ct=5` sẽ đem
  //    mã `HD-MB` đi lọc bộ Duyệt-NCC ⇒ TRANG TRẮNG. `ct` rác/thiếu ⇒ BỎ QUA, giữ hành vi cũ.
  //    Clamp bằng REGEX CHUỖI chứ không `Number()`: `Number('03')===3` lọt lưới.
  const rawCt = searchParams.get('ct')
  const hdCode =
    typeInt === 3 && rawCt !== null && /^[1-7]$/.test(rawCt) ? INT_TO_HD_CODE[Number(rawCt)] : null

  // 🔴 LỌC CLIENT-SIDE y khuôn `group`: query đã tải TRỌN bộ quy trình của `applicableType=3`,
  // `ct` chỉ là lát cắt của đúng payload đó ⇒ KHÔNG thêm `ct` vào `queryKey` (thêm = 7 lần gọi
  // mạng cho cùng một payload + 7 ô cache trùng nội dung). Khớp bằng `code` (BE seed
  // `ContractApprovalWorkflowFamily.CodeFor`), giữ đủ mọi VERSION cùng `code`.
  const workflows =
    khkkGroup !== null
      ? allWorkflows.filter(wf => wf.code === khkkGroupWorkflowCode(khkkGroup))
      : hdCode !== null
        ? allWorkflows.filter(wf => wf.code === hdCode)
        : allWorkflows

  return (
    // [Plan AA hotfix S24 t1] Bro UAT request: dịch hết content sang trái.
    // px-6 → px-2 (24px → 8px) cho title + table sát sidebar.
    <div className="space-y-4 px-2 py-5">
      <PageHeader
        title={
          <span className="flex items-center gap-2">
            <Network className="h-5 w-5 text-slate-500" />
            Luồng duyệt — {typeLabel}
            {khkkGroup !== null && (
              <span className="inline-flex items-center gap-1 rounded-md border border-violet-300 bg-violet-100 px-2 py-0.5 text-xs font-semibold text-violet-800">
                <Layers className="h-3.5 w-3.5" />
                Nhóm N{khkkGroup}
              </span>
            )}
          </span>
        }
        description={
          // Đang xem lát cắt của một nhóm thì phải nói RÕ nhóm nào — nếu không,
          // 8 leaf menu mở ra 8 trang trông hệt nhau và người dùng không biết
          // mình đang đứng ở đâu.
          khkkGroup !== null
            ? `${khkkGroupMenuLabel(khkkGroup)} — cấu hình do Admin quản trị. Có thắc mắc liên hệ Admin.`
            : 'Cấu hình do Admin quản trị. Có thắc mắc liên hệ Admin.'
        }
        actions={
          khkkGroup !== null ? (
            // Giữ nguyên đường dẫn hiện tại (trang này gắn ở 3 route), chỉ bỏ
            // `group` ⇒ về lại chế độ xem cả 8 nhóm.
            <Link
              to={`${pathname}?type=${typeInt}`}
              className="rounded-md border border-slate-300 px-2.5 py-1 text-xs font-medium text-slate-600 transition hover:bg-slate-50"
            >
              Xem tất cả nhóm
            </Link>
          ) : undefined
        }
      />

      {isLoading && (
        <div className="rounded-xl border border-dashed border-slate-300 p-8 text-center text-sm text-slate-500">
          Đang tải cấu hình...
        </div>
      )}

      {isError && !isLoading && (
        <div className="rounded-xl border border-dashed border-rose-300 bg-rose-50/40 p-8 text-center text-sm text-rose-700">
          Không thể tải cấu hình quy trình. Thử lại sau.
        </div>
      )}

      {!isLoading && !isError && workflows.length === 0 && (
        <div className="rounded-xl border border-dashed border-slate-300 bg-slate-50/40 p-8 text-center text-sm text-slate-500">
          {/* 🔴 Rỗng-vì-lọc ⟂ rỗng-vì-chưa-có-gì là HAI chuyện khác nhau. Dùng
              chung một câu thì người dùng nhóm N5 tưởng cả module chưa cấu hình,
              trong khi 7 nhóm kia đang chạy bình thường. */}
          {khkkGroup !== null ? (
            <>
              Chưa có quy trình nào được Admin ghim cho nhóm{' '}
              <span className="font-medium text-slate-700">N{khkkGroup}</span>
              {allWorkflows.length > 0 && <> (loại phiếu này có {allWorkflows.length} quy trình ở nhóm khác)</>}. Liên hệ Admin.
            </>
          ) : (
            <>Chưa có quy trình nào được Admin ghim cho loại phiếu này. Liên hệ Admin.</>
          )}
        </div>
      )}

      {!isLoading && !isError && workflows.map(wf => (
        <WorkflowCard key={wf.id} wf={wf} />
      ))}
    </div>
  )
}

// Build flat row list per Step với rowSpan metadata cho table layout.
// Mỗi Level row = 1 NV slot (Mig 29 OR-of-N split). Group theo level.order.
type Row = {
  level: AwLevelDto
  order: number
  isFirstInStep: boolean
  isFirstInCap: boolean
  rowSpanStep: number
  rowSpanCap: number
}

function buildStepRows(step: AwDefinitionDto['steps'][number]): Row[] {
  const byOrder = new Map<number, AwLevelDto[]>()
  for (const lvl of step.levels) {
    const arr = byOrder.get(lvl.order) ?? []
    arr.push(lvl)
    byOrder.set(lvl.order, arr)
  }
  const sortedOrders = [...byOrder.keys()].sort((a, b) => a - b)
  const totalInStep = step.levels.length

  const rows: Row[] = []
  let stepCounter = 0
  for (const order of sortedOrders) {
    const levelsOfOrder = byOrder.get(order)!
    levelsOfOrder.forEach((lvl, idx) => {
      rows.push({
        level: lvl,
        order,
        isFirstInStep: stepCounter === 0,
        isFirstInCap: idx === 0,
        rowSpanStep: totalInStep,
        rowSpanCap: levelsOfOrder.length,
      })
      stepCounter++
    })
  }
  return rows
}

function WorkflowCard({ wf }: { wf: AwDefinitionDto }) {
  const totalLevels = wf.steps.reduce((sum, s) => sum + s.levels.length, 0)

  return (
    <div className="overflow-hidden rounded-lg border border-slate-200 bg-white shadow-sm">
      <header className="flex items-start justify-between gap-3 border-b border-slate-100 px-4 py-3">
        <div className="min-w-0 flex-1">
          <div className="flex flex-wrap items-center gap-2">
            <h3 className="text-[15px] font-semibold text-slate-900">
              {wf.name}
            </h3>
            <span className="rounded bg-slate-100 px-2 py-0.5 font-mono text-[11px] text-slate-600">
              {wf.code} v{String(wf.version).padStart(2, '0')}
            </span>
            {wf.isActive && (
              <span className="inline-flex items-center gap-1 rounded-full bg-emerald-100 px-2.5 py-0.5 text-[11px] font-medium text-emerald-700">
                <CheckCircle2 className="h-3 w-3" />
                Đang dùng
              </span>
            )}
            {wf.isUserSelectable && (
              <span className="inline-flex items-center gap-1 rounded-full bg-amber-100 px-2.5 py-0.5 text-[11px] font-medium text-amber-700">
                <Pin className="h-3 w-3" />
                Được ghim
              </span>
            )}
          </div>
          {wf.description && (
            <p className="mt-1.5 text-[12px] leading-relaxed text-slate-500">{wf.description}</p>
          )}
        </div>
      </header>

      {totalLevels === 0 ? (
        <div className="px-3 py-3">
          <div className="rounded-md border border-dashed border-slate-200 bg-slate-50/40 px-3 py-4 text-center text-[12px] italic text-slate-400">
            Quy trình chưa cấu hình bước duyệt nào.
          </div>
        </div>
      ) : (
        <div className="overflow-x-auto">
          <table className="w-full border-collapse text-[12px]">
            <colgroup>
              <col className="w-[160px]" />
              <col className="w-[100px]" />
              <col className="w-[240px]" />
              <col />
            </colgroup>
            <thead>
              <tr className="bg-slate-50 text-[11px] font-semibold uppercase tracking-wide text-slate-600">
                <th className="border border-slate-200 px-3 py-2 text-left">Bước (Phòng)</th>
                <th className="border border-slate-200 px-3 py-2 text-left">Cấp</th>
                <th className="border border-slate-200 px-3 py-2 text-left">NV duyệt</th>
                <th className="border border-slate-200 px-3 py-2 text-left">Quyền duyệt</th>
              </tr>
            </thead>
            <tbody>
              {wf.steps.map((step, sIdx) => {
                const stepColor = STEP_PALETTE[sIdx % STEP_PALETTE.length]
                const rows = buildStepRows(step)

                if (rows.length === 0) {
                  return (
                    <tr key={step.id} className={stepColor.bg}>
                      <td className={`border ${stepColor.border} ${stepColor.headerBg} px-3 py-2 align-top`}>
                        <div className={`text-[13px] font-semibold ${stepColor.headerText}`}>
                          Bước {sIdx + 1}
                        </div>
                        <div className={`mt-0.5 text-[11px] ${stepColor.headerText} opacity-80`}>
                          {step.departmentName ?? '(Không gắn phòng)'}
                        </div>
                      </td>
                      <td colSpan={3} className={`border ${stepColor.border} px-3 py-2 text-[12px] italic text-slate-400`}>
                        Chưa có cấp duyệt
                      </td>
                    </tr>
                  )
                }

                return rows.map(r => {
                  const levelColor = LEVEL_PALETTE[(r.order - 1) % LEVEL_PALETTE.length]
                  return (
                    <tr key={r.level.id} className={stepColor.bg}>
                      {r.isFirstInStep && (
                        <td
                          rowSpan={r.rowSpanStep}
                          className={`border ${stepColor.border} ${stepColor.headerBg} px-3 py-2 align-top`}
                        >
                          <div className={`text-[13px] font-semibold ${stepColor.headerText}`}>
                            Bước {sIdx + 1}
                          </div>
                          <div className={`mt-0.5 text-[11px] ${stepColor.headerText} opacity-80`}>
                            {step.departmentName ?? '(Không gắn phòng)'}
                          </div>
                        </td>
                      )}
                      {r.isFirstInCap && (
                        <td
                          rowSpan={r.rowSpanCap}
                          className={`border ${stepColor.border} bg-white/60 px-3 py-2 align-top`}
                        >
                          <span className={`inline-flex items-center rounded-full px-2.5 py-0.5 text-[11px] font-bold ring-1 ${levelColor}`}>
                            Cấp {r.order}
                          </span>
                          {r.rowSpanCap > 1 && (
                            <div className="mt-1 text-[10px] leading-tight text-slate-500">
                              {r.rowSpanCap} NV OR
                              <br />
                              (chỉ cần 1 NV duyệt)
                            </div>
                          )}
                        </td>
                      )}
                      <td className={`border ${stepColor.border} bg-white/80 px-3 py-2 align-top`}>
                        <div className="font-medium text-slate-800">
                          {r.level.approverUserName ?? r.level.approverUserId}
                        </div>
                        {r.level.approverEmail && (
                          <div className="mt-0.5 text-[11px] text-slate-400">
                            {r.level.approverEmail}
                          </div>
                        )}
                      </td>
                      <td className={`border ${stepColor.border} bg-white/80 px-3 py-2 align-top`}>
                        <div className="grid grid-cols-1 gap-x-4 gap-y-1.5 md:grid-cols-2">
                          <FlagRow active={r.level.allowReturnOneLevel}      label="Trả về 1 Cấp trước" />
                          <FlagRow active={r.level.allowReturnOneStep}       label="Trả về 1 Bước trước" />
                          <FlagRow active={r.level.allowReturnToAssignee}    label="Trả về Người chỉ định" />
                          <FlagRow active={r.level.allowReturnToDrafter}     label="Trả về Drafter (mặc định)" />
                          <FlagRow active={r.level.allowApproverEditDetails} label="Cho phép chỉnh sửa Section 2 (Hạng mục/NCC/Báo giá) lúc đang duyệt" colSpan2 />
                          <FlagRow active={r.level.allowApproverEditBudget}  label="Cho phép chỉnh sửa Section ngân sách lúc đang duyệt" colSpan2 />
                          <FlagRow active={r.level.allowApproverSkipToFinal} label="Cho phép duyệt thẳng Cấp cuối khi đang duyệt" colSpan2 />
                          {/* [Mig 58 — anh Kiệt FDC, S89] Flag thứ 8: cấp này Duyệt = KẾT THÚC (không trình CEO) — trước đây matrix thiếu nên "chưa hiển thị chính xác". */}
                          <FlagRow active={r.level.allowApproverFinalize} label="Duyệt là KẾT THÚC quy trình (không trình tiếp CEO)" colSpan2 />
                          {/* [F6 S155] Flag thứ 9 — quyền xóa phiếu đang duyệt, PER-NGƯỜI của đúng dòng NV này (không phải cả Cấp). */}
                          <FlagRow active={r.level.allowApproverDelete} label="Cho phép NV này XÓA phiếu khi đến lượt duyệt của mình" colSpan2 />
                        </div>
                      </td>
                    </tr>
                  )
                })
              })}
            </tbody>
          </table>
        </div>
      )}

      <footer className="border-t border-slate-100 px-4 py-2.5">
        <small className="text-[11px] text-slate-400">
          Cấu hình do Admin quản trị. Có thắc mắc liên hệ Admin.
        </small>
      </footer>
    </div>
  )
}

// FlagRow read-only checkbox mirror admin Designer line 885-948. `disabled`
// giữ tick visible nhưng disable interaction. colSpan2 cho 3 Allow* label dài
// (Edit Section 2 / Edit Budget / Skip Final) chiếm full 2 col.
function FlagRow({ active, label, colSpan2 }: { active: boolean; label: string; colSpan2?: boolean }) {
  return (
    <label className={`flex items-start gap-1.5 text-[12px] ${colSpan2 ? 'sm:col-span-2' : ''}`}>
      <input
        type="checkbox"
        className="mt-0.5 h-3.5 w-3.5 shrink-0 accent-emerald-600"
        checked={active}
        disabled
        readOnly
      />
      <span className={active ? 'font-medium text-slate-800' : 'text-slate-400'}>
        {label}
      </span>
    </label>
  )
}
