// Types cho module Duyệt NCC (PurchaseEvaluation) — mirror BE Domain.

export const PurchaseEvaluationType = {
  DuyetNcc: 1,
  DuyetNccPhuongAn: 2,
} as const
export type PurchaseEvaluationType = typeof PurchaseEvaluationType[keyof typeof PurchaseEvaluationType]

export const PurchaseEvaluationTypeLabel: Record<number, string> = {
  1: 'Duyệt NCC',
  2: 'Duyệt NCC và Giải pháp',
}

export const PurchaseEvaluationTypeCode: Record<number, string> = {
  1: 'DuyetNcc',
  2: 'DuyetNccPhuongAn',
}

// Mig 21 drastic refactor: enum simplified. ChoDuyet=10 generic intermediate.
// Legacy 2-9 + 98 deprecated, giữ values cho data cũ đọc OK.
export const PurchaseEvaluationPhase = {
  DangSoanThao: 1,
  ChoPurchasing: 2,             // [LEGACY]
  ChoDuAn: 3,                   // [LEGACY]
  ChoCCM: 4,                    // [LEGACY]
  ChoCEODuyetPA: 5,             // [LEGACY]
  ChoCEODuyetNCC: 6,            // [LEGACY]
  DaDuyet: 7,
  ChoDuyet: 10,                 // [Mig 21] generic intermediate
  TraLai: 98,                   // Phase riêng — Drafter sửa+gửi lại chạy từ đầu
  TuChoi: 99,
} as const
export type PurchaseEvaluationPhase = typeof PurchaseEvaluationPhase[keyof typeof PurchaseEvaluationPhase]

export const PurchaseEvaluationPhaseLabel: Record<number, string> = {
  1: 'Nháp',
  2: 'Chờ Purchasing',
  3: 'Chờ Dự án',
  4: 'Chờ CCM',
  5: 'Chờ CEO duyệt PA',
  6: 'Chờ CEO duyệt NCC',
  7: 'Đã duyệt',
  10: 'Đã gửi duyệt',
  98: 'Cần chỉnh sửa lại',
  99: 'Từ chối',
}

// 2026-06-16 "badge mỗi trạng thái 1 màu rõ" (anh): deepened text to -800;
// phase-2 (đang soạn) tinted brand-blue. AA-safe on the -100 tints.
export const PurchaseEvaluationPhaseColor: Record<number, string> = {
  1: 'bg-slate-200 text-slate-700',
  2: 'bg-brand-100 text-brand-800',
  3: 'bg-orange-100 text-orange-800',
  4: 'bg-indigo-100 text-indigo-800',
  5: 'bg-fuchsia-100 text-fuchsia-800',
  6: 'bg-pink-100 text-pink-800',
  7: 'bg-emerald-100 text-emerald-800',
  10: 'bg-amber-100 text-amber-800',
  98: 'bg-yellow-100 text-yellow-800',
  99: 'bg-red-100 text-red-800',
}

// Phase nào được phép edit phiếu (Drafter sửa header + detail).
// User 2026-05-07: chỉ Đang soạn thảo + Trả lại (Từ chối là terminal, không edit).
export function isEditablePhase(phase: number): boolean {
  return phase === PurchaseEvaluationPhase.DangSoanThao
    || phase === PurchaseEvaluationPhase.TraLai
}

// Display status meta — 5 trạng thái spec Session 17:
//   Nháp        = DangSoanThao (chưa vào quy trình duyệt)
//   Đã gửi duyệt = ChoDuyet/legacy intermediate (đang chạy quy trình)
//   Trả lại     = TraLai (có history đã đi qua quy trình, sửa+gửi lại chạy từ đầu)
//   Đã duyệt    = DaDuyet (terminal OK — input cho phiếu khác / in trình ký)
//   Từ chối     = TuChoi (terminal lock — không thao tác gì được nữa)
export const PeDisplayStatus = {
  Nhap: 'Nhap',
  DaGuiDuyet: 'DaGuiDuyet',
  TraLai: 'TraLai',
  DaDuyet: 'DaDuyet',
  TuChoi: 'TuChoi',
} as const
export type PeDisplayStatus = typeof PeDisplayStatus[keyof typeof PeDisplayStatus]

