import { Prisma } from "@prisma/client";
import { describe, expect, test } from "vitest";
import { TResponse } from "@formbricks/types/responses";
import { TSurveyElementTypeEnum } from "@formbricks/types/surveys/elements";
import { TSurvey } from "@formbricks/types/surveys/types";
import {
  buildWhereClause,
  calculateTtcTotal,
  extracMetadataKeys,
  extractChoiceIdsFromResponse,
  extractSurveyDetails,
  generateAllPermutationsOfSubsets,
  getResponseContactAttributes,
  getResponseHiddenFields,
  getResponseMeta,
  getResponsesFileName,
  getResponsesJson,
} from "./utils";

describe("Response Utils", () => {
  describe("calculateTtcTotal", () => {
    test("should calculate total time correctly", () => {
      const ttc = {
        question1: 10,
        question2: 20,
        question3: 30,
      };
      const result = calculateTtcTotal(ttc);
      expect(result._total).toBe(60);
    });

    test("should handle empty ttc object", () => {
      const ttc = {};
      const result = calculateTtcTotal(ttc);
      expect(result._total).toBe(0);
    });
  });

  describe("buildWhereClause", () => {
    const mockSurvey: Partial<TSurvey> = {
      id: "survey1",
      name: "Test Survey",
      blocks: [],
      questions: [],
      type: "app",
      hiddenFields: { enabled: true, fieldIds: [] },
      createdAt: new Date(),
      updatedAt: new Date(),
      environmentId: "env1",
      createdBy: "user1",
      status: "draft",
    };

    test("should build where clause with finished filter", () => {
      const filterCriteria = { finished: true };
      const result = buildWhereClause(mockSurvey as TSurvey, filterCriteria);
      expect(result.AND).toContainEqual({ finished: true });
    });

    test("should build where clause with date range", () => {
      const filterCriteria = {
        createdAt: {
          min: new Date("2024-01-01"),
          max: new Date("2024-12-31"),
        },
      };
      const result = buildWhereClause(mockSurvey as TSurvey, filterCriteria);
      expect(result.AND).toContainEqual({
        createdAt: {
          gte: new Date("2024-01-01"),
          lte: new Date("2024-12-31"),
        },
      });
    });

    test("should build where clause with tags", () => {
      const filterCriteria = {
        tags: {
          applied: ["tag1", "tag2"],
          notApplied: ["tag3"],
        },
      };
      const result = buildWhereClause(mockSurvey as TSurvey, filterCriteria);
      expect(result.AND).toHaveLength(1);
    });

    test("should build where clause with contact attributes", () => {
      const filterCriteria = {
        contactAttributes: {
          email: { op: "equals" as const, value: "test@example.com" },
        },
      };
      const result = buildWhereClause(mockSurvey as TSurvey, filterCriteria);
      expect(result.AND).toHaveLength(1);
    });
  });

  describe("buildWhereClause – others & meta filters", () => {
    const baseSurvey: Partial<TSurvey> = {
      id: "s1",
      name: "Survey",
      blocks: [],
      questions: [],
      type: "app",
      hiddenFields: { enabled: false, fieldIds: [] },
      createdAt: new Date(),
      updatedAt: new Date(),
      environmentId: "e1",
      createdBy: "u1",
      status: "inProgress",
    };

    test("others: equals & notEquals", () => {
      const criteria = {
        others: {
          Language: { op: "equals" as const, value: "en" },
          Region: { op: "notEquals" as const, value: "APAC" },
        },
      };
      const result = buildWhereClause(baseSurvey as TSurvey, criteria);
      expect(result.AND).toEqual([
        {
          AND: [{ language: "en" }, { region: { not: "APAC" } }],
        },
      ]);
    });

    test("meta: equals & notEquals map to userAgent paths", () => {
      const criteria = {
        meta: {
          browser: { op: "equals" as const, value: "Chrome" },
          os: { op: "notEquals" as const, value: "Windows" },
        },
      };
      const result = buildWhereClause(baseSurvey as TSurvey, criteria);
      expect(result.AND).toEqual([
        {
          AND: [
            { meta: { path: ["userAgent", "browser"], equals: "Chrome" } },
            { meta: { path: ["userAgent", "os"], not: "Windows" } },
          ],
        },
      ]);
    });

    test("meta: URL string comparison operations", () => {
      const testCases = [
        {
          name: "contains",
          criteria: { meta: { url: { op: "contains" as const, value: "example.com" } } },
          expected: { meta: { path: ["url"], string_contains: "example.com" } },
        },
        {
          name: "doesNotContain",
          criteria: { meta: { url: { op: "doesNotContain" as const, value: "test.com" } } },
          expected: { NOT: { meta: { path: ["url"], string_contains: "test.com" } } },
        },
        {
          name: "startsWith",
          criteria: { meta: { url: { op: "startsWith" as const, value: "https://" } } },
          expected: { meta: { path: ["url"], string_starts_with: "https://" } },
        },
        {
          name: "doesNotStartWith",
          criteria: { meta: { url: { op: "doesNotStartWith" as const, value: "http://" } } },
          expected: { NOT: { meta: { path: ["url"], string_starts_with: "http://" } } },
        },
        {
          name: "endsWith",
          criteria: { meta: { url: { op: "endsWith" as const, value: ".com" } } },
          expected: { meta: { path: ["url"], string_ends_with: ".com" } },
        },
        {
          name: "doesNotEndWith",
          criteria: { meta: { url: { op: "doesNotEndWith" as const, value: ".org" } } },
          expected: { NOT: { meta: { path: ["url"], string_ends_with: ".org" } } },
        },
      ];

      testCases.forEach(({ criteria, expected }) => {
        const result = buildWhereClause(baseSurvey as TSurvey, criteria);
        expect(result.AND).toEqual([{ AND: [expected] }]);
      });
    });
  });

  describe("buildWhereClause – data‐field filter operations", () => {
    const textSurvey: Partial<TSurvey> = {
      id: "s2",
      name: "TextSurvey",
      blocks: [
        {
          id: "block1",
          name: "Block 1",
          elements: [
            {
              id: "qText",
              type: TSurveyElementTypeEnum.OpenText,
              headline: { default: "Text Q" },
              required: false,
              isDraft: false,
              charLimit: {},
              inputType: "text",
            },
            {
              id: "qNum",
              type: TSurveyElementTypeEnum.OpenText,
              headline: { default: "Num Q" },
              required: false,
              isDraft: false,
              charLimit: {},
              inputType: "number",
            },
          ],
        },
      ],
      questions: [],
      type: "app",
      hiddenFields: { enabled: false, fieldIds: [] },
      createdAt: new Date(),
      updatedAt: new Date(),
      environmentId: "e2",
      createdBy: "u2",
      status: "inProgress",
    };

    const ops: Array<[keyof TSurveyElementTypeEnum | string, any, any]> = [
      ["submitted", { op: "submitted" }, { path: ["qText"], not: Prisma.DbNull }],
      ["filledOut", { op: "filledOut" }, { path: ["qText"], not: [] }],
      ["skipped", { op: "skipped" }, "OR"],
      ["equals", { op: "equals", value: "foo" }, { path: ["qText"], equals: "foo" }],
      ["notEquals", { op: "notEquals", value: "bar" }, "NOT"],
      ["lessThan", { op: "lessThan", value: 5 }, { path: ["qNum"], lt: 5 }],
      ["lessEqual", { op: "lessEqual", value: 10 }, { path: ["qNum"], lte: 10 }],
      ["greaterThan", { op: "greaterThan", value: 1 }, { path: ["qNum"], gt: 1 }],
      ["greaterEqual", { op: "greaterEqual", value: 2 }, { path: ["qNum"], gte: 2 }],
      [
        "includesAll",
        { op: "includesAll", value: ["a", "b"] },
        { path: ["qText"], array_contains: ["a", "b"] },
      ],
    ];

    ops.forEach(([name, filter, expected]) => {
      test(name as string, () => {
        const result = buildWhereClause(textSurvey as TSurvey, {
          data: {
            [["submitted", "filledOut", "equals", "includesAll"].includes(name as string) ? "qText" : "qNum"]:
              filter,
          },
        });
        // for OR/NOT cases we just ensure the operator key exists
        if (expected === "OR" || expected === "NOT") {
          expect(JSON.stringify(result)).toMatch(
            new RegExp(name === "skipped" ? `"OR":\\s*\\[` : `"not":"${filter.value}"`)
          );
        } else {
          expect(result.AND).toEqual([
            {
              AND: [{ data: expected }],
            },
          ]);
        }
      });
    });

    test("uploaded & notUploaded", () => {
      const res1 = buildWhereClause(textSurvey as TSurvey, { data: { qText: { op: "uploaded" } } });
      expect(res1.AND).toContainEqual({
        AND: [{ data: { path: ["qText"], not: "skipped" } }],
      });

      const res2 = buildWhereClause(textSurvey as TSurvey, { data: { qText: { op: "notUploaded" } } });
      expect(JSON.stringify(res2)).toMatch(/"equals":"skipped"/);
      expect(JSON.stringify(res2)).toMatch(/"equals":{}/);
    });

    test("clicked, accepted & booked", () => {
      ["clicked", "accepted", "booked"].forEach((status) => {
        const key = status as "clicked" | "accepted" | "booked";
        const res = buildWhereClause(textSurvey as TSurvey, { data: { qText: { op: key } } });
        expect(res.AND).toEqual([{ AND: [{ data: { path: ["qText"], equals: status } }] }]);
      });
    });

    test("matrix", () => {
      const matrixSurvey: Partial<TSurvey> = {
        id: "s3",
        name: "MatrixSurvey",
        blocks: [
          {
            id: "block1",
            name: "Block 1",
            elements: [
              {
                id: "qM",
                type: TSurveyElementTypeEnum.Matrix,
                headline: { default: "Matrix" },
                required: false,
                rows: [{ id: "r1", label: { default: "R1" } }],
                columns: [{ id: "c1", label: { default: "C1" } }],
                shuffleOption: "none",
                isDraft: false,
              },
            ],
          },
        ],
        questions: [],
        type: "app",
        hiddenFields: { enabled: false, fieldIds: [] },
        createdAt: new Date(),
        updatedAt: new Date(),
        environmentId: "e3",
        createdBy: "u3",
        status: "inProgress",
      };
      const res = buildWhereClause(matrixSurvey as TSurvey, {
        data: { qM: { op: "matrix", value: { R1: "foo" } } },
      });
      expect(res.AND).toEqual([
        {
          AND: [
            {
              data: { path: ["qM", "R1"], equals: "foo" },
            },
          ],
        },
      ]);
    });
  });

  describe("getResponsesFileName", () => {
    test("should generate correct filename", () => {
      const surveyName = "Test Survey";
      const extension = "csv";
      const result = getResponsesFileName(surveyName, extension);
      expect(result).toContain("export-test_survey-");
    });
  });

  describe("extracMetadataKeys", () => {
    test("should extract metadata keys correctly", () => {
      const meta = {
        userAgent: { browser: "Chrome", os: "Windows", device: "Desktop" },
        country: "US",
        source: "direct",
      };
      const result = extracMetadataKeys(meta);
      expect(result).toContain("userAgent - browser");
      expect(result).toContain("userAgent - os");
      expect(result).toContain("userAgent - device");
      expect(result).toContain("country");
      expect(result).toContain("source");
    });

    test("should handle empty metadata", () => {
      const result = extracMetadataKeys({});
      expect(result).toEqual([]);
    });
  });

  // TODO: Fix this test after the survey editor poc is merged
  describe("extractSurveyDetails", () => {
    const mockSurvey: Partial<TSurvey> = {
      id: "survey1",
      name: "Test Survey",
      blocks: [
        {
          id: "block1",
          name: "Block 1",
          elements: [
            {
              id: "q1",
              type: TSurveyElementTypeEnum.MultipleChoiceSingle,
              headline: { default: "Question 1" },
              required: true,
              choices: [
                { id: "1", label: { default: "Option 1" } },
                { id: "2", label: { default: "Option 2" } },
              ],
              shuffleOption: "none",
              isDraft: false,
            },
            {
              id: "q2",
              type: TSurveyElementTypeEnum.Matrix,
              headline: { default: "Matrix Question" },
              required: true,
              rows: [
                { id: "r1", label: { default: "Row 1" } },
                { id: "r2", label: { default: "Row 2" } },
              ],
              columns: [
                { id: "c1", label: { default: "Column 1" } },
                { id: "c2", label: { default: "Column 2" } },
              ],
              shuffleOption: "none",
              isDraft: false,
            },
          ],
        },
      ],
      questions: [],
      type: "app",
      hiddenFields: { enabled: true, fieldIds: ["hidden1"] },
      createdAt: new Date(),
      updatedAt: new Date(),
      environmentId: "env1",
      createdBy: "user1",
      status: "draft",
    };

    const mockResponses: Partial<TResponse>[] = [
      {
        id: "response1",
        surveyId: "survey1",
        data: {},
        meta: { userAgent: { browser: "Chrome" } },
        contactAttributes: { email: "test@example.com" },
        finished: true,
        createdAt: new Date(),
        updatedAt: new Date(),
        tags: [],
      },
    ];

    test("should extract survey details correctly", () => {
      const result = extractSurveyDetails(mockSurvey as TSurvey, mockResponses as TResponse[]);
      expect(result.metaDataFields).toContain("userAgent - browser");
      expect(result.elements).toHaveLength(2); // 1 regular question + 2 matrix rows
      expect(result.hiddenFields).toContain("hidden1");
      expect(result.userAttributes).toContain("email");
    });
  });

  describe("getResponsesJson", () => {
    const mockSurvey: Partial<TSurvey> = {
      id: "survey1",
      name: "Test Survey",
      blocks: [
        {
          id: "block1",
          name: "Block 1",
          elements: [
            {
              id: "q1",
              type: TSurveyElementTypeEnum.MultipleChoiceSingle,
              headline: { default: "Question 1" },
              required: true,
              choices: [
                { id: "1", label: { default: "Option 1" } },
                { id: "2", label: { default: "Option 2" } },
              ],
              shuffleOption: "none",
              isDraft: false,
            },
          ],
        },
      ],
      questions: [],
      type: "app",
      hiddenFields: { enabled: true, fieldIds: [] },
      createdAt: new Date(),
      updatedAt: new Date(),
      environmentId: "env1",
      createdBy: "user1",
      status: "draft",
    };

    const mockResponses: Partial<TResponse>[] = [
      {
        id: "response1",
        surveyId: "survey1",
        data: { q1: "answer1" },
        meta: { userAgent: { browser: "Chrome" } },
        contactAttributes: { email: "test@example.com" },
        finished: true,
        createdAt: new Date(),
        updatedAt: new Date(),
        tags: [],
      },
    ];

    test("should generate correct JSON data", () => {
      const questionsHeadlines = [["1. Question 1"]];
      const userAttributes = ["email"];
      const hiddenFields: string[] = [];
      const result = getResponsesJson(
        mockSurvey as TSurvey,
        mockResponses as TResponse[],
        questionsHeadlines,
        userAttributes,
        hiddenFields,
        false
      );
      expect(result[0]["Response ID"]).toBe("response1");
      expect(result[0]["userAgent - browser"]).toBe("Chrome");
      expect(result[0]["1. Question 1"]).toBe("answer1");
      expect(result[0]["email"]).toBe("test@example.com");
    });
  });

  describe("getResponseContactAttributes", () => {
    test("should extract contact attributes correctly", () => {
      const responses = [
        {
          contactAttributes: { email: "test1@example.com", name: "Test 1" },
          data: {},
          meta: {},
        },
        {
          contactAttributes: { email: "test2@example.com", name: "Test 2" },
          data: {},
          meta: {},
        },
      ];
      const result = getResponseContactAttributes(
        responses as Pick<TResponse, "contactAttributes" | "data" | "meta">[]
      );
      expect(result.email).toContain("test1@example.com");
      expect(result.email).toContain("test2@example.com");
      expect(result.name).toContain("Test 1");
      expect(result.name).toContain("Test 2");
    });

    test("should handle empty responses", () => {
      const result = getResponseContactAttributes([]);
      expect(result).toEqual({});
    });
  });

  describe("getResponseMeta", () => {
    test("should extract meta data correctly", () => {
      const responses = [
        {
          contactAttributes: {},
          data: {},
          meta: {
            userAgent: { browser: "Chrome", os: "Windows" },
            country: "US",
          },
        },
        {
          contactAttributes: {},
          data: {},
          meta: {
            userAgent: { browser: "Firefox", os: "MacOS" },
            country: "UK",
          },
        },
      ];
      const result = getResponseMeta(responses as Pick<TResponse, "contactAttributes" | "data" | "meta">[]);
      expect(result.browser).toContain("Chrome");
      expect(result.browser).toContain("Firefox");
      expect(result.os).toContain("Windows");
      expect(result.os).toContain("MacOS");
    });

    test("should extract URL data correctly", () => {
      const responses = [
        {
          contactAttributes: {},
          data: {},
          meta: {
            url: "https://example.com/page1",
            source: "direct",
          },
        },
        {
          contactAttributes: {},
          data: {},
          meta: {
            url: "https://test.com/page2?param=value",
            source: "google",
          },
        },
      ];
      const result = getResponseMeta(responses as Pick<TResponse, "contactAttributes" | "data" | "meta">[]);
      expect(result.url).toEqual([]);
      expect(result.source).toContain("direct");
      expect(result.source).toContain("google");
    });

    test("should handle mixed meta data with URLs", () => {
      const responses = [
        {
          contactAttributes: {},
          data: {},
          meta: {
            userAgent: { browser: "Chrome", device: "desktop" },
            url: "https://formbricks.com/dashboard",
            country: "US",
          },
        },
        {
          contactAttributes: {},
          data: {},
          meta: {
            userAgent: { browser: "Safari", device: "mobile" },
            url: "https://formbricks.com/surveys/123",
            country: "UK",
          },
        },
      ];
      const result = getResponseMeta(responses as Pick<TResponse, "contactAttributes" | "data" | "meta">[]);
      expect(result.browser).toContain("Chrome");
      expect(result.browser).toContain("Safari");
      expect(result.device).toContain("desktop");
      expect(result.device).toContain("mobile");
      expect(result.url).toEqual([]);
      expect(result.country).toContain("US");
      expect(result.country).toContain("UK");
    });

    test("should handle empty responses", () => {
      const result = getResponseMeta([]);
      expect(result).toEqual({});
    });

    test("should ignore empty or null URL values", () => {
      const responses = [
        {
          contactAttributes: {},
          data: {},
          meta: {
            url: "",
            source: "direct",
          },
        },
        {
          contactAttributes: {},
          data: {},
          meta: {
            url: null as any,
            source: "newsletter",
          },
        },
        {
          contactAttributes: {},
          data: {},
          meta: {
            url: "https://valid.com",
            source: "google",
          },
        },
      ];
      const result = getResponseMeta(responses as Pick<TResponse, "contactAttributes" | "data" | "meta">[]);
      expect(result.url).toEqual([]);
      expect(result.source).toEqual(expect.arrayContaining(["direct", "newsletter", "google"]));
    });
  });

  describe("getResponseHiddenFields", () => {
    const mockSurvey: Partial<TSurvey> = {
      id: "survey1",
      name: "Test Survey",
      questions: [],
      type: "app",
      hiddenFields: { enabled: true, fieldIds: ["hidden1", "hidden2"] },
      createdAt: new Date(),
      updatedAt: new Date(),
      environmentId: "env1",
      createdBy: "user1",
      status: "draft",
    };

    test("should extract hidden fields correctly", () => {
      const responses = [
        {
          contactAttributes: {},
          data: { hidden1: "value1", hidden2: "value2" },
          meta: {},
        },
        {
          contactAttributes: {},
          data: { hidden1: "value3", hidden2: "value4" },
          meta: {},
        },
      ];
      const result = getResponseHiddenFields(
        mockSurvey as TSurvey,
        responses as Pick<TResponse, "contactAttributes" | "data" | "meta">[]
      );
      expect(result.hidden1).toContain("value1");
      expect(result.hidden1).toContain("value3");
      expect(result.hidden2).toContain("value2");
      expect(result.hidden2).toContain("value4");
    });

    test("should handle empty responses", () => {
      const result = getResponseHiddenFields(mockSurvey as TSurvey, []);
      expect(result).toEqual({
        hidden1: [],
        hidden2: [],
      });
    });
  });

  describe("generateAllPermutationsOfSubsets", () => {
    test("with empty array returns empty", () => {
      expect(generateAllPermutationsOfSubsets([])).toEqual([]);
    });

    test("with two elements returns 4 permutations", () => {
      const out = generateAllPermutationsOfSubsets(["x", "y"]);
      expect(out).toEqual(expect.arrayContaining([["x"], ["y"], ["x", "y"], ["y", "x"]]));
      expect(out).toHaveLength(4);
    });
  });
});

