/**
 * React Native Unified Auth Provider
 * 
 * Creates a platform-specific auth provider that automatically selects the appropriate storage:
 * - Web: Uses IndexedDBTokenStorage for DPoP (CryptoKey persistence) or LocalStorage
 * - Mobile: Uses AsyncStorage-based storage
 */

import { Platform } from 'react-native';
import { DefaultAuthProvider, AccountOwnerType, LocalStorageTokenStorage, IndexedDBTokenStorage } from '@explorins/pers-sdk/core';
import { ReactNativeSecureStorage } from '../storage/rn-secure-storage';
import type { TokenStorage } from '@explorins/pers-sdk/core';

// Use React Native's built-in platform detection
const isWebPlatform = Platform.OS === 'web';

/**
 * Check if IndexedDB is available (web environments only)
 * Uses globalThis to avoid TypeScript errors in React Native context
 */
function hasIndexedDB(): boolean {
  return typeof globalThis !== 'undefined' && 
         typeof (globalThis as Record<string, unknown>).indexedDB !== 'undefined';
}

/**
 * Configuration for React Native Auth Provider
 */
export interface ReactNativeAuthConfig {
  /** Custom storage key prefix */
  keyPrefix?: string;
  /** Enable debug logging */
  debug?: boolean;
  /** Custom token storage implementation */
  customStorage?: TokenStorage;
  /** Authentication type (default: AccountOwnerType.USER) */
  authType?: AccountOwnerType;
  /** DPoP Configuration (optional) */
  dpop?: {
    enabled?: boolean;
    cryptoProvider?: import('@explorins/pers-sdk/core').DPoPCryptoProvider;
  };
}

/**
 * Create a React Native auth provider with platform-appropriate storage
 * 
 * Automatically selects storage implementation:
 * - Web: Uses LocalStorageTokenStorage (from core SDK)
 * - Mobile: Uses AsyncStorageTokenStorage (React Native specific)
 * 
 * @param projectKey - PERS project key
 * @param config - Configuration options
 * @returns DefaultAuthProvider configured for the current platform
 */
export function createReactNativeAuthProvider(
  projectKey: string,
  config: ReactNativeAuthConfig = {}
): DefaultAuthProvider {
  if (!projectKey || typeof projectKey !== 'string') {
    throw new Error('createReactNativeAuthProvider: projectKey is required and must be a string');
  }

  const {
    keyPrefix = `pers_${projectKey.slice(0, 8)}_`,
    debug = false,
    customStorage,
    authType = AccountOwnerType.USER,
    dpop
  } = config;

  // Platform-specific storage selection
  // Web with DPoP: Use IndexedDB for CryptoKey persistence
  // Web without DPoP or no IndexedDB: Use LocalStorage
  // Mobile: Use ReactNativeSecureStorage
  let tokenStorage: TokenStorage;
  
  if (customStorage) {
    tokenStorage = customStorage;
  } else if (isWebPlatform) {
    // On web, prefer IndexedDB when DPoP is enabled for proper CryptoKey persistence
    const dpopEnabled = dpop?.enabled ?? true;
    
    if (dpopEnabled && hasIndexedDB()) {
      tokenStorage = new IndexedDBTokenStorage();
    } else {
      if (dpopEnabled && !hasIndexedDB()) {
        console.warn('[ReactNativeAuthProvider] DPoP requested but IndexedDB not available. Falling back to LocalStorage (DPoP will be disabled by DefaultAuthProvider).');
      }
      tokenStorage = new LocalStorageTokenStorage();
    }
  } else {
    tokenStorage = new ReactNativeSecureStorage(keyPrefix);
  }

  // Prepare DPoP config ensuring enabled is boolean (default true)
  const dpopConfig = dpop ? {
    enabled: dpop.enabled ?? true,
    cryptoProvider: dpop.cryptoProvider
  } : undefined;
  
  // DEBUG LOGGING
  if (debug) {
    console.log('[ReactNativeAuthProvider] Creating provider with DPoP config:', JSON.stringify(dpopConfig));
  }

  // Return DefaultAuthProvider configured with platform-appropriate storage
  return new DefaultAuthProvider({
    authType,
    projectKey,
    storage: tokenStorage,
    dpop: dpopConfig
  });
}