export const PeDisplayStatusLabel: Record<PeDisplayStatus, string> = {
  Nhap: 'Nháp',
  DaGuiDuyet: 'Đã gửi duyệt',
  TraLai: 'Cần chỉnh sửa lại',
  DaDuyet: 'Đã duyệt',
  TuChoi: 'Từ chối',
}

// 2026-06-16 "mỗi trạng thái 1 màu rõ (xanh/cam/đỏ/lục/xám)" (anh): the 5
// display statuses now map cleanly to the requested colour set — xám/cam/vàng/
// lục/đỏ — at deeper -800 ink for legibility.
export const PeDisplayStatusColor: Record<PeDisplayStatus, string> = {
  Nhap: 'bg-slate-200 text-slate-700',
  DaGuiDuyet: 'bg-amber-100 text-amber-800',
  TraLai: 'bg-yellow-100 text-yellow-800',
  DaDuyet: 'bg-emerald-100 text-emerald-800',
  TuChoi: 'bg-red-100 text-red-800',
}

export function getPeDisplayStatus(phase: number): PeDisplayStatus {
  if (phase === PurchaseEvaluationPhase.DangSoanThao) return PeDisplayStatus.Nhap
  if (phase === PurchaseEvaluationPhase.DaDuyet) return PeDisplayStatus.DaDuyet
  if (phase === PurchaseEvaluationPhase.TraLai) return PeDisplayStatus.TraLai
  if (phase === PurchaseEvaluationPhase.TuChoi) return PeDisplayStatus.TuChoi
  return PeDisplayStatus.DaGuiDuyet
}

export type PeListItem = {
  id: string
  maPhieu: string | null
  tenGoiThau: string
  type: number
  phase: number
  projectId: string
  projectName: string
  projectCode: string
  // S57bis — Hạng mục công việc (nullable cho phiếu cũ). BE list DTO trả workItemName.
  workItemId: string | null
  workItemName: string | null
  selectedSupplierId: string | null
  selectedSupplierName: string | null
  contractId: string | null
  slaDeadline: string | null
  createdAt: string
  // S23 t2 UAT: BE sort theo UpdatedAt DESC (fallback CreatedAt) — phiếu vừa
  // update (Tạo / Gửi duyệt / Trả lại) đưa lên đầu. FE list item hiển thị
  // "Tạo lúc createdAt" (KHÔNG còn SLA countdown "Còn N ngày").
  updatedAt: string | null
  // Plan AG4 (2026-05-21): bro UAT yêu cầu bổ sung Người tạo + Phòng ban tạo
  // vào PE card. BE JOIN Users + Departments LEFT, cả 2 nullable theo PE entity.
  drafterUserId: string | null
  drafterName: string | null
  departmentId: string | null
  departmentName: string | null
  // S61 — 2 cột ngân sách mới (list DTO mirror detail; chưa render ở list UI)
  budgetPeriodAmount: number | null
  expectedRemainingAmount: number | null
  // S69 — cờ gấp per-vai (PRO ĐỎ / CCM XANH). FE render chip nhỏ trên card list.
  isUrgentByPro: boolean
  isUrgentByCcm: boolean
  // [Mig 58 — anh Kiệt FDC] Multi-winner: tên MỌI đơn vị trúng thầu (IsWinner). BE
  // null selectedSupplierName khi joint ≥2 winner → list card ưu tiên field này,
  // fallback selectedSupplierName cho phiếu 1-winner cũ.
  winnerSupplierNames: string[]
  // [Mig 58 AllowApproverFinalize — anh Kiệt FDC, S89] Quy trình có cấp bật "Duyệt là
  // KẾT THÚC" (không trình CEO). BE first-reachable finalize theo Step.Order↑ → Level.Order↑.
  // V1 (approvalWorkflowId==null) → endsBeforeCeo=false + names null. FE render PeFinalizeChip.
  endsBeforeCeo: boolean
  finalizeStepName: string | null
  finalizeLevelName: string | null
}

