/**
 * Local-storage and BroadcastChannel helpers for StateSyncManager.
 *
 * Extracted from sync.ts to stay within the 300-LOC target.
 */

import type { SDKState, SyncState } from '@breakpilot/compliance-sdk-types'

// =============================================================================
// CONSTANTS
// =============================================================================

export const STORAGE_KEY_PREFIX = 'breakpilot-compliance-sdk-state'
export const SYNC_CHANNEL = 'breakpilot-sdk-state-sync'

// =============================================================================
// TAB ID
// =============================================================================

export function getTabId(): string {
  if (typeof window === 'undefined') return 'server'

  let tabId = sessionStorage.getItem('breakpilot-sdk-tab-id')
  if (!tabId) {
    tabId = `tab-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`
    sessionStorage.setItem('breakpilot-sdk-tab-id', tabId)
  }
  return tabId
}

// =============================================================================
// LOCAL STORAGE HELPERS
// =============================================================================

export function getStorageKey(tenantId: string): string {
  return `${STORAGE_KEY_PREFIX}-${tenantId}`
}

export function saveStateToLocalStorage(
  tenantId: string,
  state: SDKState,
  version: number
): void {
  if (typeof window === 'undefined') return

  try {
    const data = {
      state,
      version,
      savedAt: new Date().toISOString(),
    }
    localStorage.setItem(getStorageKey(tenantId), JSON.stringify(data))
  } catch (error) {
    console.error('Failed to save to localStorage:', error)
  }
}

export function loadStateFromLocalStorage(
  tenantId: string,
  syncState: SyncState
): SDKState | null {
  if (typeof window === 'undefined') return null

  try {
    const stored = localStorage.getItem(getStorageKey(tenantId))
    if (stored) {
      const data = JSON.parse(stored)
      syncState.localVersion = data.version || 0
      return data.state
    }
  } catch (error) {
    console.error('Failed to load from localStorage:', error)
  }
  return null
}

export function clearStateFromLocalStorage(tenantId: string): void {
  if (typeof window === 'undefined') return

  try {
    localStorage.removeItem(getStorageKey(tenantId))
  } catch (error) {
    console.error('Failed to clear localStorage:', error)
  }
}

// =============================================================================
// BROADCAST CHANNEL HELPERS
// =============================================================================

export function createBroadcastChannel(
  tenantId: string
): BroadcastChannel | null {
  if (typeof window === 'undefined' || !('BroadcastChannel' in window)) {
    return null
  }

  try {
    return new BroadcastChannel(`${SYNC_CHANNEL}-${tenantId}`)
  } catch (error) {
    console.warn('BroadcastChannel not available:', error)
    return null
  }
}

export function broadcastStateUpdate(
  channel: BroadcastChannel | null,
  state: SDKState,
  version: number
): void {
  if (!channel) return

  channel.postMessage({
    type: 'STATE_UPDATED',
    state,
    version,
    tabId: getTabId(),
  })
}

export function broadcastSyncComplete(
  channel: BroadcastChannel | null,
  version: number
): void {
  if (!channel) return

  channel.postMessage({
    type: 'SYNC_COMPLETE',
    version,
    tabId: getTabId(),
  })
}

// =============================================================================
// ONLINE / OFFLINE LISTENER
// =============================================================================

export interface OnlineListenerHandlers {
  onOnline: () => void
  onOffline: () => void
}

/**
 * Registers window online/offline listeners and returns the current online status.
 * No-ops in non-browser environments.
 */
export function setupOnlineListener(handlers: OnlineListenerHandlers): boolean {
  if (typeof window === 'undefined') return true

  window.addEventListener('online', handlers.onOnline)
  window.addEventListener('offline', handlers.onOffline)

  return navigator.onLine
}
