export interface StorageManagerLike {
  estimate(): Promise<StorageEstimate>;
  persisted?(): Promise<boolean>;
  persist?(): Promise<boolean>;
}

export interface StorageQuotaSnapshot {
  readonly available: boolean;
  readonly usageBytes?: number;
  readonly quotaBytes?: number;
  readonly remainingBytes?: number;
  readonly usageFraction?: number;
  readonly persisted?: boolean;
  readonly error?: string;
}

export async function readStorageQuota(
  storage?: StorageManagerLike
): Promise<StorageQuotaSnapshot> {
  const manager =
    storage ??
    (typeof navigator !== 'undefined' ? navigator.storage : undefined);
  if (!manager?.estimate) {
    return {
      available: false,
      error: 'Browser storage estimates are unavailable.',
    };
  }
  try {
    const estimate = await manager.estimate();
    const usageBytes = estimate.usage;
    const quotaBytes = estimate.quota;
    const persisted = manager.persisted ? await manager.persisted() : undefined;
    return Object.freeze({
      available: true,
      ...(usageBytes !== undefined ? { usageBytes } : {}),
      ...(quotaBytes !== undefined ? { quotaBytes } : {}),
      ...(usageBytes !== undefined && quotaBytes !== undefined
        ? {
            remainingBytes: Math.max(0, quotaBytes - usageBytes),
            usageFraction: quotaBytes > 0 ? usageBytes / quotaBytes : 0,
          }
        : {}),
      ...(persisted !== undefined ? { persisted } : {}),
    });
  } catch (error) {
    return {
      available: false,
      error:
        error instanceof Error ? error.message : 'Storage estimate failed.',
    };
  }
}

export async function requestPersistentStorage(
  storage?: StorageManagerLike
): Promise<boolean> {
  const manager =
    storage ??
    (typeof navigator !== 'undefined' ? navigator.storage : undefined);
  if (!manager?.persist) {
    return false;
  }
  return manager.persist();
}
