app/src/services/FeatureFlagService.tstypescript
import { UnleashClient } from "unleash-proxy-client";
import { debug, warn } from "@/utils/logging";
import env from "../utils/env";

const FEATURE_FLAG_API_KEY = env.VITE_FEATURE_FLAG_API_KEY;

const unleash = new UnleashClient({
  url: "https://features.choreo-planer.de/api/frontend",
  clientKey: FEATURE_FLAG_API_KEY as string,
  appName: "choreo-planer-ui",
});

/**
 * Known feature flag keys used by the UI.
 * @readonly
 * @enum {string}
 */
export const FeatureFlagKeys = {
  MOBILE_EDITING: "mobile-editing",
  CONTACT_FORM_WITH_LOGIN: "contact-with-login",
  CONTACT_FORM_WITHOUT_LOGIN: "contact-without-login",
  ACCESS_SHARING: "access-sharing",
  SOCIAL_LOGIN: "social-login",
  GOOGLE_OAUTH: "google-oauth",
  GITHUB_OAUTH: "github-oauth",
  FACEBOOK_OAUTH: "facebook-oauth",
} as const;

type FeatureFlagKey = (typeof FeatureFlagKeys)[keyof typeof FeatureFlagKeys];

/**
 * Client-side FeatureFlagService using the a proxy client.
 *
 * The service starts the client once and exposes helper methods
 * to check whether flags are enabled. Consumers should await the
 * initialization before querying flags to ensure the client has fetched
 * the current toggle state.
 */
class FeatureFlagService {
  unleash: UnleashClient;
  initialization: Promise<void>;

  /**
   * Initialize the service and start background polling.
   * @constructor
   */
  constructor() {
    this.unleash = unleash;
    // Start the background polling
    this.initialization = this.unleash.start();
  }

  /**
   * Check whether a feature flag is enabled.
   *
   * Waits for the client to finish initial startup before querying.
   * Logs a warning for unknown flags.
   *
   * @param {string} flagName - The feature flag key to check.
   * @returns {Promise<boolean>} Resolves to true when the flag is enabled.
   */
  async isEnabled(flagName: string): Promise<boolean> {
    await this.initialization;
    if (!Object.values(FeatureFlagKeys).includes(flagName as FeatureFlagKey))
      warn(`Unknown feature flag: ${flagName}`);
    const result = this.unleash.isEnabled(flagName);
    debug(`Feature flag "${flagName}" is ${result ? "enabled" : "disabled"}`);
    return result;
  }
}

export default new FeatureFlagService();