/**
 * Broadcasts module — React context + hook for in-app messages in React Native apps.
 */

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

export interface InAppMessage {
  id: string;
  title: string;
  body: string;
  type: 'info' | 'warning' | 'critical';
  action?: { label: string; url: string };
  dismissible: boolean;
  expiresAt?: string;
}

interface BroadcastContextType {
  messages: InAppMessage[];
  dismiss: (id: string) => void;
  refresh: () => Promise<void>;
}

const BroadcastContext = createContext<BroadcastContextType | null>(null);

export function useBroadcasts(): BroadcastContextType {
  const ctx = useContext(BroadcastContext);
  if (!ctx) throw new Error('useBroadcasts must be used within a BroadcastProvider');
  return ctx;
}

interface BroadcastProviderProps {
  sdk: PlatformSDK;
  /** Poll interval in ms (default: 300000 = 5 min) */
  pollInterval?: number;
  children: React.ReactNode;
}

export function BroadcastProvider({
  sdk,
  pollInterval = 300_000,
  children,
}: BroadcastProviderProps): React.JSX.Element {
  const [messages, setMessages] = useState<InAppMessage[]>([]);

  const refresh = useCallback(async () => {
    try {
      const res = await sdk.fetch('/broadcasts');
      if (!res.ok) return;
      const data = (await res.json()) as {
        messages?: Array<{
          id: string;
          title: string;
          body: string;
          ctaText?: string;
          ctaUrl?: string;
          priority?: 'low' | 'normal' | 'high' | 'urgent';
          dismissible?: boolean;
          expiresAt?: string;
        }>;
      };
      const raw = data.messages ?? [];
      const mapped: InAppMessage[] = raw.map(m => ({
        id: m.id,
        title: m.title,
        body: m.body,
        type:
          m.priority === 'urgent' ? 'critical' : m.priority === 'high' ? 'warning' : 'info',
        action:
          m.ctaText && m.ctaUrl ? { label: m.ctaText, url: m.ctaUrl } : undefined,
        dismissible: m.dismissible !== false,
        expiresAt: m.expiresAt,
      }));
      setMessages(mapped);
    } catch {
      /* silent */
    }
  }, [sdk]);

  const dismiss = useCallback(
    (id: string) => {
      setMessages(prev => prev.filter(m => m.id !== id));
      sdk.fetch(`/broadcasts/${id}/dismiss`, { method: 'POST' }).catch(() => {});
    },
    [sdk]
  );

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

  const value: BroadcastContextType = { messages, dismiss, refresh };
  return React.createElement(BroadcastContext.Provider, { value }, children);
}

// MARK: - UI Components

interface InAppMessageBannerProps {
  message: InAppMessage;
  onDismiss: () => void;
}

/**
 * Placeholder banner component — product apps should implement their own
 * styled version using this as a reference. Returns null (render-only hook).
 */
export function InAppMessageBanner(_props: InAppMessageBannerProps): React.JSX.Element | null {
  // Product apps implement their own styled component
  return null;
}

interface BroadcastModalProps {
  message: InAppMessage | null;
  onDismiss: () => void;
}

/**
 * Placeholder modal component — product apps should implement their own
 * styled version. Returns null.
 */
export function BroadcastModal(_props: BroadcastModalProps): React.JSX.Element | null {
  return null;
}