export type PeSupplier = {
  id: string
  supplierId: string
  supplierName: string
  displayName: string | null
  contactName: string | null
  contactEmail: string | null
  contactPhone: string | null
  paymentTermText: string | null
  note: string | null
  order: number
  // [Mig 58 — anh Kiệt FDC] Multi-winner: đơn vị này có thuộc tập đơn vị trúng thầu
  // (≥1 đơn vị được chọn) không. Nguồn-sự-thật cho checkbox "Chọn trúng thầu" — KHÔNG
  // dùng selectedSupplierId (null khi joint ≥2 winner). winnerQuoteTotal = SUM mọi isWinner.
  isWinner: boolean
}

export type PeQuote = {
  id: string
  purchaseEvaluationDetailId: string
  purchaseEvaluationSupplierId: string
  bgVat: number
  chuaVat: number
  thanhTien: number
  isSelected: boolean
  note: string | null
}

export type PeDetailRow = {
  id: string
  groupCode: string
  groupName: string
  itemCode: string | null
  noiDung: string
  donViTinh: string | null
  khoiLuongNganSach: number
  khoiLuongThiCong: number
  donGiaNganSach: number
  thanhTienNganSach: number
  order: number
  ghiChu: string | null
  quotes: PeQuote[]
}

export type PeAttachment = {
  id: string
  purchaseEvaluationSupplierId: string | null
  fileName: string
  storagePath: string
  fileSize: number
  contentType: string
  purpose: number
  note: string | null
  createdAt: string
}

export const PeAttachmentPurpose = {
  QuoteDocument: 1,
  RequirementSpec: 2,
  DecisionExport: 3,
  ComparisonTable: 4,
  ApprovalAttachment: 5,
  Other: 99,
} as const

export const PeAttachmentPurposeLabel: Record<number, string> = {
  1: 'Báo giá',
  2: 'Yêu cầu KT',
  3: 'Phiếu duyệt',
  4: 'Bảng so sánh',
  5: 'File khi duyệt',
  99: 'Khác',
}

export type PeApproval = {
  id: string
  fromPhase: number
  toPhase: number
  approverUserId: string | null
  approverName: string | null
  decision: number
  comment: string | null
  approvedAt: string
}

export type PeWorkflowSummary = {
  policyName: string
  policyDescription: string
  activePhases: number[]
  nextPhases: number[]
}

// Mig 22-24 V2 — info Bước/Cấp đang chờ duyệt + danh sách approver được duyệt.
export type PeCurrentApprovalLevelApprover = {
  userId: string
  fullName: string
  email: string | null
  // [S76] Hiển thị-only: approver được nhập/điều chỉnh ngân sách cột nào (suy từ role).
  canEditProBudget: boolean
  canEditCcmBudget: boolean
}

export type PeCurrentApproval = {
  stepIndex: number
  stepName: string
  stepDepartmentId: string | null
  stepDepartmentName: string | null
  levelOrder: number
  levelName: string | null
  approvers: PeCurrentApprovalLevelApprover[]
}

// Mig 22-24 V2 — full workflow flow snapshot (Bước → Cấp → NV).
export type PeApprovalFlowLevel = {
  order: number
  name: string | null
  approvers: PeCurrentApprovalLevelApprover[]
  status: 'Done' | 'Current' | 'Pending'
  // [Mig 58 — anh Kiệt FDC, S89] Cấp này bật "Duyệt là KẾT THÚC quy trình" (không trình CEO).
  allowApproverFinalize: boolean
}

export type PeApprovalFlowStep = {
  order: number
  name: string
  departmentId: string | null
  departmentName: string | null
  status: 'Done' | 'Current' | 'Pending'
  levels: PeApprovalFlowLevel[]
}

export type PeApprovalFlow = {
  currentStepIndex: number | null
  currentLevelOrder: number | null
  steps: PeApprovalFlowStep[]
}

export type PeChangelog = {
  id: string
  entityType: number
  entityId: string | null
  action: number
  phaseAtChange: number | null
  userId: string | null
  userName: string | null
  summary: string | null
  fieldChangesJson: string | null
  contextNote: string | null
  createdAt: string
}

