/**
 * React adapter for the chat widget
 *
 * Provides a React component wrapper around the Svelte widget.
 */

import { useEffect, useRef, useMemo } from 'react';
import { initChatWidget } from '../index.js';
import type { ChatWidgetConfig, PageContext, ChatWidgetAPI } from '../index.js';

export type { ChatWidgetConfig, PageContext };

// Extend React JSX to include custom element
declare module 'react' {
  namespace JSX {
    interface IntrinsicElements {
      'chat-widget': React.DetailedHTMLProps<
        React.HTMLAttributes<HTMLElement> & {
          'api-base': string;
          site: string;
          'site-name': string;
          title?: string;
          'logo-url'?: string;
          'primary-color'?: string;
          'welcome-message'?: string;
          'welcome-topics'?: string;
          'disclaimer-html'?: string;
          position?: 'bottom-right' | 'bottom-left';
          fullscreen?: boolean;
          'storage-prefix'?: string;
        },
        HTMLElement
      >;
    }
  }
}

export interface ChatWidgetProps extends ChatWidgetConfig {
  className?: string;
  style?: React.CSSProperties;
}

/**
 * React component wrapper for the chat widget
 *
 * The widget is initialized on mount and destroyed on unmount.
 * Config changes trigger a remount to apply new settings.
 */
export function ChatWidget(props: ChatWidgetProps) {
  const {
    className,
    style,
    ...config
  } = props;

  const containerRef = useRef<HTMLDivElement>(null);
  const widgetRef = useRef<ChatWidgetAPI | null>(null);

  // Memoize config to prevent unnecessary remounts
  // Only recreate when relevant config values change
  const memoizedConfig = useMemo(
    () => config,
    [
      config.apiBase,
      config.site,
      config.siteName,
      config.title,
      config.primaryColor,
      config.welcomeMessage,
      // Stringify arrays/objects for stable comparison
      JSON.stringify(config.welcomeTopics),
      config.disclaimerHtml,
      config.position,
      config.fullscreen,
      config.storagePrefix,
      config.logoUrl,
      config.sentryDsn,
      config.environment,
    ]
  );

  useEffect(() => {
    if (!containerRef.current) return;

    // Initialize widget
    widgetRef.current = initChatWidget(containerRef.current, memoizedConfig);

    return () => {
      // Cleanup: destroy widget to prevent memory leaks
      if (widgetRef.current) {
        widgetRef.current.destroy();
        widgetRef.current = null;
      }
    };
  }, [memoizedConfig]);

  return (
    <div
      ref={containerRef}
      className={className}
      style={style}
    />
  );
}

/**
 * Alternative: Use the custom element directly in React
 *
 * This is a simpler approach that doesn't require the Svelte mount API.
 */
export function ChatWidgetElement(props: ChatWidgetProps) {
  const {
    apiBase,
    site,
    siteName,
    title,
    logoUrl,
    primaryColor,
    welcomeMessage,
    welcomeTopics,
    disclaimerHtml,
    position,
    fullscreen,
    storagePrefix,
    className,
  } = props;

  // Import the index to ensure custom element is registered
  useEffect(() => {
    import('../index.js');
  }, []);

  return (
    <chat-widget
      api-base={apiBase}
      site={site}
      site-name={siteName}
      title={title}
      logo-url={logoUrl}
      primary-color={primaryColor}
      welcome-message={welcomeMessage}
      welcome-topics={welcomeTopics ? JSON.stringify(welcomeTopics) : undefined}
      disclaimer-html={disclaimerHtml}
      position={position}
      fullscreen={fullscreen}
      storage-prefix={storagePrefix}
      className={className}
    />
  );
}

export default ChatWidget;
