using SolutionErp.Domain.Contracts;

namespace SolutionErp.Application.Contracts.Dtos;

public record ContractListItemDto(
    Guid Id,
    string? MaHopDong,
    string? TenHopDong,
    ContractType Type,
    ContractPhase Phase,
    Guid SupplierId,
    string SupplierName,
    Guid ProjectId,
    string ProjectName,
    decimal GiaTri,
    DateTime? SlaDeadline,
    DateTime CreatedAt,
    // [W7 S161] Cờ "đã có bản cứng" — append-CUỐI + CÓ DEFAULT có chủ đích.
    // 🔴 Default BẮT BUỘC: DTO này còn 2 call-site dựng bằng 12 arg
    // (`ContractFeatures.cs` ListDeleted + Inbox) — bỏ default là vỡ compile 2 chỗ đó.
    // Hệ quả KHAI THẲNG: cờ CHỈ được derive ở `ListContractsQueryHandler` (màn danh sách
    // HĐ, nơi FE gắn badge); ở màn "Đã xóa" + "Hộp thư" nó luôn `false` vì KHÔNG derive
    // — cố ý giữ scope W7 tối thiểu, KHÔNG phải bỏ sót.
    // Nguồn sự-thật của cờ = có ≥1 `ContractAttachment.Purpose == SealedCopy(3)`.
    bool HasSealedCopy = false);

