/**
 * Pusher Beams composable for push notifications
 * Handles initialization and user authentication with Pusher Beams
 */

import { registerPlugin } from '@capacitor/core'

// Define the plugin interface
interface PusherBeamsPlugin {
  start(options: { instanceId: string }): Promise<void>
  setUserId(options: { userId: string, tokenProviderUrl: string, sessionCookie?: string }): Promise<void>
  clearAllState(): Promise<void>
  getDeviceId(): Promise<{ deviceId: string }>
  addDeviceInterest(options: { interest: string }): Promise<void>
  removeDeviceInterest(options: { interest: string }): Promise<void>
}

// Register the plugin (only works on native platforms)
const PusherBeams = registerPlugin<PusherBeamsPlugin>('PusherBeams')

export function usePusherBeams() {
  const config = useRuntimeConfig()
  const log = useLogger('PusherBeams')

  const isInitialized = ref(false)
  const error = ref<string | null>(null)

  // Lazy check for native platform - only call useCapacitor when needed
  const checkIsNative = (): boolean => {
    if (!import.meta.client) return false
    try {
      const { isCapacitor } = useCapacitor()
      return isCapacitor?.value === true
    } catch {
      return false
    }
  }

  /**
   * Initialize Pusher Beams
   * Should be called once when the app starts
   */
  async function initialize(instanceId: string): Promise<boolean> {
    if (!checkIsNative()) {
      log.info('Not on native platform, skipping initialization')
      return false
    }

    try {
      await PusherBeams.start({ instanceId })
      isInitialized.value = true
      error.value = null
      log.info('Initialized successfully')
      return true
    } catch (e: unknown) {
      error.value = e instanceof Error ? e.message : 'Failed to initialize Pusher Beams'
      log.error('Initialization failed:', e)
      return false
    }
  }

  /**
   * Associate the current user with Pusher Beams
   * Should be called after user logs in
   */
  async function setUser(userId: string): Promise<boolean> {
    if (!checkIsNative()) {
      log.info('Not on native platform, skipping setUser')
      return false
    }

    if (!isInitialized.value) {
      log.warn('Not initialized, cannot set user')
      return false
    }

    try {
      // Get the backend API base URL for the token provider
      const baseUrl = config.public.backendApiBaseUrl || ''
      const tokenProviderUrl = `${baseUrl}/api/push/auth`

      // Get session cookie for authentication
      // In Capacitor WebView, document.cookie contains the session cookies
      const sessionCookie = typeof document !== 'undefined' ? document.cookie : ''

      await PusherBeams.setUserId({
        userId,
        tokenProviderUrl,
        sessionCookie
      })

      log.info('User set successfully:', userId)
      return true
    } catch (e: unknown) {
      error.value = e instanceof Error ? e.message : 'Failed to set user'
      log.error('setUser failed:', e)
      return false
    }
  }

  /**
   * Clear all Pusher Beams state
   * Should be called when user logs out
   */
  async function clearState(): Promise<boolean> {
    if (!checkIsNative()) {
      return false
    }

    try {
      await PusherBeams.clearAllState()
      isInitialized.value = false
      log.info('State cleared')
      return true
    } catch (e: unknown) {
      error.value = e instanceof Error ? e.message : 'Failed to clear state'
      log.error('clearState failed:', e)
      return false
    }
  }

  /**
   * Get the device ID (useful for debugging)
   */
  async function getDeviceId(): Promise<string | null> {
    if (!checkIsNative() || !isInitialized.value) {
      return null
    }

    try {
      const result = await PusherBeams.getDeviceId()
      return result.deviceId
    } catch (e: unknown) {
      log.error('getDeviceId failed:', e)
      return null
    }
  }

  /**
   * Subscribe to a device interest (topic)
   */
  async function addInterest(interest: string): Promise<boolean> {
    if (!checkIsNative() || !isInitialized.value) {
      return false
    }

    try {
      await PusherBeams.addDeviceInterest({ interest })
      return true
    } catch (e: unknown) {
      log.error('addInterest failed:', e)
      return false
    }
  }

  /**
   * Unsubscribe from a device interest
   */
  async function removeInterest(interest: string): Promise<boolean> {
    if (!checkIsNative() || !isInitialized.value) {
      return false
    }

    try {
      await PusherBeams.removeDeviceInterest({ interest })
      return true
    } catch (e: unknown) {
      log.error('removeInterest failed:', e)
      return false
    }
  }

  return {
    isInitialized: readonly(isInitialized),
    error: readonly(error),
    initialize,
    setUser,
    clearState,
    getDeviceId,
    addInterest,
    removeInterest
  }
}
