/**
 * Feature Flags module — React context + hook for feature flags in React Native apps.
 */

import React, { createContext, useContext, useState, useCallback, useEffect } from 'react';
import type { PlatformSDK } from '../core.js';

export interface FeatureFlag {
  key: string;
  enabled: boolean;
  value?: unknown;
}

interface FeatureFlagContextType {
  flags: Map<string, FeatureFlag>;
  isEnabled: (key: string) => boolean;
  getValue: <T = unknown>(key: string, fallback: T) => T;
  refresh: () => Promise<void>;
}

const FeatureFlagContext = createContext<FeatureFlagContextType | null>(null);

export function useFeatureFlags(): FeatureFlagContextType {
  const ctx = useContext(FeatureFlagContext);
  if (!ctx) throw new Error('useFeatureFlags must be used within a FeatureFlagProvider');
  return ctx;
}

interface FeatureFlagProviderProps {
  sdk: PlatformSDK;
  /** Poll interval in ms (default: 60000) */
  pollInterval?: number;
  /** Optional user id for targeted flag evaluation (GET /flags/poll). */
  userId?: string | null;
  children: React.ReactNode;
}

export function FeatureFlagProvider({
  sdk,
  pollInterval = 60_000,
  userId,
  children,
}: FeatureFlagProviderProps): React.JSX.Element {
  const [flags, setFlags] = useState<Map<string, FeatureFlag>>(new Map());

  const refresh = useCallback(async () => {
    try {
      const qs = new URLSearchParams({ platform: 'mobile' });
      if (userId) qs.set('userId', userId);
      const res = await sdk.fetch(`/flags/poll?${qs.toString()}`);
      if (res.ok) {
        const data = (await res.json()) as { flags?: Record<string, boolean> };
        const map = new Map<string, FeatureFlag>();
        const raw = data.flags ?? {};
        for (const [key, enabled] of Object.entries(raw)) {
          map.set(key, { key, enabled, value: enabled });
        }
        setFlags(map);
      }
    } catch {
      /* fail-open: keep existing flags */
    }
  }, [sdk, userId]);

  const isEnabled = useCallback(
    (key: string): boolean => {
      return flags.get(key)?.enabled ?? false;
    },
    [flags]
  );

  const getValue = useCallback(
    <T = unknown>(key: string, fallback: T): T => {
      const flag = flags.get(key);
      if (!flag?.enabled) return fallback;
      return (flag.value as T) ?? fallback;
    },
    [flags]
  );

  useEffect(() => {
    refresh();
    const id = setInterval(refresh, pollInterval);
    return () => clearInterval(id);
  }, [refresh, pollInterval]);

  const value: FeatureFlagContextType = { flags, isEnabled, getValue, refresh };
  return React.createElement(FeatureFlagContext.Provider, { value }, children);
}