// S61 · [S76] Ngân sách gói thầu MA TRẬN 3 cột (DỰ ÁN | PRO | CCM) — PeWorkItemBudgets
// 1 record/cặp Dự án × Hạng mục. BE compute + trả kèm PE detail GET. Mỗi cột full =
// ban hành + hiệu chỉnh. fullAmount (authoritative Block B) = CCM nếu CCM nhập, else
// PRO (proInitial+proAdjust) + fullIsEstimate=true (badge "ngân sách PRO"). canEditPro
// = Procurement|Admin · canEditCcm = CostControl|Admin (BE-computed, FE KHÔNG đoán role).
// DỰ ÁN = FE hiển thị-only (chưa wire BE). budgetId=null → phiếu chưa gắn Hạng mục.
export type PeBudgetSummary = {
  budgetId: string | null
  proEstimateAmount: number | null    // [LEGACY ≤S75] FE không dùng — thay bằng proInitial/proAdjust
  proInitialAmount: number | null     // [S76] PRO "Ban hành lần đầu"
  proAdjustmentAmount: number | null  // [S76] PRO "V0/hiệu chỉnh" — cho phép ÂM
  proNote: string | null
  initialAmount: number | null        // CCM "Ban hành lần đầu"
  adjustmentAmount: number | null     // CCM "NS V0/hiệu chỉnh" — cho phép ÂM
  ccmNote: string | null              // CCM "Ghi chú từ CCM"
  fullAmount: number
  fullIsEstimate: boolean
  canEditPro: boolean
  canEditCcm: boolean
  // Lũy kế các phiếu cùng (ProjectId, WorkItemId), Id != this, CreatedAt < this:
  previousSubmittedTotal: number    // SUM BudgetPeriodAmount WHERE Phase IN (ChoDuyet, DaDuyet)
  previousSubmittedCount: number
  previousSelectedTotal: number     // SUM quote ThanhTien NCC trúng (IsWinner) WHERE Phase=DaDuyet
  previousSelectedCount: number
  currentProposalTotal: number      // SUM ThanhTien quotes NCC trúng (IsWinner) phiếu NÀY (0 khi chưa chọn)
  budgetFrozen: boolean             // [S133] true = phiếu DaDuyet, số NS đã chốt snapshot
  // [S134] Lũy kế TẠM TÍNH — phần góp từ phiếu cùng gói thầu CHƯA duyệt (Phase NOT IN
  // {DaDuyet, TuChoi}). Cộng dồn để hiển thị số "tạm tính", KHÔNG thay số CHÍNH XÁC.
  pendingSubmittedTotal: number     // delta cộng vào previousSubmittedTotal (row 1/5)
  pendingSubmittedCount: number
  pendingSelectedTotal: number      // delta cộng vào previousSelectedTotal (row 2/6)
  pendingSelectedCount: number
  pendingPriorPes: { id: string; maPhieu: string | null; phase: number }[] | null
}

// Mirror BE PeDepartmentKind enum
export const PeDepartmentKind = {
  PheDuyet: 1,
  Ccm: 2,
  MuaHang: 3,
  SmPm: 4,
} as const
export type PeDepartmentKind = typeof PeDepartmentKind[keyof typeof PeDepartmentKind]

export const PeDepartmentKindLabel: Record<number, string> = {
  1: 'Phê duyệt',
  2: 'P.CCM',
  3: 'P.Mua hàng',
  4: 'SM-PM',
}

export type PeDepartmentOpinion = {
  id: string
  kind: number
  kindLabel: string
  opinion: string | null
  signedAt: string | null
  userId: string | null
  userName: string | null
}

// Mig 26 (Session 19) — Section 5 V2 dynamic theo ApprovalWorkflowLevel.
// Service ApproveV2Async UPSERT auto khi NV duyệt (Q1=1B). Empty list cho
// phiếu V1 / V2 chưa có cấp nào duyệt → FE fallback message.
// `signedByUserId !== approverUserId` → FE banner "Admin duyệt thay".
export type PeLevelOpinion = {
  id: string
  approvalWorkflowLevelId: string
  stepOrder: number
  stepName: string
  stepDepartmentId: string | null
  stepDepartmentName: string | null
  levelOrder: number
  levelName: string | null
  approverUserId: string
  approverFullName: string | null
  comment: string
  signedAt: string
  signedByUserId: string
  signedByFullName: string
}

