import "server-only";
import { apiFetch } from "@/lib/api";
import { ApiError } from "@/lib/api-error";
import {
  integrationListSchema,
  keywordListsSchema,
  type Integration,
  type KeywordListRef,
} from "@/lib/integrations";

// D'où viennent les mots-clés d'un import : un fichier, ou l'API du fournisseur branché.
//
// **Serveur uniquement** (`server-only`, comme `lib/api.ts`) : ce module appelle l'api. Il est
// séparé de `lib/integrations.ts` — que des composants clients importent pour ses types et ses
// libellés — précisément pour que l'un ne traîne jamais l'autre dans un bundle navigateur.
//
// Le fournisseur BYOK est unique aujourd'hui (Mangools/KWFinder) ; le jour où il y en aura deux,
// c'est cette fonction qui rendra une liste, et les tuiles suivront sans qu'un écran change.

export const KWFINDER_PROVIDER = "mangools";

/** Les deux valeurs que `?source=` peut prendre. Tout le reste retombe sur le choix. */
export const IMPORT_SOURCES = ["csv", "api"] as const;
export type ImportSource = (typeof IMPORT_SOURCES)[number];

export function parseImportSource(value: string | undefined): ImportSource | null {
  return IMPORT_SOURCES.find((source) => source === value) ?? null;
}

export type ApiSourceAccess = {
  integration: Integration | null;
  /**
   * La voie API est ouverte : une clé existe **et** le fournisseur lui a répondu. C'est le
   * `status` enregistré par `POST /integrations/{id}/check` qui fait foi — vérifier à nouveau
   * ici transformerait l'ouverture d'un écran en appel réseau vers un tiers, à chaque rendu.
   */
  ready: boolean;
};

/**
 * L'intégration KWFinder de l'organisation, et si elle est utilisable.
 *
 * **Ne jette jamais** : cet appel décore un écran (une tuile, un état vide), il ne le porte pas.
 * Une api qui bronche doit coûter une tuile désactivée, jamais la page entière — l'utilisateur
 * garde le chemin CSV et le lien vers les réglages.
 */
export async function loadApiSourceAccess(): Promise<ApiSourceAccess> {
  try {
    const listing = integrationListSchema.parse(await apiFetch<unknown>("/integrations"));
    const integration = listing.items.find((item) => item.provider === KWFINDER_PROVIDER) ?? null;
    return { integration, ready: integration?.status === "connected" };
  } catch {
    return { integration: null, ready: false };
  }
}

/**
 * Les listes déjà enregistrées dans le compte du fournisseur — l'étape 1 du parcours API.
 *
 * **Chargées ici, côté serveur, et pas par le wizard.** L'écran s'ouvre alors sur ses listes au
 * lieu d'un squelette, il n'y a pas d'aller-retour de plus après l'hydratation, et le composant
 * client n'a plus qu'un état de sélection à tenir — la règle « Server Components par défaut »
 * appliquée là où elle rapporte quelque chose de visible.
 *
 * Le coût est nul chez le fournisseur (`GET /kwfinder/lists` ne consomme aucune unité de quota,
 * mesuré le 2026-09-02) et l'appel n'est fait que sur la branche API du wizard.
 *
 * **Ne jette jamais**, comme `loadApiSourceAccess` : un fournisseur muet doit coûter une liste
 * vide et son motif à l'écran, jamais la page entière dans son `error.tsx`.
 */
export async function loadKwfinderLists(
  integrationId: string,
): Promise<{ lists: KeywordListRef[]; error: string | null }> {
  try {
    const raw = await apiFetch<unknown>(`/integrations/${integrationId}/lists`);
    return { lists: keywordListsSchema.parse(raw).items, error: null };
  } catch (error) {
    //  Le motif du fournisseur quand il y en a un (clé refusée, quota atteint) : c'est le seul
    //  message sur lequel l'utilisateur peut agir. Le détail d'une panne de notre côté ne
    //  traverse pas la frontière (architecture §9).
    return {
      lists: [],
      error:
        error instanceof ApiError ? error.message : "Listes KWFinder indisponibles pour le moment",
    };
  }
}
