import React from 'react';
import ReactDOM from 'react-dom';

export const prettyRenderState = (data, parentKey) => {
    if (data !== null && typeof data === 'object') {
        return (
            <ul>
                {Object.keys(data).map((key, index) => {
                    const dataKey = `${parentKey ? parentKey + '-' : ''}${key}`;
                    const value = data[key];

                    if (value === null) {
                        return null;
                    }

                    return (
                        <li
                            key={`state-render-${key}-${index}`}
                            id={`key-${key}`}
                        >
                            <span className="key">
                                <b>{key}</b>:
                            </span>
                            &nbsp;
                            {prettyRenderState(value, dataKey)}
                        </li>
                    );
                })}
            </ul>
        );
    }

    if (data === null) {
        return null;
    }

    const val = typeof data === 'object' ? JSON.stringify(data) : data;

    return (
        <span>
            <span id={`${parentKey}-${val}`} data-value={val} />
            <span id={parentKey} data-value={val}>
                {String(val)}
            </span>
        </span>
    );
};

export const prettyDebugRender = (state) => {
    return (
        <div>
            <div>
                <pre id="pre">{JSON.stringify(state, null, 2)}</pre>
            </div>
            <div>
                <div id="data">{prettyRenderState(state)}</div>
            </div>
        </div>
    );
};

export const deepMerge = (target, source) => {
    for (const key of Object.keys(source)) {
        if (source[key] instanceof Object) {
            source[key] = source[key] || {};
            target[key] = target[key] || {};
            Object.assign(source[key], deepMerge(target[key], source[key]));
        }
    }

    return Object.assign(target || {}, source);
};

export const ReactVersion = () => {
    return (
        <div>
            <h3>
                React version:{' '}
                <span id="react-version" data-version={React.version}>
                    {React.version}
                </span>
            </h3>
        </div>
    );
};

// Render a test fixtures in the DOM.
// Since react 19, ReactDOM.render is removed. Our test fixtures need to
// support running in multiple versions of React.
// We check if ReactDOM.render is available, if not we use the new API.
// We must dynamically import react-dom-19/client to avoid breaking the build
// in old versions. react-dom-19 must be a separate package in the package.json,
// otherwise when react-dom is aliased to an older version, the /client import
// will fail at build time.
export const renderFixture = (component) => {
    if (ReactDOM.render) {
        ReactDOM.render(component, document.getElementById('app'));
    } else {
        const ReactDOM19 = import('react-dom-19/client');
        ReactDOM19.then((ReactDOM) => {
            ReactDOM.createRoot(document.getElementById('app')).render(
                component,
            );
        });
    }
};
