using SolutionErp.Domain.Common;

namespace SolutionErp.Domain.ContractSigningPlans;

// [W1 Mig 69 — S161 2026-07-29] Aggregate root "Kế hoạch ký kết HĐ" (GĐ2, tờ FO-002.01).
// Nối tiếp phiếu Duyệt NCC (PE) đã DaDuyet → chốt giá per-NCC trước khi sinh HĐ (GĐ3).
//
// Cookie-cutter mirror PurchaseEvaluation (con-trỏ ĐÔI StepIndex + LevelOrder cho
// workflow V2 OR-of-N) — KHÔNG mirror Proposal (Proposal chỉ có LevelOrder, flatten
// SelectMany làm OR-of-N thành AND, xem spec §2.1).
//
// Convention loose-Guid: PurchaseEvaluationId / ProjectId / DepartmentId / DrafterUserId
// KHÔNG FK vật lý (mirror PE `PurchaseEvaluation.cs:15-18` + Mig 49). FK vật lý CHỈ:
// nội bộ module (Lines/DossierItems/... Cascade) + ApprovalWorkflowId → bảng V2 dùng chung.
public class ContractSigningPlan : AuditableEntity
{
    // [W2 S161] "KHKK/2026/001" — gen atomic NGAY LÚC TẠO phiếu (POST trả về mã liền).
    // 🔴 Đính chính comment W1 ("gen lúc Submit"): spec W2 §③-B chốt acceptance
    // `POST /api/contract-signing-plans` → mã khớp `^KHKK/\d{4}/\d{3}$` ⇒ không thể defer
    // tới Submit. Vẫn để nullable vì cột đã sinh nullable ở Mig 69 (không đổi schema) —
    // phiếu tạo bằng đường CQRS luôn có mã.
    public string? MaKeHoach { get; set; }

    public Guid PurchaseEvaluationId { get; set; }       // loose-Guid + IX — phiếu PE nguồn (DaDuyet)
    public Guid ProjectId { get; set; }                  // denorm để lọc list (loose-Guid, mirror PE)
    public Guid? DepartmentId { get; set; }              // [C5 review-schema] phòng của phiếu — vế `DeptManager`
                                                         // của guard trình so với cột NÀY (Step.DepartmentId chỉ là
                                                         // hint của quy trình, KHÔNG thay được phòng của phiếu).
    public Guid DrafterUserId { get; set; }              // BCH soạn kế hoạch

    public ContractSigningPlanPhase Phase { get; set; } = ContractSigningPlanPhase.DangSoanThao;

    // [K2 Mig 71 — S164] NHÓM DUYỆT 1..8 (N1..N8 theo SOL-CCM-SP-002). 1 phiếu = 1 nhóm,
    // N hạng mục CÙNG nhóm. Phiếu cũ backfill = 1 (Mig 71 `Sql UPDATE`) ⇒ COUNT(phiếu) ==
    // Σ COUNT 8 folder, không có phiếu nào rơi ngoài cây.
    // 🔴 K2 là CHỦ DUY NHẤT của cột này (QĐ-3/spec §②-3): K3 chỉ ĐỌC (map Code `KHKK-N{n}`
    // ↔ group + validator phiếu-pin-đúng-nhóm). Range 1..8 gác bằng validator, KHÔNG CHECK
    // constraint (khuôn repo: `ContractCatalogEntry.ApprovalGroup` cũng vậy).
    // 🔴 [gate-K2 F-9] Mig 71 để DEFAULT constraint 0 (AddColumn) — app LUÔN set giá trị;
    // CẤM INSERT SQL thô (họ #84): SQL thô sẽ ra nhóm 0 ngoài dải 1..8, rơi khỏi cây 8 folder câm lặng.
    public int ApprovalGroup { get; set; } = 1;

    // [K2 Mig 71 — S164, forward-provision cho K3] Cờ RUNTIME "phiếu kết thúc SỚM bằng
    // level-finalize" (approver ở Cấp có `AllowApproverFinalize` tick kết-thúc-tại-đây).
    // 🔴 GHOST-WINDOW KHAI TRƯỚC: K2 ĐẺ cột, K3 TIÊU THỤ. Từ lúc K2 land tới lúc K3 land,
    // cột này NẰM IM = luôn false, KHÔNG có site nào ghi (service KHKK hiện chỉ có đúng một
    // nhánh set DaDuyet — `ContractSigningPlanWorkflowService.cs:277-278` — và nhánh đó là
    // đường THƯỜNG, không phải finalize sớm). Cố ý gộp vào Mig 71 để K3 = 0-mig
    // (spec §②-9 + vá-7 item-6). Đọc RUNTIME chứ không suy từ CONFIG = né tái diễn #78
    // (PE S97: phiếu opt-out vẫn lên CEO mà display suy từ cờ config nên báo sai).
    public bool EndedByLevelFinalize { get; set; }

    // Workflow V2 pin (ApplicableType = ContractSigningPlan = 10). Con-trỏ ĐÔI mirror PE:
    // StepIndex 0-based (Bước) + LevelOrder 1-based (Cấp trong Bước). Null khi terminal.
    public Guid? ApprovalWorkflowId { get; set; }
    public int? CurrentWorkflowStepIndex { get; set; }
    public int? CurrentApprovalLevelOrder { get; set; }

    // 🔸 SLA = FE hiển thị THAM KHẢO (O-2 owner chốt). KHÔNG đăng ký SlaExpiryJob,
    // KHÔNG có cờ SlaWarningSent — cố ý khai rõ để cột này không rơi vào lớp
    // "cột có mà 0 ai đọc"; người đọc nó là FE, không phải job.
    public DateTime? SlaDeadline { get; set; }

    public string? HoSoLink { get; set; }                // hyperlink thư mục hồ sơ NAS (mirror PE HoSoLink)
    public string? GhiChu { get; set; }

    public List<ContractSigningPlanLine> Lines { get; set; } = new();
    public List<ContractSigningPlanDossierItem> DossierItems { get; set; } = new();
    public List<ContractSigningPlanAttachment> Attachments { get; set; } = new();
    public List<ContractSigningPlanChangelog> Changelogs { get; set; } = new();
    public List<ContractSigningPlanApproval> Approvals { get; set; } = new();
    public List<ContractSigningPlanLevelOpinion> LevelOpinions { get; set; } = new();
}
