import React, { lazy, Suspense } from 'react';

// Load html-react-parser and sanitize-html in a single async chunk.
// Neither library ships in the main bundle — they are only fetched when a
// component that uses this wrapper actually renders.
const SanitizedHtmlContent = lazy(() =>
  Promise.all([
    import(/* webpackChunkName: "html-parser" */ 'html-react-parser'),
    import(/* webpackChunkName: "html-parser" */ 'sanitize-html'),
  ]).then(([{ default: parse }, { default: sanitizeHtml }]) => ({
    default: function SanitizedHtmlContent({ html, sanitizeOptions, parseOptions }) {
      try {
        // sanitizeOptions can be a plain object or a factory (fn) that receives
        // the sanitizeHtml module so callers can reference sanitizeHtml.defaults.
        const resolvedSanitizeOptions =
          typeof sanitizeOptions === 'function'
            ? sanitizeOptions(sanitizeHtml)
            : sanitizeOptions;

        const sanitized = sanitizeHtml(html, resolvedSanitizeOptions);
        return parse(sanitized, parseOptions);
      } catch (error) {
        console.warn('LazySanitizedHtml: failed to parse HTML', error);
        return <span>{html}</span>;
      }
    },
  }))
);

/**
 * Renders sanitized and parsed HTML without including sanitize-html or
 * html-react-parser in the initial JavaScript bundle.
 *
 * @param {string}           html             Raw HTML string to sanitize and render
 * @param {object|function}  sanitizeOptions  sanitize-html options object, or a
 *                                            factory (sanitizeHtml) => options so
 *                                            callers can use sanitizeHtml.defaults
 * @param {object}           parseOptions     html-react-parser options (e.g. replace)
 * @param {React.ReactNode}  fallback         Shown while the libraries are loading
 */
export default function LazySanitizedHtml({ html, sanitizeOptions, parseOptions, fallback = null }) {
  if (!html) return null;
  return (
    <Suspense fallback={fallback}>
      <SanitizedHtmlContent
        html={html}
        sanitizeOptions={sanitizeOptions}
        parseOptions={parseOptions}
      />
    </Suspense>
  );
}
