/**
 * syntroReactPlugin — esbuild plugin for shared React via SynOS
 *
 * Replaces `import { useState } from 'react'` (and react-dom, jsx-runtime)
 * with lazy wrappers that resolve to SynOS.React / SynOS.ReactDOM at call
 * time. This means:
 *   - Adaptive modules load and self-register without React being available
 *   - React resolves when components actually render
 *   - The runtime SDK sets SynOS.React at module scope before any render
 *
 * Used by: build-cdn.js, build-adaptives-only.js, editor-sdk/build.js
 */
export const syntroReactPlugin = {
  name: 'syntro-react',
  setup(build) {
    build.onResolve({ filter: /^react(-dom)?(\/.*)?$/ }, (args) => ({
      path: args.path,
      namespace: 'syntro-react',
    }));

    build.onLoad({ filter: /.*/, namespace: 'syntro-react' }, (args) => {
      if (args.path === 'react/jsx-runtime' || args.path === 'react/jsx-dev-runtime') {
        return {
          contents: `
            function _R() {
              return (typeof SynOS !== 'undefined' && SynOS.React) || {};
            }
            function _jsx(type, props, key) {
              var R = _R();
              var p = props || {};
              var c = p.children;
              delete p.children;
              if (key !== undefined) p.key = key;
              return Array.isArray(c)
                ? R.createElement.apply(null, [type, p].concat(c))
                : c !== undefined
                  ? R.createElement(type, p, c)
                  : R.createElement(type, p);
            }
            export var jsx = _jsx;
            export var jsxs = _jsx;
            export var Fragment = _R().Fragment;
          `,
          loader: 'js',
        };
      }
      if (args.path === 'react') {
        // Hooks and creation APIs are lazy function wrappers — they resolve
        // SynOS.React at call time (during render), not at module load.
        //
        // Component types (Fragment, Suspense, etc.) are resolved at module
        // evaluation via _R(). This is fine because the runtime SDK always
        // loads before adaptive modules evaluate, so SynOS.React is set.
        // ES module named exports can't be truly lazy (no getter support).
        return {
          contents: `
            function _R() {
              return (typeof SynOS !== 'undefined' && SynOS.React) || {};
            }

            // Default export — lazy proxy for React.* access
            export default new Proxy({}, { get: function(_, k) { return _R()[k]; } });

            // Hooks — lazy function wrappers (resolve at call time)
            export function useState() { return _R().useState.apply(null, arguments); }
            export function useEffect() { return _R().useEffect.apply(null, arguments); }
            export function useMemo() { return _R().useMemo.apply(null, arguments); }
            export function useCallback() { return _R().useCallback.apply(null, arguments); }
            export function useRef() { return _R().useRef.apply(null, arguments); }
            export function useContext() { return _R().useContext.apply(null, arguments); }
            export function useReducer() { return _R().useReducer.apply(null, arguments); }
            export function useLayoutEffect() { return _R().useLayoutEffect.apply(null, arguments); }
            export function useId() { return _R().useId.apply(null, arguments); }
            export function useSyncExternalStore() { return _R().useSyncExternalStore.apply(null, arguments); }
            export function useDebugValue() { return _R().useDebugValue.apply(null, arguments); }
            export function useInsertionEffect() { return _R().useInsertionEffect.apply(null, arguments); }

            // Creation APIs — lazy function wrappers
            export function createElement() { return _R().createElement.apply(null, arguments); }
            export function createContext() { return _R().createContext.apply(null, arguments); }
            export function forwardRef() { return _R().forwardRef.apply(null, arguments); }
            export function memo() { return _R().memo.apply(null, arguments); }
            export function lazy() { return _R().lazy.apply(null, arguments); }
            export function isValidElement() { return _R().isValidElement.apply(null, arguments); }
            export function cloneElement() { return _R().cloneElement.apply(null, arguments); }

            // Component types — resolved at module eval (runtime loads first)
            var _r = _R();
            export var Fragment      = _r.Fragment;
            export var Suspense      = _r.Suspense;
            export var Children      = _r.Children;
            export var Component     = _r.Component;
            export var PureComponent = _r.PureComponent;
          `,
          loader: 'js',
        };
      }
      if (args.path === 'react-dom' || args.path.startsWith('react-dom/')) {
        return {
          contents: `
            function _RD() {
              return (typeof SynOS !== 'undefined' && SynOS.ReactDOM) || {};
            }
            export default new Proxy({}, { get: function(_, k) { return _RD()[k]; } });
            export function createRoot() { return _RD().createRoot.apply(null, arguments); }
            export function hydrateRoot() { return _RD().hydrateRoot.apply(null, arguments); }
            export function createPortal() { return _RD().createPortal.apply(null, arguments); }
            export function flushSync() { return _RD().flushSync.apply(null, arguments); }
          `,
          loader: 'js',
        };
      }
      return { contents: 'export default {};', loader: 'js' };
    });
  },
};
