/**
 * Deep Link Router — TypeScript
 * Handles routing from push notification deep links to app screens
 */

export interface DeepLinkRoute {
  screen: string;
  params?: Record<string, string>;
}

export type DeepLinkHandler = (route: DeepLinkRoute) => void;

/**
 * Deep Link Router class
 */
export class DeepLinkRouter {
  private handlers = new Map<string, DeepLinkHandler>();
  private fallbackHandler?: DeepLinkHandler;

  /**
   * Register a handler for a specific screen
   */
  register(screen: string, handler: DeepLinkHandler): void {
    this.handlers.set(screen, handler);
  }

  /**
   * Set a fallback handler for unregistered screens
   */
  setFallback(handler: DeepLinkHandler): void {
    this.fallbackHandler = handler;
  }

  /**
   * Parse a deep link URL and extract route
   */
  parseDeepLink(url: string): DeepLinkRoute | null {
    try {
      const urlObj = new URL(url);

      // Handle app-specific URLs: myapp://screen/params
      if (urlObj.protocol !== 'http:' && urlObj.protocol !== 'https:') {
        const routeParts = [urlObj.host, ...urlObj.pathname.split('/').filter(Boolean)].filter(
          Boolean
        );
        const screen = routeParts[0] || 'home';
        const params: Record<string, string> = {};

        // Parse query params
        urlObj.searchParams.forEach((value, key) => {
          params[key] = value;
        });

        return { screen, params };
      }

      // Handle web URLs with deep link params
      const deepLinkParam = urlObj.searchParams.get('dl');
      if (deepLinkParam) {
        return this.parseDeepLink(deepLinkParam);
      }

      // Handle path-based routing: /screen/params
      const pathParts = urlObj.pathname.split('/').filter(Boolean);
      if (pathParts.length > 0) {
        const screen = pathParts[0];
        const params: Record<string, string> = {};

        urlObj.searchParams.forEach((value, key) => {
          params[key] = value;
        });

        return { screen, params };
      }

      return null;
    } catch {
      return null;
    }
  }

  /**
   * Handle a deep link route
   */
  handle(route: DeepLinkRoute): boolean {
    const handler = this.handlers.get(route.screen);

    if (handler) {
      handler(route);
      return true;
    }

    if (this.fallbackHandler) {
      this.fallbackHandler(route);
      return true;
    }

    // eslint-disable-next-line no-console -- Deep-link consumers need an opt-in diagnostic when a route is dropped.
    console.warn(`[DeepLink] No handler for screen: ${route.screen}`);
    return false;
  }

  /**
   * Process a deep link URL end-to-end
   */
  process(url: string): boolean {
    const route = this.parseDeepLink(url);
    if (!route) {
      // eslint-disable-next-line no-console -- Parse failures are intentionally surfaced to host apps during integration.
      console.warn(`[DeepLink] Failed to parse: ${url}`);
      return false;
    }
    return this.handle(route);
  }
}

/**
 * Create a broadcast deep link URL
 */
export function createBroadcastDeepLink(
  baseUrl: string,
  screen: string,
  params?: Record<string, string>,
  broadcastId?: string
): string {
  const url = new URL(baseUrl);
  url.pathname = `/${screen}`;

  if (params) {
    Object.entries(params).forEach(([key, value]) => {
      url.searchParams.set(key, value);
    });
  }

  if (broadcastId) {
    url.searchParams.set('broadcastId', broadcastId);
  }

  return url.toString();
}

/**
 * Common deep link screens for broadcast/survey flows
 */
export const DeepLinkScreens = {
  // Broadcasts
  BROADCAST_DETAIL: 'broadcast',
  ANNOUNCEMENTS: 'announcements',

  // Surveys
  SURVEY: 'survey',
  SURVEY_LIST: 'surveys',

  // Product-specific (examples)
  SETTINGS: 'settings',
  PROFILE: 'profile',
  UPGRADE: 'upgrade',
  SUPPORT: 'support',

  // Fallback
  HOME: 'home',
} as const;

// Singleton instance for app-wide use
export const deepLinkRouter = new DeepLinkRouter();
