// src/lib/tours/mark-tour.ts — corps de l'unique écriture publique.
//
// Volontairement HORS "use server" et sans dépendance serveur : `markTour`
// reçoit session, garde et persistance en paramètres. C'est ce qui rend la
// garde d'usurpation assertable pour ce qu'elle FAIT (« rien n'est écrit »)
// plutôt que par une inspection du texte de ./actions.ts, qu'un remaniement
// équivalent — paralléliser les deux lectures, annoter un type, renommer un
// helper — rendrait rouge à tort.
import { TOUR_IDS, type TourId } from "./catalog";
import type { TourStatus } from "./progress";

const STATUSES: readonly TourStatus[] = ["completed", "dismissed"];

export type MarkTourDeps = {
  /** Vraie quand un super-admin agit sous l'identité d'un client. */
  isImpersonating: () => Promise<boolean>;
  /** Identité DÉRIVÉE de la session — jamais un paramètre d'appel. */
  getUserId: () => Promise<string>;
  setProgress: (
    userId: string,
    tourId: string,
    status: TourStatus,
  ) => Promise<void>;
};

/**
 * Pendant une usurpation, Better Auth REMPLACE l'utilisateur de session par la
 * personne ciblée (voir `src/lib/auth/impersonation-guard.ts`) : l'écriture
 * atterrit sur son compte, et un opérateur du support qui parcourt son espace
 * lui consommerait durablement des tours qu'elle n'a jamais vus. C'est vrai
 * quel que soit le schéma de la table — `activation_dismissals`, clée sur
 * (utilisateur, organisation), brûle exactement pareil et porte la même garde.
 * L'absence d'`org_id` sur `tour_progress` ne change pas le danger, seulement
 * son rayon : la brûlure est globale à l'utilisateur au lieu d'être confinée à
 * l'organisation consultée.
 *
 * `tourId` et `status` viennent d'un endpoint POST : on les recale sur le
 * catalogue plutôt que d'écrire une ligne orpheline qu'aucun tour ne relira.
 * Un refus est silencieux — la portée est de toute façon auto-infligée, la clé
 * primaire contenant l'identifiant d'utilisateur de l'appelant.
 */
export async function markTour(
  deps: MarkTourDeps,
  tourId: string,
  status: TourStatus,
): Promise<void> {
  if (await deps.isImpersonating()) return;
  if (!TOUR_IDS.includes(tourId as TourId) || !STATUSES.includes(status))
    return;
  const userId = await deps.getUserId();
  await deps.setProgress(userId, tourId, status);
}
