// Rôle : lance les validations structurelles des données publiques du site.
import { readFile } from "node:fs/promises";
import { test } from "node:test";
import assert from "node:assert/strict";
import {
  validateDiablo4Affixes,
  validateEndemicData,
  validateLibraryData,
  validateMonsterData,
  validateSiteContent,
  validateTranslationKeys
} from "./helpers/data-validation.mjs";

test("site content json is complete", async () => {
  const site = JSON.parse(await readFile("website/public/data/site.json", "utf8"));
  validateSiteContent(site);
});

test("library examples are available", async () => {
  const library = JSON.parse(await readFile("website/public/data/library.json", "utf8"));
  validateLibraryData(library);
});

test("mhwilds data and assets are available", async () => {
  const site = JSON.parse(await readFile("website/public/data/site.json", "utf8"));
  const games = JSON.parse(await readFile("website/public/data/games.json", "utf8"));
  const monsters = JSON.parse(await readFile("website/public/data/mhwilds/monsters.json", "utf8"));
  const endemicLife = JSON.parse(await readFile("website/public/data/mhwilds/endemic_life.json", "utf8"));
  const listIndex = JSON.parse(await readFile("website/public/data/mhwilds/lists/index.json", "utf8"));
  const translations = JSON.parse(await readFile("website/public/data/mhwilds/i18n/fr.json", "utf8"));
  const enTranslations = JSON.parse(await readFile("website/public/data/mhwilds/i18n/en.json", "utf8"));
  const listingSource = await readFile("website/src/features/games/mhwilds/MhwildsListing.jsx", "utf8");

  assert.equal(site.brand.name, "Sokko G");
  assert.equal(site.home.hero.title, "Sokko G");
  assert.equal(site.gamesPage.title, "Jeux disponibles");
  assert.match(site.toolboxes.summary, /espaces modulaires/);
  assert.ok(site.toolboxes.storageHelp.items.length >= 3);
  assert.equal(games.games[0].id, "mhwilds");
  assert.equal(games.games[0].eyebrow, "Guide de jeu");
  assert.match(games.games[0].images.cardCover, /games\/mhwilds\/card-cover\.png/);
  assert.match(games.games[0].images.heroBg, /games\/mhwilds\/hero-bg\.png/);
  assert.ok(monsters.monsters.length > 0);
  assert.deepEqual(monsters.elements, ["fire", "water", "thunder", "ice", "dragon"]);
  validateMonsterData(monsters.monsters);
  assert.ok(Array.isArray(endemicLife.locations), "endemicLife.locations must be an array");
  assert.ok(endemicLife.locations.length > 0, "endemicLife.locations must not be empty");
  assert.ok(endemicLife.endemicLife.length > 0);
  validateEndemicData(endemicLife);
  assert.ok(Array.isArray(listIndex.lists), "mhwilds list index must expose lists");
  assert.ok(listIndex.lists.length >= 1, "mhwilds list index must contain at least one list");
  for (const list of listIndex.lists) {
    assert.equal(typeof list.id, "string", "mhwilds list id must be a string");
    assert.equal(typeof list.title, "string", "mhwilds list title must be a string");
    assert.match(list.file, /\.json$/, "mhwilds list file must target a json file");
    const listData = JSON.parse(await readFile(`website/public/data/mhwilds/lists/${list.file}`, "utf8"));
    assert.equal(typeof listData.titre, "string", `${list.file}.titre must be a string`);
    assert.ok(listData.titre.trim(), `${list.file}.titre must not be empty`);
    for (const [category, items] of Object.entries(listData).filter(([key]) => key !== "titre")) {
      assert.ok(Array.isArray(items), `mhwilds list category ${category} must be an array`);
      items.forEach((item, index) => {
        assert.equal(typeof item.nom, "string", `${list.file}.${category}[${index}].nom must be a string`);
        assert.ok(item.nom.trim(), `${list.file}.${category}[${index}].nom must not be empty`);
        if (item.description !== undefined) {
          assert.equal(typeof item.description, "string", `${list.file}.${category}[${index}].description must be a string`);
        }
        if (item.quantite !== undefined) {
          assert.ok(Number.isFinite(Number(item.quantite)), `${list.file}.${category}[${index}].quantite must be numeric`);
        }
      });
    }
  }
  validateTranslationKeys(translations, "fr");
  validateTranslationKeys(enTranslations, "en");
  assert.equal(translations.monsters, "monstres");
  assert.equal(translations.dark_hornet, "frelon clair-obscur");
  assert.equal(translations["dark hornet"], undefined);
  assert.match(listingSource, /function MhwildsListing/);
  const monsterCardSource = await readFile("website/src/features/games/mhwilds/cards/MonsterCard.jsx", "utf8");
  assert.match(monsterCardSource, /monster-card/);
  assert.match(monsterCardSource, /monster\.hitzones/);
  await readFile("website/public/static/img/mhwilds/chatacabra.png");
  await readFile("website/public/static/img/games/mhwilds/card-cover.png");
  await readFile("website/public/static/img/games/mhwilds/hero-bg.png");
});

test("diablo4 data and route are available", async () => {
  const games = JSON.parse(await readFile("website/public/data/games.json", "utf8"));
  const affixes = JSON.parse(await readFile("website/public/data/diablo4/affixes_types.json", "utf8"));
  const routeSource = await readFile("website/src/features/games/GameRoute.jsx", "utf8");
  const pageSource = await readFile("website/src/features/games/diablo4/Diablo4Page.jsx", "utf8");
  const listingSource = await readFile("website/src/features/games/diablo4/Diablo4Listing.jsx", "utf8");
  const diablo4Game = games.games.find((game) => game.id === "diablo4");

  assert.ok(diablo4Game, "games.json must declare diablo4");
  assert.match(diablo4Game.images.cardCover, /games\/diablo4\/card-cover\.png/);
  assert.match(diablo4Game.images.heroBg, /games\/diablo4\/hero-bg\.png/);
  validateDiablo4Affixes(affixes);
  assert.match(routeSource, /game\.id === "diablo4"/);
  assert.match(pageSource, /category === "affixes"/);
  assert.match(listingSource, /diablo4\.filterOptions\.affixes/);
  await readFile("website/public/static/img/games/diablo4/card-cover.png");
  await readFile("website/public/static/img/games/diablo4/hero-bg.png");
  await readFile("website/public/static/img/diablo4/axe.svg");
  await readFile("website/public/static/img/diablo4/cube.svg");
  await readFile("website/public/static/img/diablo4/fire.svg");
  await readFile("website/public/static/img/diablo4/shield.svg");
  await readFile("website/public/static/img/diablo4/wing.svg");
});
