import * as SecureStore from "expo-secure-store";

const API_BASE_URL_KEY = "mf_api_base_url";
const INVITE_TOKEN_KEY = "mf_invite_token";
const REQUEST_TIMEOUT_MS = 15000;

function normalizeUrl(value: string): string {
  const trimmed = value.trim();
  if (!trimmed) {
    throw new Error("L'URL de l'instance est requise.");
  }

  const withProtocol = /^https?:\/\//i.test(trimmed) ? trimmed : `https://${trimmed}`;

  let parsed: URL;
  try {
    parsed = new URL(withProtocol);
  } catch {
    throw new Error("URL d'instance invalide.");
  }

  // On exige https:// en production : sans TLS, le Bearer JWT (et les
  // identifiants au login) transiteraient en clair -> MITM trivial via un QR
  // d'onboarding ou une URL saisie pointant sur http://attaquant. http:// reste
  // tolere uniquement en developpement (__DEV__) pour cibler un backend local.
  const isHttps = parsed.protocol === "https:";
  const devHttpAllowed =
    parsed.protocol === "http:" && typeof __DEV__ !== "undefined" && __DEV__;
  if (!isHttps && !devHttpAllowed) {
    throw new Error("L'URL doit utiliser https:// (http n'est autorise qu'en developpement).");
  }

  let cleaned = parsed.toString();
  while (cleaned.endsWith("/")) {
    cleaned = cleaned.slice(0, -1);
  }

  // Strip trailing /mobile : on accepte les URLs d'onboarding finissant par
  // .../api/mobile (forme historique, suggeree dans le placeholder de
  // l'OnboardingScreen) tout en stockant la racine /api. Les endpoints metier
  // sont a /api/X.php et l'auth a /api/mobile/X.php — un seul stockage gere
  // les deux via concatenation de path.
  if (cleaned.endsWith("/api/mobile")) {
    cleaned = cleaned.slice(0, -"/mobile".length);
  }

  return cleaned;
}

export function getRequestTimeoutMs(): number {
  return REQUEST_TIMEOUT_MS;
}

export async function setEnvironmentBaseUrl(value: string): Promise<string> {
  const normalized = normalizeUrl(value);
  await SecureStore.setItemAsync(API_BASE_URL_KEY, normalized);
  return normalized;
}

export async function getEnvironmentBaseUrl(): Promise<string | null> {
  const value = await SecureStore.getItemAsync(API_BASE_URL_KEY);
  if (!value) {
    return null;
  }

  try {
    return normalizeUrl(value);
  } catch {
    return null;
  }
}

export async function requireEnvironmentBaseUrl(): Promise<string> {
  const value = await getEnvironmentBaseUrl();
  if (!value) {
    throw new Error("Aucune instance configuree. Configurez l'URL avant de vous connecter.");
  }
  return value;
}

export async function clearEnvironmentConfig(): Promise<void> {
  await Promise.all([
    SecureStore.deleteItemAsync(API_BASE_URL_KEY),
    SecureStore.deleteItemAsync(INVITE_TOKEN_KEY),
  ]);
}

export async function saveInviteToken(token: string | null): Promise<void> {
  if (!token || token.trim() === "") {
    await SecureStore.deleteItemAsync(INVITE_TOKEN_KEY);
    return;
  }
  await SecureStore.setItemAsync(INVITE_TOKEN_KEY, token.trim());
}

export async function getInviteToken(): Promise<string | null> {
  const value = await SecureStore.getItemAsync(INVITE_TOKEN_KEY);
  return value && value.trim() !== "" ? value : null;
}