// 2-stage department approval (Migration 16) — Stage 1=Review NV, 2=Confirm TPB.
// BLOCK transition khi NV review chưa có TPB confirm cùng (PE, Phase, Dept).
// CanBypassReview=true → NV được Stage=Confirm + IsBypassed=true (skip Review).
export const ApprovalStage = {
  Review: 1,
  Confirm: 2,
} as const
export type ApprovalStage = typeof ApprovalStage[keyof typeof ApprovalStage]

export const ApprovalStageLabel: Record<number, string> = {
  1: 'Review NV',
  2: 'Confirm TPB',
}

export type PeDepartmentApproval = {
  id: string
  phaseAtApproval: number
  departmentId: string
  departmentName: string | null
  stage: number              // 1=Review, 2=Confirm
  approverUserId: string
  approverName: string | null
  approverRoleSnapshot: string | null  // "TPB" | "NV" | "NV(bypass)"
  comment: string | null
  approvedAt: string
  isBypassed: boolean
}

// Mig 29 (S21 t5) — 5 Allow* options của Cấp Approver hiện tại (per-NV slot).
// FE filter Trả lại dropdown + Edit Section 2 enabled theo flag của slot này.
// F2 (Drafter skip) MOVED sang per-User (xem PeDetailBundle.drafterAllowSkipToFinal).
export type ApprovalWorkflowOptions = {
  allowReturnOneLevel: boolean
  allowReturnOneStep: boolean
  allowReturnToAssignee: boolean
  allowReturnToDrafter: boolean
  allowApproverEditDetails: boolean
  allowApproverEditBudget: boolean   // Mig 30 (S22+5) — F4 Section ngân sách
  allowApproverSkipToFinal: boolean  // Mig 31 (S23 t1) — F2 Approver duyệt thẳng Cấp cuối
  allowApproverFinalize: boolean     // [Mig 58 CCM item 4] slot này Duyệt = KẾT THÚC (không trình CEO)
  // [S155 F6] slot này được XÓA MỀM phiếu ChoDuyet khi tới lượt mình duyệt.
  // 🔴 PER-NGƯỜI: BE resolve slot theo `ApproverUserId == currentUser` rồi mới đọc cờ
  // (PurchaseEvaluationFeatures.cs:1083-1085) — KHÔNG phải OR-of-N cả Cấp.
  allowApproverDelete: boolean
}

// Mig 28 (S21 t4) — F1 mode Trả lại payload gửi BE
export const WorkflowReturnMode = {
  OneLevel: 1,
  OneStep: 2,
  Assignee: 3,
  Drafter: 4,
} as const
export type WorkflowReturnMode = typeof WorkflowReturnMode[keyof typeof WorkflowReturnMode]