public record ContractDetailDto(
    Guid Id,
    string? MaHopDong,
    string? TenHopDong,
    string? NoiDung,
    ContractType Type,
    ContractPhase Phase,
    Guid SupplierId,
    string SupplierName,
    Guid ProjectId,
    string ProjectName,
    Guid? DepartmentId,
    string? DepartmentName,
    Guid? DrafterUserId,
    string? DrafterName,
    Guid? TemplateId,
    decimal GiaTri,
    bool BypassProcurementAndCCM,
    DateTime? SlaDeadline,
    string? DraftData,
    DateTime CreatedAt,
    DateTime? UpdatedAt,
    // [S61 Mig 50] Module Budget cũ XÓA — Contract.BudgetId drop, GIỮ BudgetManual*
    // (ngân sách nhập tay của HĐ không đổi, anh Kiệt chỉ redesign ngân sách PE).
    string? BudgetManualName,
    decimal? BudgetManualAmount,
    List<ContractApprovalDto> Approvals,
    List<ContractCommentDto> Comments,
    List<ContractAttachmentDto> Attachments,
    WorkflowSummaryDto Workflow,
    // [Plan B S29 2026-05-22 Chunk E2] V2 workflow fields — mirror PE pattern.
    // ApprovalWorkflowId pin lúc create (Mig 32). FE Section 5 detect V2 mode
    // qua field này: nếu Guid → render dynamic LevelOpinionsSectionV2;
    // nếu null → V1 legacy KHÔNG Section 5 V2.
    // FE fetch ApprovalFlow shape via /api/approval-workflows-v2/{ApprovalWorkflowId}.
    Guid? ApprovalWorkflowId = null,
    int? CurrentApprovalLevelOrder = null,
    List<ContractLevelOpinionDto>? LevelOpinions = null,
    // ===================== [W2 S187 — YC-023 GĐ3] append-CUỐI =========================
    // 🔴 Positional record: 3 field dưới BẮT BUỘC có default `null` và đứng CUỐI —
    // call-site duy nhất (`ContractFeatures.cs:721`) truyền theo vị trí, thêm vào giữa
    // là vỡ mọi arg sau nó.
    //
    //  • `Source` — NGUỒN GỐC KHKK (GĐ2) của HĐ này. Đường đọc là REVERSE-JOIN
    //    `ContractSigningPlanLines WHERE ContractId = {id}`: `Contract` KHÔNG mang con-trỏ
    //    ngược nào sang kế hoạch (`Contract.cs` 0 field `SigningPlan*`) — con-trỏ nằm ở
    //    phía dòng kế hoạch (`ContractSigningPlanLine.cs:46`, write-site DUY NHẤT là bridge
    //    K7 `CreateContractFromSigningPlanFeatures.cs:238`). HĐ tạo tay / HĐ cũ trước K7
    //    ⇒ 0 dòng nối ⇒ `null` ⇒ FE KHÔNG render card (null-path là ca THƯỜNG, không phải lỗi).
    //  • `CurrentWorkflowStepIndex` — con-trỏ Bước 0-based, đọc THẲNG cột đã có sẵn
    //    (`Contract.cs:40`, Mig 21) ⇒ wave này 0-migration. Ghép với
    //    `CurrentApprovalLevelOrder` (đã có `:63`) thành ĐỦ CẶP con-trỏ mà panel duyệt cần.
    //  • `WorkflowSteps` — CÂY THÔ (Bước → Cấp → người) của quy trình V2 đã pin.
    //    🔴 KHUÔN KHKK, KHÔNG PHẢI KHUÔN PE: BE trả cây thô + cặp con-trỏ, panel FE TỰ SUY
    //    Done/Current/Pending — cố ý KHÔNG precompute `status` như cặp DTO PE
    //    (`PurchaseEvaluationCurrentApprovalDto`/`...ApprovalFlowDto`), vì panel được chọn
    //    mirror là `KhkkWorkflowPanel` và nó tiêu thụ ĐÚNG shape này
    //    (`ContractSigningPlanFeatures.cs:194` + `:205`).
    //    `null` khi HĐ chưa pin `ApprovalWorkflowId` (V1 legacy) — FE giữ nhánh cũ.
    //    ⚠️ Đường CŨ vẫn sống: FE Section 5 từng fetch cây qua
    //    `/api/approval-workflows-v2/{ApprovalWorkflowId}` (xem chú thích `:61`). Field này
    //    là đường INLINE 1-request để panel không phải gọi thêm — KHÔNG đẻ đường thứ 3.
    ContractSourceDto? Source = null,
    int? CurrentWorkflowStepIndex = null,
    List<ContractWorkflowStepDto>? WorkflowSteps = null,
    // ================= [WQ3-BE S190 — YC-030 Q3] append-CUỐI (khuôn KHKK DTO
    // `ContractSigningPlanFeatures.cs:216-224`) ==========================================
    //  • `WorkflowCode` + `WorkflowVersion` — dòng meta `{code} v{NN}` của panel duyệt. Đọc từ
    //    `ApprovalWorkflow` ĐÃ PIN (cùng một lượt nạp cây thô `:787` — KHÔNG query thêm). `null`
    //    khi HĐ chưa pin V2 (V1 legacy) ⇒ FE không render dòng meta.
    //    🔴 `Code` ở đây là mã QUY TRÌNH (`HD-TP`, `QT-HD-V2-001`…), KHÔNG phải `MaHopDong` —
    //    hai thứ trùng chữ "mã" mà khác hẳn nhau.
    //  • `EndedByLevelFinalize` — CỜ RUNTIME đọc THẲNG cột `Contract.EndedByLevelFinalize` (Mig 73),
    //    KHÔNG suy từ `AllowApproverFinalize` của cây (bài #78 / PE Mig 60: HĐ opt-out sẽ bị gắn
    //    nhãn sai, và HĐ kết-thúc-sớm thật mất nhãn ngay khi admin gỡ tick). Non-nullable: HĐ V1
    //    legacy luôn `false` — đúng sự thật, không phải "không biết".
    string? WorkflowCode = null,
    int? WorkflowVersion = null,
    bool EndedByLevelFinalize = false);

