import type { EncryptionState } from './types';

export type RecoveryPrompt = 'recover' | 'setup';

export interface InstallContext {
  device: boolean;
  standalone: boolean;
}

export interface PersistResult {
  persisted: boolean;
  usage: number | null;
  quota: number | null;
}

export interface StorageLike {
  getItem(key: string): string | null;
  setItem(key: string, value: string): void;
}

export interface PersistManager {
  persisted?(): Promise<boolean>;
  persist?(): Promise<boolean>;
  estimate?(): Promise<{ usage?: number; quota?: number }>;
}

export function canDismissRecovery(ctx: InstallContext): boolean {
  return ctx.device && !ctx.standalone;
}

export function recoveryPrompt(state: EncryptionState | null, ctx: InstallContext, dismissed: boolean): RecoveryPrompt | null {
  if (!state) return null;
  if (state.recovery === 'Incomplete') return 'recover';
  if (state.recovery === 'Disabled') return dismissed && canDismissRecovery(ctx) ? null : 'setup';
  return null;
}

export function dismissalKey(kind: 'recovery' | 'storage', account: string): string {
  return `malice.dismissed.${kind}.${account}`;
}

export function isDismissed(store: StorageLike, kind: 'recovery' | 'storage', account: string): boolean {
  try {
    return store.getItem(dismissalKey(kind, account)) === '1';
  } catch {
    return false;
  }
}

export function setDismissed(store: StorageLike, kind: 'recovery' | 'storage', account: string): void {
  try {
    store.setItem(dismissalKey(kind, account), '1');
  } catch {
    // dismissal then lasts only for this page load
  }
}

export async function requestPersistence(manager: PersistManager | undefined): Promise<PersistResult | null> {
  if (!manager?.persist || !manager.persisted) return null;
  let persisted = await manager.persisted();
  if (!persisted) persisted = await manager.persist();
  const estimate = manager.estimate ? await manager.estimate().catch(() => null) : null;
  return { persisted, usage: estimate?.usage ?? null, quota: estimate?.quota ?? null };
}