export type PeDetailBundle = {
  id: string
  maPhieu: string | null
  type: number
  phase: number
  tenGoiThau: string
  diaDiem: string | null
  moTa: string | null
  projectId: string
  projectName: string
  // S57bis — Hạng mục công việc (WorkItem master) gắn header phiếu. Nullable cho
  // phiếu cũ tạo trước khi field này tồn tại. BE PE DTO trả 3 field này.
  workItemId: string | null
  workItemName: string | null
  workItemCode: string | null
  departmentId: string | null
  departmentName: string | null
  drafterUserId: string | null
  drafterName: string | null
  selectedSupplierId: string | null
  selectedSupplierName: string | null
  contractId: string | null
  paymentTerms: string | null
  // anh Kiệt FDC — 1 hyperlink tới thư mục hồ sơ trên NAS công ty (string? nullable,
  // BE HasMaxLength 1000). JSON camelCase "hoSoLink". KHÔNG entity con, dùng 1 cột.
  hoSoLink: string | null
  slaDeadline: string | null
  createdAt: string
  updatedAt: string | null
  // S61 — Ngân sách PE mới (module Budget cũ XÓA HẲN — budgetId/budget/budgetManual* DROP):
  budgetPeriodAmount: number | null        // 'Ngân sách - kỳ này' (row 3 Excel) cột PRO — drafter nhập
  // [Mig 59 2026-06-24 — anh Kiệt FDC / CCM] 'NS kỳ này' cột CCM (Section B THỰC HIỆN
  // tách 3 cột Dự án|PRO|CCM). PRO=budgetPeriodAmount sẵn có; CCM=cột này độc-lập.
  // Nhập qua PATCH /budget/ccm-period role-gate Admin|CostControl (absolute-set, 0 hợp lệ).
  ccmBudgetPeriodAmount: number | null     // 'Ngân sách - kỳ này' (row 3 Excel) cột CCM
  expectedRemainingAmount: number | null   // 'Giá trị thực hiện dự kiến còn lại' (row 8) — null = FE default NS còn lại
  budgetSummary: PeBudgetSummary | null    // bảng TỔNG HỢP NGÂN SÁCH TRÌNH KÝ (BE compute)
  // S69 — cờ gấp per-vai (PRO ĐỎ / CCM XANH). FE render badge header + toggle theo role.
  isUrgentByPro: boolean
  isUrgentByCcm: boolean
  // S69 — tổng giá chào của đơn vị NCC/TP ĐƯỢC CHỌN (winner). 0 khi chưa chọn.
  // FE so với ceoApprovalThreshold → hint "CCM duyệt là xong" / "Cần CEO duyệt".
  winnerQuoteTotal: number
  // S69 — ngưỡng gói CEO của workflow đã pin (PE.approvalWorkflowId). Null khi
  // chưa pin workflow V2 hoặc admin chưa set ngưỡng.
  ceoApprovalThreshold: number | null
  // [Mig 54 2026-06-18 — anh Kiệt FDC] Giá đề xuất tại "c. Giá chào thầu" (NGOÀI giá NCC):
  // PRO nhập dải Min/Max + CCM 1 giá. approvedPrice* = giá CHỐT người duyệt cuối chọn
  // (source ∈ Ncc/ProMin/ProMax/Ccm). canEdit* = capability theo role (BE-computed).
  proSuggestedMinPrice: number | null
  proSuggestedMaxPrice: number | null
  ccmSuggestedPrice: number | null
  // Ghi chú giải thích vì sao chọn Min/Max (PRO) / vì sao 1 giá (CCM). Lưu kèm
  // body /suggested-price/pro|ccm (absolute-set field `note`).
  proSuggestedPriceNote: string | null
  ccmSuggestedPriceNote: string | null
  approvedPriceAmount: number | null
  approvedPriceSource: string | null
  approvedPriceMaxAmount: number | null
  canEditProSuggestedPrice: boolean
  canEditCcmSuggestedPrice: boolean
  // Mig 23 — Pin schema mới ApprovalWorkflowsV2 (User chọn lúc create).
  approvalWorkflowId: string | null
  approvalWorkflowCode: string | null
  approvalWorkflowName: string | null
  approvalWorkflowVersion: number | null
  // Mig 29 (S21 t5) + Mig 30 (S22+5) + Mig 31 (S23 t1) — 7 Allow* options của
  // Cấp hiện tại (per-NV slot). Null nếu V1 legacy hoặc pointer chưa init. FE
  // render Trả lại dropdown + Edit Section 2/4 + Duyệt thẳng Cấp cuối
  // conditional theo flag của slot Approver đang duyệt.
  currentLevelOptions: ApprovalWorkflowOptions | null
  // Mig 24 — info Bước/Cấp đang chờ duyệt (chỉ populate khi pin V2 + Phase=ChoDuyet)
  currentApproval: PeCurrentApproval | null
  // Mig 24 — full flow snapshot (Bước → Cấp → NV) với Status per level
  approvalFlow: PeApprovalFlow | null
  // [Mig 58 AllowApproverFinalize — anh Kiệt FDC, S89] Quy trình có cấp bật "Duyệt là KẾT
  // THÚC" (không trình CEO). BE first-reachable finalize theo Step.Order↑ → Level.Order↑
  // (dùng nơi flow THỰC kết thúc). V1 (approvalWorkflowId==null) → endsBeforeCeo=false, names null.
  endsBeforeCeo: boolean
  finalizeStepName: string | null
  finalizeLevelName: string | null
  suppliers: PeSupplier[]
  details: PeDetailRow[]
  approvals: PeApproval[]
  attachments: PeAttachment[]
  departmentOpinions: PeDepartmentOpinion[]
  // Mig 26 — Section 5 V2 dynamic. Empty cho V1 / V2 chưa có cấp duyệt.
  levelOpinions: PeLevelOpinion[]
  workflow: PeWorkflowSummary
}