// [W2 S187] Nguồn gốc GĐ2 (Kế hoạch ký kết — KHKK) của một HĐ. Dựng từ N dòng kế hoạch
// cùng trỏ về HĐ này (bridge K7 gán `Line.ContractId` cho TỪNG dòng được chọn —
// `CreateContractFromSigningPlanFeatures.cs:238`; rào (3) `:111-115` bảo đảm N dòng đó
// cùng 1 NCC và rào (2) `:101-109` bảo đảm cùng 1 phiếu).
//
// 3 field nullable (`MaKeHoach`/`ApprovalGroup`/`PurchaseEvaluationId`) = dữ liệu của
// PHIẾU CHA. Chúng null KHI VÀ CHỈ KHI dòng còn sống mà phiếu cha không đọc được nữa
// (xoá mềm) — ca gần như bất khả (xoá phiếu chỉ cho ở Nháp/Trả lại/Từ chối, mà phiếu đẻ
// ra HĐ thì đã DaDuyet). Cố ý KHÔNG nuốt cả `Source` thành null ở ca đó: nuốt đi thì HĐ
// mồ-côi trông Y HỆT HĐ tạo tay — hai thứ khác hẳn nhau.
public record ContractSourceDto(
    Guid PlanId,
    string? MaKeHoach,
    int? ApprovalGroup,
    Guid? PurchaseEvaluationId,
    // Tên hạng mục của TỪNG dòng nối (denorm tại thời điểm gán — `ContractSigningPlanLine.cs:27`).
    // Dòng chưa gán hạng mục ⇒ "(chưa gán hạng mục)" (đúng chữ bridge dùng ở `:121`) thay vì
    // bị lọc bỏ: giữ `Count` == số dòng để FE không hiển thị ít chip hơn số tiền đã cộng.
    List<string> TenHangMucs,
    // Σ `ApprovedAmount` — giá CHỐT tại choke-point finalize. Bridge cấm dòng chưa có giá
    // chốt (`:125-127`) ⇒ trên thực tế 0 dòng nào null; `?? 0` chỉ là rào.
    decimal ApprovedAmountTotal);

// [W2 S187] Cây thô workflow V2 — mirror 1-1 `ContractSigningPlanWorkflowStepDto`
// (`ContractSigningPlanFeatures.cs:142-152`). KHÔNG có field `Status`: trạng thái là thứ
// panel tự suy từ cặp con-trỏ, BE chỉ trả cấu hình.
public record ContractWorkflowStepDto(
    Guid Id,
    int Order,
    string Name,
    Guid? DepartmentId,
    List<ContractWorkflowLevelDto> Levels,
    // Tên phòng của Bước — `Step.DepartmentId` là loose-Guid (không nav) ⇒ join 1 lượt ở
    // handler, KHÔNG N+1. Default null để append thêm field sau này không vỡ call-site.
    string? DepartmentName = null);

public record ContractWorkflowLevelDto(
    Guid Id,
    int Order,
    string? Name,
    Guid ApproverUserId,
    string? ApproverFullName,
    // Cờ per-Cấp "Cấp này được KẾT THÚC quy trình" — trả kèm để panel mirror KHKK có đủ
    // dữ liệu; HĐ có dùng ô-tích này hay không là quyết của wave màn duyệt (W6), không
    // phải của DTO.
    bool AllowApproverFinalize = false);

// [Plan B S29 2026-05-22 Chunk E2] Ý kiến cấp duyệt V2 dynamic theo
// ApprovalWorkflowLevel. Mirror PE PurchaseEvaluationLevelOpinionDto pattern.
// Service ApproveV2Async UPSERT (Plan B Chunk B2 1f199b0). Comment empty
// fallback "(duyệt — không ý kiến)". SignedByUserId !== Level.ApproverUserId
// → FE show banner "Admin duyệt thay".
public record ContractLevelOpinionDto(
    Guid Id,
    Guid ApprovalWorkflowLevelId,
    int StepOrder,
    string StepName,
    int LevelOrder,
    string? LevelName,
    Guid ApproverUserId,
    string? ApproverFullName,
    string Comment,
    DateTime SignedAt,
    Guid SignedByUserId,
    string? SignedByFullName);

// Policy snapshot for the FE — lets UI render next-phase buttons dynamically
// without hardcoding the transition map (single source of truth in BE).
public record WorkflowSummaryDto(
    string PolicyName,
    string PolicyDescription,
    List<ContractPhase> ActivePhases,
    List<ContractPhase> NextPhases);

public record ContractApprovalDto(
    Guid Id,
    ContractPhase FromPhase,
    ContractPhase ToPhase,
    Guid? ApproverUserId,
    string? ApproverName,
    ApprovalDecision Decision,
    string? Comment,
    DateTime ApprovedAt);

public record ContractCommentDto(
    Guid Id,
    Guid UserId,
    string UserName,
    ContractPhase Phase,
    string Content,
    DateTime CreatedAt);

public record ContractAttachmentDto(
    Guid Id,
    string FileName,
    string StoragePath,
    long FileSize,
    string ContentType,
    AttachmentPurpose Purpose,
    string? Note,
    DateTime CreatedAt);
