import React from 'react';
import { createRoot } from 'react-dom/client';
import { App } from './App';
import type { WidgetConfig } from './types';
import './styles.css';

// Declare the global config injected by the WordPress plugin. We keep the SAME
// window.AISTHETIX_CONFIG global the portable widget already reads.
declare global {
	interface Window {
		AISTHETIX_CONFIG?: WidgetConfig;
		// Set true by App once it has bound its click handler to the plugin's
		// trigger button, so bootstrap.js can replay a cold first click without
		// racing React's effect timing. See assets/bootstrap.js.
		AISTHETIX_WIDGET_READY?: boolean;
	}
}

// Some themes/builders (e.g. via SVG sprites) can cause React to create HTML
// elements in the SVG namespace, making them invisible. This patch forces known
// HTML tags to always use the HTML namespace.
const SVG_ONLY_TAGS = new Set( [
	'svg', 'g', 'path', 'circle', 'rect', 'line', 'polyline', 'polygon',
	'text', 'tspan', 'defs', 'clipPath', 'mask', 'pattern', 'use', 'symbol',
	'marker', 'linearGradient', 'radialGradient', 'stop', 'filter',
	'feGaussianBlur', 'feOffset', 'feMerge', 'feMergeNode', 'feBlend',
	'feColorMatrix', 'feComposite', 'feFlood', 'feImage', 'feMorphology',
	'feTurbulence', 'animate', 'animateTransform', 'foreignObject',
	'desc', 'title', 'metadata', 'image', 'switch', 'textPath',
	'altGlyph', 'altGlyphDef', 'altGlyphItem', 'glyph', 'glyphRef',
	'ellipse',
] );

const SVG_NS = 'http://www.w3.org/2000/svg';
const origCreateElementNS = document.createElementNS.bind( document );

document.createElementNS = function patchedCreateElementNS(
	namespaceURI: string,
	qualifiedName: string
) {
	if ( namespaceURI === SVG_NS && ! SVG_ONLY_TAGS.has( qualifiedName.toLowerCase() ) ) {
		return document.createElement( qualifiedName );
	}
	return origCreateElementNS( namespaceURI, qualifiedName );
} as typeof document.createElementNS;

let mounted = false;

function init() {
	if ( mounted ) {
		return;
	}

	const container = document.getElementById( 'aisthetix-widget-root' );
	if ( ! container ) {
		return;
	}

	const config = window.AISTHETIX_CONFIG;
	if ( ! config ) {
		// eslint-disable-next-line no-console
		console.warn( 'Aisthetix: configuration not found' );
		return;
	}

	if ( ! config.apiBaseUrl || ! config.publishableKey || ! config.productImage ) {
		// eslint-disable-next-line no-console
		console.error(
			'Aisthetix: missing required configuration (apiBaseUrl, publishableKey, productImage)'
		);
		return;
	}

	try {
		const root = createRoot( container );
		root.render(
			<React.StrictMode>
				<App config={ config } />
			</React.StrictMode>
		);
		mounted = true;
	} catch ( error ) {
		// eslint-disable-next-line no-console
		console.error( 'Aisthetix: failed to render widget', error );
	}
}

if ( document.readyState === 'loading' ) {
	document.addEventListener( 'DOMContentLoaded', init );
} else {
	init();
}
