import { describe, test, expect } from "bun:test";
import { ValueType } from "../../src/modules/credentials/credentialTypeDefs";
import { fieldValidator } from "../../src/modules/credentials/fieldValidator";
import type {
  CredentialField,
  CredentialTypeField,
} from "../../src/modules/credentials/credentialTypeDefs";

const baseAcceptableFields: CredentialTypeField[] = [
  {
    id: "username",
    name: "Username",
    required: true,
    secure: false,
    valueType: ValueType.PLAIN_TEXT,
  },
  {
    id: "password",
    name: "Password",
    required: true,
    secure: true,
    valueType: ValueType.PASSWORD,
  },
  {
    id: "notes",
    name: "Notes",
    required: false,
    secure: false,
    valueType: ValueType.PLAIN_TEXT,
  },
];

describe("fieldValidator", () => {
  test("validates correct fields and returns validated array", async () => {
    const fields: CredentialField[] = [
      { fieldId: "username", value: "admin" },
      { fieldId: "password", value: "secret123" },
    ];
    const result = await fieldValidator(fields, baseAcceptableFields);
    expect(result).toHaveLength(2);
    expect(result[0]!.fieldId).toBe("username");
    expect(result[0]!.secure).toBe(false);
    expect(result[1]!.fieldId).toBe("password");
    expect(result[1]!.secure).toBe(true);
  });

  test("throws GenericError for unknown field ID", async () => {
    const fields: CredentialField[] = [
      { fieldId: "nonexistent", value: "val" },
    ];
    await expect(fieldValidator(fields, baseAcceptableFields)).rejects.toThrow(
      "Invalid field ID: nonexistent",
    );
  });

  test("handles optional fields", async () => {
    const fields: CredentialField[] = [
      { fieldId: "notes", value: "some note" },
    ];
    const result = await fieldValidator(fields, baseAcceptableFields);
    expect(result).toHaveLength(1);
    expect(result[0]!.secure).toBe(false);
  });

  test("handles empty fields array", async () => {
    const result = await fieldValidator([], baseAcceptableFields);
    expect(result).toEqual([]);
  });

  test("marks MULTI_CREDENTIAL fields correctly", async () => {
    const acceptableFields: CredentialTypeField[] = [
      {
        id: "sub_creds",
        name: "Sub Credentials",
        required: false,
        secure: false,
        valueType: ValueType.MULTI_CREDENTIAL,
        subFields: [
          {
            id: "sub_user",
            name: "Sub User",
            required: true,
            secure: false,
            valueType: ValueType.PLAIN_TEXT,
          },
        ],
      },
    ];
    const fields: CredentialField[] = [{ fieldId: "sub_creds", value: "" }];
    const result = await fieldValidator(fields, acceptableFields);
    expect(result).toHaveLength(1);
    expect(result[0]!.isMultiCredential).toBe(true);
    expect(result[0]!.secure).toBe(false);
  });
});
