import type { ApiEnvelope } from "../types/auth";
import type { MobileConfig } from "../types/mobileConfig";

// Fallback config used when the server is reachable but /mobile-config isn't implemented yet.
// The backend can override any of these values once the endpoint is deployed.
function buildFallbackConfig(baseUrl: string): MobileConfig {
  return {
    app_name: "MissioFlow Mobile",
    primary_color: "#1E56A8",
    logo_url: null,
    tenant_id: null,
    support_email: null,
    support_phone: null,
  };
}

function stripTrailingSlashes(value: string): string {
  let out = value;
  while (out.endsWith("/")) {
    out = out.slice(0, -1);
  }
  return out;
}

function buildMobileConfigUrls(baseUrl: string): string[] {
  const normalized = stripTrailingSlashes(baseUrl);
  if (normalized.endsWith("/api/mobile")) {
    return [`${normalized}-config`, `${normalized}-config.php`];
  }
  return [`${normalized}/mobile-config`, `${normalized}/mobile-config.php`];
}

// Vérifie que le serveur est joignable (n'importe quelle réponse HTTP valide suffit).
async function isServerReachable(baseUrl: string): Promise<boolean> {
  const normalized = stripTrailingSlashes(baseUrl);
  try {
    const response = await fetch(normalized, {
      method: "GET",
      headers: { Accept: "application/json" },
    });
    return response.status < 500;
  } catch {
    return false;
  }
}

async function tryFetch(endpoint: string): Promise<Response> {
  return fetch(endpoint, {
    method: "GET",
    headers: {
      Accept: "application/json",
    },
  });
}

export async function fetchMobileConfig(baseUrl: string): Promise<MobileConfig> {
  const endpoints = buildMobileConfigUrls(baseUrl);

  let serverWasReachable = false;
  let lastApiMessage: string | null = null;

  for (const endpoint of endpoints) {
    let response: Response;
    try {
      response = await tryFetch(endpoint);
      serverWasReachable = true;
    } catch {
      continue;
    }

    let payload: ApiEnvelope<MobileConfig> | null = null;
    try {
      payload = (await response.json()) as ApiEnvelope<MobileConfig>;
    } catch {
      // Corps non-JSON mais serveur joignable — on retient l'info.
      continue;
    }

    if (response.ok && payload?.success && payload.data) {
      return payload.data;
    }

    if (payload?.message) {
      lastApiMessage = payload.message;
    }
  }

  // Le serveur a répondu (même en 404) : l'endpoint n'est pas encore implémenté.
  // On utilise le config par défaut pour ne pas bloquer les tests terrain.
  if (serverWasReachable) {
    return buildFallbackConfig(baseUrl);
  }

  // Vérification supplémentaire : tenter la base URL directement.
  const reachable = await isServerReachable(baseUrl);
  if (reachable) {
    return buildFallbackConfig(baseUrl);
  }

  throw new Error(lastApiMessage || "Instance inaccessible ou invalide");
}
