import { Platform } from 'react-native'
import { appKeys, appStorage } from './storage'

// Android Prominent Disclosure (D.2). Play UGC + sensitive-permissions policy
// requires an in-app explanation BEFORE the system permission prompt for
// camera and microphone. iOS uses the NS*UsageDescription Info.plist strings
// instead, so on iOS this store short-circuits and the actual permission
// request fires immediately.
//
// Shape mirrors AccountStore: tiny singleton with subscribe/snapshot for
// React via useSyncExternalStore. The modal lives in src/components/
// PermissionDisclosure.tsx and is mounted once at the root layout.

export type DisclosureKind = 'camera' | 'microphone'

type State = {
  visible: boolean
  kind: DisclosureKind | null
}

let _state: State = { visible: false, kind: null }
let _pendingResolve: (() => void) | null = null
const _listeners = new Set<() => void>()

function emit() {
  for (const fn of _listeners) fn()
}

function setState(next: State) {
  _state = next
  emit()
}

function isAlreadyDisclosed(kind: DisclosureKind): boolean {
  return appStorage.getBoolean(appKeys.permissionDisclosed(kind)) === true
}

function markDisclosed(kind: DisclosureKind): void {
  appStorage.set(appKeys.permissionDisclosed(kind), true)
}

/**
 * Show the disclosure modal for the given permission kind, then resolve.
 *
 * Resolves immediately (no modal) when:
 *   - Platform is iOS (Info.plist strings cover the disclosure).
 *   - The user has already seen the modal for this kind on this device.
 *
 * Otherwise on Android, opens the modal and resolves when the user taps
 * Continue. If a second `disclose()` call lands while the modal is already
 * open, the existing promise is replaced — the modal stays open with the
 * newly-requested kind, and only the latest caller's resolver fires on
 * Continue. Sequential awaits from useStoryCompose are the expected pattern;
 * concurrent calls are not.
 */
export function disclose(kind: DisclosureKind): Promise<void> {
  if (Platform.OS !== 'android') return Promise.resolve()
  if (isAlreadyDisclosed(kind)) return Promise.resolve()
  return new Promise<void>((resolve) => {
    _pendingResolve = resolve
    setState({ visible: true, kind })
  })
}

/** Called by the modal's Continue button. */
export function acknowledge(): void {
  const kind = _state.kind
  if (kind) markDisclosed(kind)
  const resolve = _pendingResolve
  _pendingResolve = null
  setState({ visible: false, kind: null })
  resolve?.()
}

export const PermissionDisclosureStore = {
  subscribe(listener: () => void): () => void {
    _listeners.add(listener)
    return () => {
      _listeners.delete(listener)
    }
  },
  getSnapshot(): State {
    return _state
  },
} as const
