import TRenderEngine from '@native-html/transient-render-engine';
import React, { PropsWithChildren, ReactElement } from 'react';
import { Platform } from 'react-native';
import useTRenderEngine from './hooks/useTRenderEngine';
import { TRenderEngineConfig } from './shared-types';
import defaultSystemFonts from './defaultSystemFonts';

const defaultTRenderEngine = {} as any;

const TRenderEngineContext = React.createContext<TRenderEngine>(defaultTRenderEngine);

/**
 * Default fallback font for special keys such as 'sans-serif', 'monospace',
 * 'serif', based on current platform.
 */
export const defaultFallbackFonts = {
  'sans-serif': Platform.select({ ios: 'system', default: 'sans-serif' }),
  monospace: Platform.select({ ios: 'Menlo', default: 'monospace' }),
  serif: Platform.select({ ios: 'Times New Roman', default: 'serif' }),
};

export const defaultTRenderEngineProviderProps: TRenderEngineConfig = {
  htmlParserOptions: {
    decodeEntities: true,
  },
  emSize: 14,
  ignoredDomTags: [],
  ignoredStyles: [],
  baseStyle: { fontSize: 14 },
  tagsStyles: {},
  classesStyles: {},
  enableUserAgentStyles: true,
  enableCSSInlineProcessing: true,
  customHTMLElementModels: {},
  fallbackFonts: defaultFallbackFonts,
  systemFonts: defaultSystemFonts,
};

/**
 * Use the ambient transient render engine.
 *
 * @returns The ambient transient render engine.
 *
 * @public
 */
export function useAmbientTRenderEngine() {
  const engine = React.useContext(TRenderEngineContext);
  if (typeof __DEV__ === 'boolean' && __DEV__ && engine === defaultTRenderEngine) {
    console.error('TRenderEngineProvider is missing in the render tree.');
  }
  return engine;
}

/**
 * A react component to share a {@link TRenderEngine} instance across different
 * rendered contents via {@link RenderHTMLSource}. This can significantly enhance
 * performance in applications with potentially dozens or hundreds of distinct
 * rendered snippets such as chat apps.
 *
 * @param props - Pass engine config here.
 */
export default function TRenderEngineProvider({
  children,
  ...config
}: PropsWithChildren<TRenderEngineConfig>): ReactElement {
  config = {
    ...defaultTRenderEngineProviderProps,
    ...config,
  };
  const engine = useTRenderEngine(config);
  return <TRenderEngineContext.Provider value={engine}>{children}</TRenderEngineContext.Provider>;
}
