import { describe, expect, it } from "vitest";
import { ProposalWorkflowStateSchema, computeWorkflowCompletionPercent, computeWorkflowGate } from "@/lib/proposals/workflow-state";

function buildBaseWorkflow() {
  return ProposalWorkflowStateSchema.parse({
    step: 5,
    info: {
      title: "Licitacion de prueba",
      issuingEntity: "Entidad contratante",
      procedureType: "Publica",
      jurisdiction: "Federal",
      state: "Nuevo Leon",
      municipality: "San Pedro",
      sector: "Tecnologia",
      description: "Servicio de arrendamiento",
      convocatoriaUrl: "https://example.com/convocatoria",
    },
    requirements: [
      {
        id: "req-1",
        title: "Formato I",
        description: "Acreditacion de personalidad",
        category: "legal",
        mandatory: true,
        source: "official_format",
        status: "completed",
        note: "",
        evidences: [
          {
            id: "evidence-1",
            documentId: "doc-1",
            fileName: "formato-i.pdf",
            uploadedAtIso: "2026-01-10T10:00:00.000Z",
          },
        ],
      },
      {
        id: "req-2",
        title: "Carta de fabricante",
        description: "Documento tecnico",
        category: "tecnico",
        mandatory: true,
        source: "required_checklist",
        status: "completed",
        note: "",
        evidences: [
          {
            id: "evidence-2",
            documentId: "doc-2",
            fileName: "carta-fabricante.pdf",
            uploadedAtIso: "2026-01-10T10:05:00.000Z",
          },
        ],
      },
    ],
    technicalSections: [
      {
        id: "section-1",
        title: "Propuesta tecnica",
        description: "Detalle tecnico",
        completed: true,
      },
    ],
    economicItems: [
      {
        id: "eco-1",
        concept: "Equipo de computo",
        unit: "pieza",
        quantity: 10,
        unitPrice: 1000,
      },
    ],
    milestones: [
      {
        id: "milestone-1",
        title: "Presentacion de propuestas",
        dateIso: "2026-11-30T20:00:00.000Z",
        location: "Sala de juntas",
        note: "",
      },
    ],
    signatureCompliance: {
      policyStatus: "condicionado",
      policyName: "Politica estatal",
      jurisdictionLabel: "Nuevo Leon",
      sourceUrl: "https://www.nl.gob.mx/",
      minimumEvidence: ["Clausula expresa en convocatoria", "Certificado de firma"],
      notes: "",
      validatedByLegal: true,
    },
    readyMarked: false,
  });
}

describe("proposal workflow state", () => {
  it("returns allReady true when every hard-gate condition is met", () => {
    const workflow = buildBaseWorkflow();
    const gate = computeWorkflowGate(workflow);

    expect(gate.infoReady).toBe(true);
    expect(gate.docsReady).toBe(true);
    expect(gate.technicalReady).toBe(true);
    expect(gate.economicReady).toBe(true);
    expect(gate.datesReady).toBe(true);
    expect(gate.signatureReady).toBe(true);
    expect(gate.allReady).toBe(true);
  });

  it("blocks readiness when mandatory requirements remain pending", () => {
    const workflow = buildBaseWorkflow();
    workflow.requirements[0] = {
      ...workflow.requirements[0],
      status: "pending",
    };

    const gate = computeWorkflowGate(workflow);
    expect(gate.docsReady).toBe(false);
    expect(gate.allReady).toBe(false);
  });

  it("computes completion percentage from six-step gate states", () => {
    const workflow = buildBaseWorkflow();
    expect(computeWorkflowCompletionPercent(workflow)).toBe(100);

    workflow.milestones[0] = {
      ...workflow.milestones[0],
      dateIso: null,
    };

    expect(computeWorkflowCompletionPercent(workflow)).toBe(67);
  });

  it("requires legal validation when signature policy is flagged as critical", () => {
    const workflow = buildBaseWorkflow();
    workflow.signatureCompliance = {
      ...workflow.signatureCompliance,
      policyStatus: "requiere_validacion_legal",
      validatedByLegal: false,
    };

    const gate = computeWorkflowGate(workflow);
    expect(gate.signatureReady).toBe(false);
    expect(gate.allReady).toBe(false);
  });
});