describe("extractChoiceIdsFromResponse", () => {
  const multipleChoiceMultiQuestion = {
    id: "multi-choice-id",
    type: TSurveyElementTypeEnum.MultipleChoiceMulti as typeof TSurveyElementTypeEnum.MultipleChoiceMulti,
    headline: { default: "Select multiple options" },
    required: false,
    choices: [
      {
        id: "choice-1",
        label: { default: "Option 1", es: "Opción 1" },
      },
      {
        id: "choice-2",
        label: { default: "Option 2", es: "Opción 2" },
      },
      {
        id: "choice-3",
        label: { default: "Option 3", es: "Opción 3" },
      },
    ],
    shuffleOption: "none" as const,
  };

  const multipleChoiceSingleQuestion = {
    id: "single-choice-id",
    type: TSurveyElementTypeEnum.MultipleChoiceSingle as typeof TSurveyElementTypeEnum.MultipleChoiceSingle,
    headline: { default: "Select one option" },
    required: false,
    choices: [
      {
        id: "choice-a",
        label: { default: "Choice A", fr: "Choix A" },
      },
      {
        id: "choice-b",
        label: { default: "Choice B", fr: "Choix B" },
      },
    ],
    shuffleOption: "none" as const,
  };

  const textQuestion = {
    id: "text-id",
    type: TSurveyElementTypeEnum.OpenText as typeof TSurveyElementTypeEnum.OpenText,
    headline: { default: "What do you think?" },
    required: false,
    inputType: "text" as const,
    charLimit: { enabled: false, min: 0, max: 0 },
  };

  describe("multipleChoiceMulti questions", () => {
    test("should extract choice IDs from array response with default language", () => {
      const responseValue = ["Option 1", "Option 3"];
      const result = extractChoiceIdsFromResponse(responseValue, multipleChoiceMultiQuestion, "default");

      expect(result).toEqual(["choice-1", "choice-3"]);
    });

    test("should extract choice IDs from array response with specific language", () => {
      const responseValue = ["Opción 1", "Opción 2"];
      const result = extractChoiceIdsFromResponse(responseValue, multipleChoiceMultiQuestion, "es");

      expect(result).toEqual(["choice-1", "choice-2"]);
    });

    test("should fall back to checking all language values when exact language match fails", () => {
      const responseValue = ["Opción 1", "Option 2"];
      const result = extractChoiceIdsFromResponse(responseValue, multipleChoiceMultiQuestion, "default");

      expect(result).toEqual(["choice-1", "choice-2"]);
    });

    test("should render other option when non-matching choice is selected", () => {
      const responseValue = ["Option 1", "Non-existent option", "Option 3"];
      const result = extractChoiceIdsFromResponse(responseValue, multipleChoiceMultiQuestion, "default");

      expect(result).toEqual(["choice-1", "other", "choice-3"]);
    });

    test("should return empty array for empty response", () => {
      const responseValue: string[] = [];
      const result = extractChoiceIdsFromResponse(responseValue, multipleChoiceMultiQuestion, "default");

      expect(result).toEqual([]);
    });
  });

  describe("multipleChoiceSingle questions", () => {
    test("should extract choice ID from string response with default language", () => {
      const responseValue = "Choice A";
      const result = extractChoiceIdsFromResponse(responseValue, multipleChoiceSingleQuestion, "default");

      expect(result).toEqual(["choice-a"]);
    });

    test("should extract choice ID from string response with specific language", () => {
      const responseValue = "Choix B";
      const result = extractChoiceIdsFromResponse(responseValue, multipleChoiceSingleQuestion, "fr");

      expect(result).toEqual(["choice-b"]);
    });

    test("should fall back to checking all language values for single choice", () => {
      const responseValue = "Choix A";
      const result = extractChoiceIdsFromResponse(responseValue, multipleChoiceSingleQuestion, "default");

      expect(result).toEqual(["choice-a"]);
    });

    test("should return empty array for empty string response", () => {
      const responseValue = "";
      const result = extractChoiceIdsFromResponse(responseValue, multipleChoiceSingleQuestion, "default");

      expect(result).toEqual([]);
    });
  });

  describe("edge cases", () => {
    test("should return empty array for non-multiple choice questions", () => {
      const responseValue = "Some text response";
      const result = extractChoiceIdsFromResponse(responseValue, textQuestion, "default");

      expect(result).toEqual([]);
    });

    test("should handle missing language parameter by defaulting to 'default'", () => {
      const responseValue = "Option 1";
      const result = extractChoiceIdsFromResponse(responseValue, multipleChoiceMultiQuestion);

      expect(result).toEqual(["choice-1"]);
    });

    test("should handle numeric or other types by returning empty array", () => {
      const responseValue = 123;
      const result = extractChoiceIdsFromResponse(responseValue, multipleChoiceMultiQuestion, "default");

      expect(result).toEqual([]);
    });

    test("should handle object responses by returning empty array", () => {
      const responseValue = { invalid: "object" };
      const result = extractChoiceIdsFromResponse(responseValue, multipleChoiceMultiQuestion, "default");

      expect(result).toEqual([]);
    });
  });

  describe("language handling", () => {
    test("should use provided language parameter", () => {
      const responseValue = ["Opción 1"];
      const result = extractChoiceIdsFromResponse(responseValue, multipleChoiceMultiQuestion, "es");

      expect(result).toEqual(["choice-1"]);
    });

    test("should handle null language parameter by defaulting to 'default'", () => {
      const responseValue = ["Option 1"];
      const result = extractChoiceIdsFromResponse(responseValue, multipleChoiceMultiQuestion, null as any);

      expect(result).toEqual(["choice-1"]);
    });

    test("should handle undefined language parameter by defaulting to 'default'", () => {
      const responseValue = ["Option 1"];
      const result = extractChoiceIdsFromResponse(
        responseValue,
        multipleChoiceMultiQuestion,
        undefined as any
      );

      expect(result).toEqual(["choice-1"]);
    });
  });
});
