import {
  EstimateExportFormat,
  EstimateStatus,
  EstimateVersionStatus,
} from "@capakraken/shared";
import { describe, expect, it } from "vitest";
import {
  serializeEstimateExport,
  type EstimateExportSource,
} from "../estimate/export-serializer.js";

const createdAt = new Date("2026-03-13T08:00:00.000Z");

function buildSource(): EstimateExportSource {
  return {
    estimate: {
      id: "est_1",
      projectId: "project_1",
      name: "CGI Estimate",
      opportunityId: "OP-42",
      baseCurrency: "EUR",
      status: EstimateStatus.APPROVED,
      createdAt,
      updatedAt: createdAt,
    },
    project: {
      id: "project_1",
      shortCode: "CGI-001",
      name: "CGI Project",
      status: "ACTIVE",
      startDate: "2026-03-01T00:00:00.000Z",
      endDate: "2026-04-01T00:00:00.000Z",
    },
    version: {
      id: "ver_1",
      versionNumber: 1,
      label: "Approved",
      status: EstimateVersionStatus.APPROVED,
      notes: "Ready for export",
      lockedAt: createdAt,
      projectSnapshot: {},
      createdAt,
      updatedAt: createdAt,
      assumptions: [
        {
          id: "assumption_1",
          category: "commercial",
          key: "pricingStructure",
          label: "Pricing Structure",
          valueType: "string",
          value: "fixed-bid",
          sortOrder: 0,
          notes: null,
          createdAt,
          updatedAt: createdAt,
        },
      ],
      scopeItems: [
        {
          id: "scope_1",
          sequenceNo: 10,
          scopeType: "SHOT",
          packageCode: "PKG-1",
          name: "Shot 010",
          description: "Main hero shot",
          scene: "Scene 01",
          page: null,
          location: "Berlin",
          assumptionCategory: null,
          technicalSpec: { resolution: "4K" },
          frameCount: 120,
          itemCount: 1,
          unitMode: "shot",
          internalComments: null,
          externalComments: null,
          metadata: {},
          createdAt,
          updatedAt: createdAt,
        },
      ],
      demandLines: [
        {
          id: "line_1",
          scopeItemId: "scope_1",
          roleId: "role_1",
          resourceId: "resource_1",
          lineType: "LABOR",
          name: "Comp Artist",
          chapter: "Compositing",
          hours: 40,
          days: 5,
          fte: 1,
          rateSource: "resource",
          costRateCents: 5000,
          billRateCents: 8000,
          currency: "EUR",
          costTotalCents: 200000,
          priceTotalCents: 320000,
          monthlySpread: { "2026-03": 40 },
          staffingAttributes: { location: "Berlin" },
          metadata: {},
          createdAt,
          updatedAt: createdAt,
        },
      ],
      resourceSnapshots: [
        {
          id: "snapshot_1",
          resourceId: "resource_1",
          sourceEid: "E100",
          displayName: "Alex Artist",
          chapter: "Compositing",
          roleId: "role_1",
          currency: "EUR",
          lcrCents: 5000,
          ucrCents: 8000,
          fte: 1,
          location: "Berlin",
          country: "DE",
          level: "Senior",
          workType: "Remote",
          attributes: {},
          createdAt,
          updatedAt: createdAt,
        },
      ],
      metrics: [
        {
          id: "metric_1",
          key: "total_hours",
          label: "Total Hours",
          metricGroup: "summary",
          valueDecimal: 40,
          valueCents: null,
          currency: null,
          metadata: {},
          createdAt,
          updatedAt: createdAt,
        },
      ],
    },
  };
}

describe("estimate export serializer", () => {
  it("creates a structured JSON export payload", async () => {
    const payload = await serializeEstimateExport(buildSource(), EstimateExportFormat.JSON);

    expect(payload.encoding).toBe("utf8");
    expect(payload.mimeType).toBe("application/json; charset=utf-8");
    expect(payload.summary.totalHours).toBe(40);
    expect(payload.content).toContain('"estimateId": "est_1"');
    expect(payload.previewText).toContain('"schemaVersion": 1');
  });

  it("creates a multi-sheet xlsx export payload", async () => {
    const payload = await serializeEstimateExport(buildSource(), EstimateExportFormat.XLSX);
    const ExcelJS = await import("exceljs");
    const workbook = new ExcelJS.Workbook();
    const workbookBytes = Uint8Array.from(Buffer.from(payload.content, "base64"));
    const workbookBuffer = workbookBytes.buffer.slice(
      workbookBytes.byteOffset,
      workbookBytes.byteOffset + workbookBytes.byteLength,
    );
    await workbook.xlsx.load(workbookBuffer);

    expect(payload.encoding).toBe("base64");
    expect(payload.sheetNames).toEqual([
      "Overview",
      "Assumptions",
      "Scope",
      "DemandLines",
      "Resources",
      "Metrics",
    ]);
    expect(workbook.getWorksheet("DemandLines")).toBeDefined();
    expect(payload.byteLength).toBeGreaterThan(100);
  });
});
