/**
 * MGT2 Commerce – Client API Traveller Map
 *
 * Documentation : https://travellermap.com/doc/api
 *
 * Deux fonctions exportées :
 *   searchWorlds(query)             → [{name, sector, hex, uwp, zone}]
 *   fetchWorldDetail(sector, hex)   → {uwp, zone}  (zone: 'normal'|'amber'|'red')
 */

const BASE_URL = 'https://travellermap.com';

/** Convertit la zone Traveller Map ('A', 'R', '') vers notre convention. */
function normalizeZone(z) {
  if (z === 'A') return 'amber';
  if (z === 'R') return 'red';
  return 'normal';
}

/**
 * Recherche des mondes par nom via l'API Traveller Map.
 *
 * @param {string} query  Nom partiel ou complet (ex. "Regina")
 * @returns {Promise<Array<{name:string, sector:string, hex:string, uwp:string}>>}
 *          Tableau de résultats (uniquement les mondes, pas secteurs/subsecteurs).
 *          Vide si erreur réseau.
 */
export async function searchWorlds(query) {
  if (!query || query.trim().length < 2) return [];

  const url = `${BASE_URL}/api/search?q=${encodeURIComponent(query.trim())}`;

  let data;
  try {
    const resp = await fetch(url);
    if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
    data = await resp.json();
  } catch (err) {
    console.warn('MGT2 Commerce | Traveller Map search error:', err);
    return [];
  }

  const items = data?.Results?.Items ?? [];
  return items
    .filter(item => item.World)           // garder uniquement les mondes
    .map(item => {
      const w = item.World;
      // Formatter le code hex sur 4 chiffres (HexX→XX, HexY→YY)
      const hex = String(w.HexX).padStart(2, '0') + String(w.HexY).padStart(2, '0');
      return {
        name:   w.Name,
        sector: w.Sector,
        hex,
        uwp:    w.Uwp ?? '',
      };
    });
}

/**
 * Récupère les coordonnées absolues d'un monde en parsecs.
 * Utilise l'endpoint /api/coordinates.
 *
 * @param {string} sector  Nom du secteur (ex. "Spinward Marches")
 * @param {string} hex     Code hex 4 chiffres (ex. "1910")
 * @returns {Promise<{x:number, y:number}|null>}
 */
export async function fetchWorldCoordinates(sector, hex) {
  const url = `${BASE_URL}/api/coordinates?sector=${encodeURIComponent(sector)}&hex=${encodeURIComponent(hex)}`;

  try {
    const resp = await fetch(url);
    if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
    const data = await resp.json();
    if (data?.x == null || data?.y == null) return null;
    return { x: data.x, y: data.y };
  } catch (err) {
    console.warn('MGT2 Commerce | Traveller Map coordinates error:', err);
    return null;
  }
}

/**
 * Calcule la distance en parsecs entre deux mondes à partir de leurs
 * coordonnées absolues (retournées par fetchWorldCoordinates).
 * Utilise la formule de distance en coordonnées cubiques pour grille hexagonale.
 *
 * Dans le système Traveller Map : les colonnes impaires (hx impair) sont
 * décalées vers le bas. En coordonnées API, hx impair ↔ x pair.
 * Conversion offset→cube : q=x, r=y−⌈x/2⌉, s=−q−r.
 * Distance = max(|Δq|, |Δr|, |Δs|).
 *
 * @param {{x:number,y:number}} c1
 * @param {{x:number,y:number}} c2
 * @returns {number}  Distance en parsecs (entier, minimum 1)
 */
export function calcParsecs(c1, c2) {
  const q1 = c1.x, r1 = c1.y - Math.ceil(c1.x / 2);
  const q2 = c2.x, r2 = c2.y - Math.ceil(c2.x / 2);
  const dq = q2 - q1, dr = r2 - r1, ds = -dq - dr;
  return Math.max(1, Math.max(Math.abs(dq), Math.abs(dr), Math.abs(ds)));
}

/**
 * Récupère les détails d'un monde pour obtenir la zone de voyage.
 * Utilise l'endpoint /data/{sector}/{hex} (jump=0).
 *
 * @param {string} sector  Nom du secteur (ex. "Spinward Marches")
 * @param {string} hex     Code hex 4 chiffres (ex. "1910")
 * @returns {Promise<{uwp:string, zone:string}>}
 */
export async function fetchWorldDetail(sector, hex) {
  const url = `${BASE_URL}/data/${encodeURIComponent(sector)}/${hex}`;

  let data;
  try {
    const resp = await fetch(url);
    if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
    data = await resp.json();
  } catch (err) {
    console.warn('MGT2 Commerce | Traveller Map detail error:', err);
    return null;
  }

  const world = data?.Worlds?.[0];
  if (!world) return null;

  return {
    uwp:  world.UWP ?? '',
    zone: normalizeZone(world.Zone ?? ''),
  };
}
