import { createWriteStream, existsSync, mkdirSync } from "fs";
import sharp from "sharp";
import fs from "fs/promises";
import { pipeline } from "stream";
import { promisify } from "util";
const streamPipeline = promisify(pipeline);
const apiUrl = "https://admin.ceiba-conseil.com";

async function fetchJSONApi(path) {
  const url = `${apiUrl}${path}`;
  const options = {
    method: "GET",
    headers: {
      "content-type": "application/json",
    },
  };
  console.log(`fetchJSONApi: ${url}`);
  const response = await fetch(url, options);

  if (!response.ok) {
    const errors = await response.json();
    throw errors.errors[0].message;
  }

  return response.json();
}

async function fetchAsset(uuid) {
  const url = `${apiUrl}/assets/${uuid}`;
  return fetch(url);
}

async function fetchScoresData() {
  const fields = [
    "*",
    "translations.*",
    "questions.sort",
    "questions.questions_id.*",
    "questions.questions_id.translations.*",
    "questions.questions_id.answers.*",
    "questions.questions_id.answers.answers_id.*",
    "questions.questions_id.answers.answers_id.translations.*",
    "results.*",
    "results.results_id.*",
    "results.results_id.translations.*",
  ];
  const url = `/items/scores?${fields
    .map((item) => `fields[]=${item}`)
    .join("&")}`;
  const scores = (await fetchJSONApi(url)).data;
  await fs.writeFile("./src/data.json", JSON.stringify(scores), "utf8");

  const folder = "public/answers";
  if (!existsSync(folder)) mkdirSync(folder);
  for (const score of scores) {
    const uuid_score = score.image;
    if (uuid_score) {
      console.log(`Score image : ${folder}/${uuid_score}`);
      const response = await fetchAsset(uuid_score);
      try {
        const thumbnail = sharp().resize({ height: 200 }).webp();
        await streamPipeline(
          response.body,
          thumbnail,
          createWriteStream(`${folder}/${uuid_score}.webp`)
        );
      } catch (err) {
        console.log(err);
      }
    }
    for (const question of score.questions) {
      for (const answer of question.questions_id.answers) {
        const uuid = answer.answers_id.image;
        if (uuid) {
          await downloadImage(uuid, `${folder}/${uuid}.webp`, { height: 200 });
        }
      }
    }
  }

  // await sharp('src/assets/arbre.png').resize({ width: 440, height: 690 }).webp().toFile('public/arbre.webp')
}

async function transformImage(response, path, options, format = "webp") {
  try {
    let thumbnail;
    console.log(path);
    if (format == "webp") {
      thumbnail = sharp().resize(options).webp();
    } else {
      thumbnail = sharp().resize(options).toFormat("png");
    }
    const stream = createWriteStream(path);
    await streamPipeline(response.body, thumbnail, stream);
    await stream;
  } catch (err) {
    console.log(err);
  }
}

async function downloadImage(uuid, path, options, format = "webp") {
  const response = await fetchAsset(uuid);
  await transformImage(response, path, options, format);
}

