import {Jsona} from "jsona";
import {DrupalJsonApiParams} from "drupal-jsonapi-params";
import type {TJsonApiBody} from "jsona/lib/JsonaTypes";
import type { NavigationMenuItem } from '@nuxt/ui'


function resolve_baseURL(): string {
    // Check if the Drupal base URL is set in the environment variables.
    if (!import.meta.env.PUBLIC_DRUPAL_BASE_URL) {
        console.warn("[fetchNodeArticle] Set DRUPAL_BASE_URL in your .env (e.g. https://project.ddev.site)");
        throw new Error("DRUPAL_BASE_URL is not set in your .env");
    }
    // Check if the component is running on the client side.
    const is_client_side_component = (typeof globalThis !== "undefined" && "location" in globalThis);
    // If the component is running on the client side and in development mode, use the Vite proxy.
    if (import.meta.env.DEV && is_client_side_component) {return "/__drupal";}
    // Otherwise, use the Drupal base URL.
    else {return import.meta.env.DRUPAL_BASE_URL;}
}


export const fetchNodeArticle = async () => {
    const baseURL = resolve_baseURL();

    // Generate the JSON:API Query. Get all title and body from published articles.
    const params: DrupalJsonApiParams = new DrupalJsonApiParams();
    params.addFields("node--article", ["title","body",]).addFilter("status", "1");
    const path: string = params.getQueryString();
    const url: string = `${baseURL}/jsonapi/node/article?${path}`;

    // Get the articles from the Drupal JSON API
    const request = await fetch(url);
    if (!request.ok) {throw new Error(`JSON:API request failed: ${request.status} ${request.statusText}`,);}
    const json: string | TJsonApiBody = await request.json();

    // Initiate Jsona.
    const dataFormatter: Jsona = new Jsona();
    // Deserialise the response.
    const articles = dataFormatter.deserialize(json);

    return articles;
}


export const fetchNodeArticleInRange = async (from: number, to: number) => {
    if (!Number.isInteger(from) || !Number.isInteger(to) || from < 1 || to < from) {
        throw new Error("Invalid range: `from` and `to` must be integers with from >= 1 and to >= from.");
    }

    const baseURL = resolve_baseURL();
    const offset = from - 1;
    const limit = (to - from) + 1;

    // Generate the JSON:API Query for published articles within a range.
    const params: DrupalJsonApiParams = new DrupalJsonApiParams();
    params.addFields("node--article", ["title","body",]).addFilter("status", "1");
    const path: string = params.getQueryString();
    const url: string = `${baseURL}/jsonapi/node/article?${path}&page[offset]=${offset}&page[limit]=${limit}`;

    // Get the articles from the Drupal JSON API
    const request = await fetch(url);
    if (!request.ok) {throw new Error(`JSON:API request failed: ${request.status} ${request.statusText}`,);}
    const json: string | TJsonApiBody = await request.json();

    // Initiate Jsona.
    const dataFormatter: Jsona = new Jsona();
    // Deserialise the response.
    const articles = dataFormatter.deserialize(json);

    return articles;
}


export const fetchMainNavigationMenu = async () => {
    const baseURL = resolve_baseURL();
    // Please remeber to configure decoupled menu in your Drupal site.
    // (see: https://www.drupal.org/docs/develop/decoupled-drupal/decoupled-menus/decoupled-menus-overview)
    const url: string = `${baseURL}/system/menu/main/linkset`;
    const request = await fetch(url);
    if (!request.ok) {throw new Error(`JSON:API request failed: ${request.status} ${request.statusText}`,);}
    const json: string | TJsonApiBody = await request.json();

    // parse the json response to a javascript object
    let menu_data:NavigationMenuItem[]= [];
    const linkset_items = json.linkset[0].item;
    for (const linkset_item of linkset_items) {
        let parent_menu:NavigationMenuItem[] = menu_data;
        for (let i = 0; i < linkset_item.hierarchy.length; i++) {
            if(i == (linkset_item.hierarchy.length - 1)){
                parent_menu.push({
                    label: linkset_item.title,
                    to: linkset_item.href,
                    children: [],
                });
            } else {
                const hierarchy_idx = linkset_item.hierarchy[i];
                parent_menu = parent_menu[hierarchy_idx].children as NavigationMenuItem[];
            }
        }

    }
    return menu_data;
}
