/**
 * Broadcast Client — Browser/React Native-safe broadcast messaging client
 * @module @bytelyst/broadcast-client
 */

// =============================================================================
// Types
// =============================================================================

export interface Broadcast {
  id: string;
  productId: string;
  title: string;
  body: string;
  bodyMarkdown?: string;
  ctaText?: string;
  ctaUrl?: string;
  imageUrl?: string;
  channels: ('push' | 'in_app' | 'email')[];
  status: 'draft' | 'scheduled' | 'sending' | 'sent' | 'paused';
  scheduledAt?: string;
  sentAt?: string;
  variant?: 'control' | 'treatment';
  experimentId?: string;
  parentBroadcastId?: string;
  metrics: BroadcastMetrics;
  createdAt: string;
  updatedAt: string;
  createdBy: string;
}

export interface BroadcastMetrics {
  targetedCount: number;
  sentCount: number;
  deliveredCount: number;
  openedCount: number;
  clickedCount: number;
  dismissedCount: number;
  convertedCount: number;
}

export interface InAppMessage {
  id: string;
  userId: string;
  productId: string;
  broadcastId: string;
  title: string;
  body: string;
  bodyMarkdown?: string;
  ctaText?: string;
  ctaUrl?: string;
  priority: 'low' | 'normal' | 'high' | 'urgent';
  style: 'banner' | 'modal' | 'toast' | 'fullscreen';
  dismissible: boolean;
  expiresAt?: string;
  status: 'unread' | 'read' | 'dismissed';
  createdAt: string;
  updatedAt: string;
}

export interface BroadcastClientConfig {
  /** Platform service base URL */
  baseUrl: string;
  /** Product ID */
  productId: string;
  /** Auth token provider (async or sync) */
  getAuthToken: (() => string) | (() => Promise<string>);
  /** Platform identifier */
  platform: 'web' | 'ios' | 'android' | 'macos' | 'windows';
  /** App version */
  appVersion: string;
  /** OS version */
  osVersion: string;
  /** Optional country code */
  countryCode?: string;
  /** Optional region code */
  regionCode?: string;
  /** User segments (default: ['free']) */
  userSegments?: string[];
}

// =============================================================================
// Client Factory
// =============================================================================

export interface BroadcastClient {
  /** List active in-app messages for current user */
  listMessages(): Promise<{ messages: InAppMessage[] }>;
  /** Mark message as read */
  markRead(messageId: string): Promise<void>;
  /** Mark message as dismissed */
  markDismissed(messageId: string): Promise<void>;
  /** Track CTA click */
  trackClick(messageId: string): Promise<{ redirectUrl?: string }>;
  /** Poll for new messages (use with setInterval) */
  pollMessages(intervalMs?: number): () => void;
}

export function createBroadcastClient(config: BroadcastClientConfig): BroadcastClient {
  const headers = async () => ({
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${await Promise.resolve(config.getAuthToken())}`,
    'x-product-id': config.productId,
    'x-platform': config.platform,
    'x-app-version': config.appVersion,
    'x-os-version': config.osVersion,
    ...(config.countryCode && { 'x-country-code': config.countryCode }),
    ...(config.regionCode && { 'x-region-code': config.regionCode }),
    'x-user-segments': (config.userSegments ?? ['free']).join(','),
  });

  const request = async <T>(path: string, options?: RequestInit): Promise<T> => {
    const res = await fetch(`${config.baseUrl}${path}`, {
      ...options,
      headers: {
        ...(await headers()),
        ...(options?.headers || {}),
      },
    });
    if (!res.ok) {
      const err = await res.text();
      throw new Error(`Broadcast API error: ${res.status} ${err}`);
    }
    return res.json() as Promise<T>;
  };

  let pollInterval: ReturnType<typeof setInterval> | null = null;

  return {
    async listMessages() {
      return request<{ messages: InAppMessage[] }>('/broadcasts');
    },

    async markRead(messageId: string) {
      await request<void>(`/broadcasts/${messageId}/read`, { method: 'POST' });
    },

    async markDismissed(messageId: string) {
      await request<void>(`/broadcasts/${messageId}/dismiss`, { method: 'POST' });
    },

    async trackClick(messageId: string) {
      return request<{ redirectUrl?: string }>(`/broadcasts/${messageId}/click`, {
        method: 'POST',
      });
    },

    pollMessages(intervalMs = 60000) {
      if (pollInterval) clearInterval(pollInterval);
      pollInterval = setInterval(() => {
        this.listMessages().catch(() => {});
      }, intervalMs);
      return () => {
        if (pollInterval) {
          clearInterval(pollInterval);
          pollInterval = null;
        }
      };
    },
  };
}

// =============================================================================
// React Hook (optional)
// =============================================================================

export function createUseBroadcast(client: BroadcastClient) {
  return function useBroadcast() {
    return { client };
  };
}

// =============================================================================
// Deep Link Router
// =============================================================================

export {
  DeepLinkRouter,
  deepLinkRouter,
  DeepLinkScreens,
  createBroadcastDeepLink,
  type DeepLinkRoute,
  type DeepLinkHandler,
} from './deep-link.js';

