/* ================================================================
   Sichere Ablage auf dem Gerät (iOS Keychain / Android Keystore)
   ================================================================
   Der Zugangstoken hat vollen Zugriff auf die Home-Assistant-Schnittstelle.
   Im Browser bleibt nur localStorage; in der nativen Hülle gehört er in den
   Schlüsselbund des Betriebssystems.

   **Noch nicht in Betrieb**: das Plugin ist bewusst keine Abhängigkeit,
   solange die Capacitor-Hülle nicht gebaut ist. Der Adapter greift deshalb
   defensiv auf die Laufzeit zu, statt zu importieren — fehlt das Plugin,
   bleibt es bei der Browser-Variante, und die App läuft trotzdem.

   In Betrieb nehmen (UMSETZUNGSPLAN.md Phase 10 Stufe 2):
     npm i @aparajita/capacitor-secure-storage
   Danach ruft main.tsx `nativeAblageEinrichten()` auf. */

import { BrowserAblage, ablageSetzen, umgebungErkennen, type Ablage } from "./umgebung.ts";

/** Form des Plugins, so weit die App sie braucht. */
interface SicherheitsPlugin {
  get(optionen: { key: string }): Promise<{ value: string | null }>;
  set(optionen: { key: string; value: string }): Promise<void>;
  remove(optionen: { key: string }): Promise<void>;
}

function pluginHolen(): SicherheitsPlugin | null {
  if (typeof window === "undefined") return null;
  const global = window as unknown as {
    Capacitor?: { Plugins?: Record<string, unknown> };
  };
  const plugin = global.Capacitor?.Plugins?.["SecureStorage"];
  if (!plugin) return null;
  const kandidat = plugin as Partial<SicherheitsPlugin>;
  return typeof kandidat.get === "function" &&
    typeof kandidat.set === "function" &&
    typeof kandidat.remove === "function"
    ? (plugin as SicherheitsPlugin)
    : null;
}

export class NativeAblage implements Ablage {
  readonly #plugin: SicherheitsPlugin;
  /* Fällt einzeln auf den Browser zurück, wenn ein Aufruf scheitert - besser
     eine Sitzung ohne Schlüsselbund als eine App, die nicht startet. */
  readonly #ersatz = new BrowserAblage();

  constructor(plugin: SicherheitsPlugin) {
    this.#plugin = plugin;
  }

  async lesen(schluessel: string): Promise<string | null> {
    try {
      const { value } = await this.#plugin.get({ key: schluessel });
      return value ?? null;
    } catch {
      return this.#ersatz.lesen(schluessel);
    }
  }

  async schreiben(schluessel: string, wert: string): Promise<void> {
    try {
      await this.#plugin.set({ key: schluessel, value: wert });
    } catch {
      await this.#ersatz.schreiben(schluessel, wert);
    }
  }

  async loeschen(schluessel: string): Promise<void> {
    try {
      await this.#plugin.remove({ key: schluessel });
    } catch {
      await this.#ersatz.loeschen(schluessel);
    }
  }
}

/**
 * Schaltet auf die sichere Ablage um, sofern die App nativ läuft und das
 * Plugin vorhanden ist. Gibt zurück, ob umgeschaltet wurde — praktisch für
 * eine Anzeige in den Einstellungen.
 */
export function nativeAblageEinrichten(): boolean {
  if (umgebungErkennen() !== "capacitor") return false;
  const plugin = pluginHolen();
  if (!plugin) return false;
  ablageSetzen(new NativeAblage(plugin));
  return true;
}
