import { describe, it, expect } from "vitest";
import {
  parseLevelPayload,
  parseJsonArray,
  parseJsonNumberArray,
} from "../parsers.js";

describe("parsers", () => {
  // ────────────── parseLevelPayload ──────────────

  describe("parseLevelPayload", () => {
    it("retourne null si payload est null", () => {
      expect(parseLevelPayload(null)).toBeNull();
    });

    it("retourne null si payload est undefined", () => {
      expect(parseLevelPayload(undefined)).toBeNull();
    });

    it("retourne null si payload est une chaîne vide", () => {
      expect(parseLevelPayload("")).toBeNull();
    });

    it("retourne null si payload est 0", () => {
      expect(parseLevelPayload(0)).toBeNull();
    });

    it("parse une chaîne JSON valide", () => {
      const result = parseLevelPayload('{"id": 1, "name": "test"}');
      expect(result).toEqual({ id: 1, name: "test" });
    });

    it("retourne null pour une chaîne JSON invalide", () => {
      expect(parseLevelPayload("{invalid json}")).toBeNull();
    });

    it("retourne l'objet tel quel s'il n'est pas une chaîne", () => {
      const obj = { id: 1, tiles: [[]] };
      expect(parseLevelPayload(obj)).toBe(obj);
    });

    it("retourne un tableau tel quel", () => {
      const arr = [1, 2, 3];
      expect(parseLevelPayload(arr)).toBe(arr);
    });

    it("parse un tableau JSON string", () => {
      expect(parseLevelPayload("[1,2,3]")).toEqual([1, 2, 3]);
    });
  });

  // ────────────── parseJsonArray ──────────────

  describe("parseJsonArray", () => {
    it("retourne un tableau de strings filtré depuis un tableau", () => {
      expect(parseJsonArray(["a", "b", 123, null])).toEqual(["a", "b"]);
    });

    it("retourne un tableau vide pour un tableau vide", () => {
      expect(parseJsonArray([])).toEqual([]);
    });

    it("parse une chaîne JSON contenant un tableau de strings", () => {
      expect(parseJsonArray('["hello","world"]')).toEqual(["hello", "world"]);
    });

    it("filtre les non-strings depuis un JSON", () => {
      expect(parseJsonArray('["a", 1, true, "b"]')).toEqual(["a", "b"]);
    });

    it("retourne un tableau vide pour un JSON non-tableau", () => {
      expect(parseJsonArray('{"key": "value"}')).toEqual([]);
    });

    it("retourne un tableau vide pour une chaîne JSON invalide", () => {
      expect(parseJsonArray("{broken")).toEqual([]);
    });

    it("retourne un tableau vide pour null", () => {
      expect(parseJsonArray(null)).toEqual([]);
    });

    it("retourne un tableau vide pour undefined", () => {
      expect(parseJsonArray(undefined)).toEqual([]);
    });

    it("retourne un tableau vide pour un nombre", () => {
      expect(parseJsonArray(42)).toEqual([]);
    });

    it("retourne un tableau vide pour une chaîne vide", () => {
      expect(parseJsonArray("")).toEqual([]);
    });
  });

  // ────────────── parseJsonNumberArray ──────────────

  describe("parseJsonNumberArray", () => {
    it("retourne un tableau de nombres filtré depuis un tableau", () => {
      expect(parseJsonNumberArray([1, 2, 3, "a", null])).toEqual([1, 2, 3]);
    });

    it("retourne un tableau vide pour un tableau vide", () => {
      expect(parseJsonNumberArray([])).toEqual([]);
    });

    it("parse une chaîne JSON contenant des nombres", () => {
      expect(parseJsonNumberArray("[1,2,3]")).toEqual([1, 2, 3]);
    });

    it("convertit les strings numériques depuis un JSON", () => {
      expect(parseJsonNumberArray('["1","2","3"]')).toEqual([1, 2, 3]);
    });

    it("exclut les NaN", () => {
      expect(parseJsonNumberArray('["abc","1"]')).toEqual([1]);
    });

    it("retourne un tableau vide pour null", () => {
      expect(parseJsonNumberArray(null)).toEqual([]);
    });

    it("retourne un tableau vide pour undefined", () => {
      expect(parseJsonNumberArray(undefined)).toEqual([]);
    });

    it("retourne un tableau vide pour un JSON non-tableau", () => {
      expect(parseJsonNumberArray('"hello"')).toEqual([]);
    });

    it("retourne un tableau vide pour une chaîne vide", () => {
      expect(parseJsonNumberArray("")).toEqual([]);
    });

    it("retourne un tableau vide pour une chaîne JSON invalide", () => {
      expect(parseJsonNumberArray("not json")).toEqual([]);
    });

    it("gère un mélange de nombres et strings numériques", () => {
      expect(parseJsonNumberArray('[1, "2", 3, "4.5"]')).toEqual([
        1, 2, 3, 4.5,
      ]);
    });
  });
});