async function fetchHomepageData() {
  const fields = ["*"];
  const url = `/items/homepage?${fields
    .map((item) => `fields[]=${item}`)
    .join("&")}`;
  const homepage = (await fetchJSONApi(url)).data;

  await downloadImage(homepage.image, `public/homepage.webp`, {
    width: 1280,
    height: 720,
    fit: sharp.fit.cover,
  });

  const favicons = [
    {
      path: `public/favicon/android-icon-192x192.png`,
      options: {
        width: 192,
        height: 192,
        fit: sharp.fit.contain,
        background: { r: 255, g: 255, b: 255, alpha: 0 },
      },
      format: "png",
    },
    {
      path: `public/favicon/apple-icon-57x57.png`,
      options: {
        width: 57,
        height: 57,
        fit: sharp.fit.contain,
        background: { r: 255, g: 255, b: 255, alpha: 0 },
      },
      format: "png",
    },
    {
      path: `public/favicon/apple-icon-60x60.png`,
      options: {
        width: 60,
        height: 60,
        fit: sharp.fit.contain,
        background: { r: 255, g: 255, b: 255, alpha: 0 },
      },
      format: "png",
    },
    {
      path: `public/favicon/apple-icon-72x72.png`,
      options: {
        width: 72,
        height: 72,
        fit: sharp.fit.contain,
        background: { r: 255, g: 255, b: 255, alpha: 0 },
      },
      format: "png",
    },
    {
      path: `public/favicon/apple-icon-76x76.png`,
      options: {
        width: 76,
        height: 76,
        fit: sharp.fit.contain,
        background: { r: 255, g: 255, b: 255, alpha: 0 },
      },
      format: "png",
    },
    {
      path: `public/favicon/apple-icon-114x114.png`,
      options: {
        width: 114,
        height: 114,
        fit: sharp.fit.contain,
        background: { r: 255, g: 255, b: 255, alpha: 0 },
      },
      format: "png",
    },
    {
      path: `public/favicon/apple-icon-120x120.png`,
      options: {
        width: 120,
        height: 120,
        fit: sharp.fit.contain,
        background: { r: 255, g: 255, b: 255, alpha: 0 },
      },
      format: "png",
    },
    {
      path: `public/favicon/apple-icon-144x144.png`,
      options: {
        width: 144,
        height: 144,
        fit: sharp.fit.contain,
        background: { r: 255, g: 255, b: 255, alpha: 0 },
      },
      format: "png",
    },
    {
      path: `public/favicon/apple-icon-152x152.png`,
      options: {
        width: 152,
        height: 152,
        fit: sharp.fit.contain,
        background: { r: 255, g: 255, b: 255, alpha: 0 },
      },
      format: "png",
    },
    {
      path: `public/favicon/apple-icon-180x180.png`,
      options: {
        width: 180,
        height: 180,
        fit: sharp.fit.contain,
        background: { r: 255, g: 255, b: 255, alpha: 0 },
      },
      format: "png",
    },
    {
      path: `public/favicon/favicon-16x16.png`,
      options: {
        width: 16,
        height: 16,
        fit: sharp.fit.contain,
        background: { r: 255, g: 255, b: 255, alpha: 0 },
      },
      format: "png",
    },
    {
      path: `public/favicon/favicon-32x32.png`,
      options: {
        width: 32,
        height: 32,
        fit: sharp.fit.contain,
        background: { r: 255, g: 255, b: 255, alpha: 0 },
      },
      format: "png",
    },
    {
      path: `public/favicon/favicon-96x96.png`,
      options: {
        width: 96,
        height: 96,
        fit: sharp.fit.contain,
        background: { r: 255, g: 255, b: 255, alpha: 0 },
      },
      format: "png",
    },
    {
      path: `public/favicon/favicon-256x256.png`,
      options: {
        width: 256,
        height: 256,
        fit: sharp.fit.contain,
        background: { r: 255, g: 255, b: 255, alpha: 0 },
      },
      format: "png",
    },
    {
      path: `public/favicon/ms-icon-70x70.png`,
      options: {
        width: 70,
        height: 70,
        fit: sharp.fit.contain,
        background: { r: 255, g: 255, b: 255, alpha: 0 },
      },
      format: "png",
    },
    {
      path: `public/favicon/ms-icon-144x144.png`,
      options: {
        width: 144,
        height: 144,
        fit: sharp.fit.contain,
        background: { r: 255, g: 255, b: 255, alpha: 0 },
      },
      format: "png",
    },
    {
      path: `public/favicon/ms-icon-150x150.png`,
      options: {
        width: 150,
        height: 150,
        fit: sharp.fit.contain,
        background: { r: 255, g: 255, b: 255, alpha: 0 },
      },
      format: "png",
    },
    {
      path: `public/favicon/ms-icon-310x310.png`,
      options: {
        width: 310,
        height: 310,
        fit: sharp.fit.contain,
        background: { r: 255, g: 255, b: 255, alpha: 0 },
      },
      format: "png",
    },
  ];
  for (const favicon of favicons) {
    downloadImage(homepage.logo, favicon.path, favicon.options, favicon.format);
  }
}

async function fetchData() {
  await fetchHomepageData();
  await fetchScoresData();
}

fetchData();