import { describe, expect, it } from "vitest";
import { PAYLOAD_AUTH_PII_DEFAULTS, type FieldPii } from "./pii-types";

const CREDENTIAL_FIELDS = [
  "password",
  "salt",
  "hash",
  "resetPasswordToken",
  "resetPasswordExpiration",
  "loginAttempts",
  "lockUntil",
  "apiKey",
  "apiKeyIndex",
] as const;

const DSR_MANAGED_FIELDS = ["processingRestrictedAt", "consentState"] as const;

describe("FieldPii type safety", () => {
  it("rejects FieldPii missing required fields at compile time", () => {
    // @ts-expect-error — 'purpose', 'exportable', 'restrictable' are required
    const _missingRequired: FieldPii = { category: "contact-email" };
    void _missingRequired;
  });

  it("rejects FieldPii missing exportable at compile time", () => {
    // @ts-expect-error — 'exportable' is required
    const _missingExportable: FieldPii = {
      category: "contact-email",
      purpose: ["account-authentication"],
      restrictable: true,
    };
    void _missingExportable;
  });
});

describe("FieldPii valid shapes", () => {
  it("accepts a minimal valid FieldPii", () => {
    const valid: FieldPii = {
      category: "contact-email",
      purpose: ["account-authentication"],
      exportable: true,
      restrictable: false,
    };
    expect(valid.category).toBe("contact-email");
    expect(valid.retention).toBeUndefined();
  });

  it("accepts FieldPii with optional retention", () => {
    const withRetention: FieldPii = {
      category: "network-ip",
      purpose: ["analytics-aggregation"],
      exportable: false,
      restrictable: false,
      retention: {
        duration: "P30D",
        trigger: "from-creation",
        action: "hard-delete",
      },
    };
    expect(withRetention.retention?.duration).toBe("P30D");
    expect(withRetention.retention?.trigger).toBe("from-creation");
    expect(withRetention.retention?.action).toBe("hard-delete");
  });

  it("accepts a custom PiiCategory string via extension escape hatch", () => {
    const extended: FieldPii = {
      category: "custom-biometric-data",
      purpose: ["legal-compliance"],
      exportable: false,
      restrictable: true,
    };
    expect(extended.category).toBe("custom-biometric-data");
  });
});

describe("PAYLOAD_AUTH_PII_DEFAULTS", () => {
  it("sets all credential fields to null", () => {
    for (const field of CREDENTIAL_FIELDS) {
      expect(PAYLOAD_AUTH_PII_DEFAULTS[field]).toBeNull();
    }
  });

  it("maps email to a non-null FieldPii with correct shape", () => {
    const emailPii = PAYLOAD_AUTH_PII_DEFAULTS["email"];
    expect(emailPii).not.toBeNull();
    expect(emailPii?.category).toBe("contact-email");
    expect(emailPii?.purpose).toContain("account-authentication");
    expect(emailPii?.purpose).toContain("transactional-notifications");
    expect(emailPii?.exportable).toBe(true);
    expect(emailPii?.restrictable).toBe(true);
  });

  it("has exactly 12 keys: email, 9 credential fields, and 2 DSR-managed fields", () => {
    expect(Object.keys(PAYLOAD_AUTH_PII_DEFAULTS)).toHaveLength(12);
  });

  it("sets DSR-managed fields to null", () => {
    for (const field of DSR_MANAGED_FIELDS) {
      expect(PAYLOAD_AUTH_PII_DEFAULTS[field]).toBeNull();
    }
  });

  it("email has no retention override (falls back to collection-level)", () => {
    const emailPii = PAYLOAD_AUTH_PII_DEFAULTS["email"];
    expect(emailPii?.retention).toBeUndefined();
  });
});
