const path = require('path');
const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');

const projectRoot = __dirname;
const repoRoot = path.resolve(projectRoot, '..');
const localModules = path.resolve(projectRoot, 'node_modules');
const sdkLib = path.join(repoRoot, 'lib', 'module');

const escapeForRegex = (p) => p.replace(/[/\\]/g, '[/\\\\]');

/** 强制 App 与 link SDK 共用同一份 React / RN（避免 Invalid hook call） */
const forcedModules = {
  react: path.join(localModules, 'react'),
  'react-native': path.join(localModules, 'react-native'),
  'react/jsx-runtime': path.join(localModules, 'react/jsx-runtime'),
  'react/jsx-dev-runtime': path.join(localModules, 'react/jsx-dev-runtime'),
};

function resolveForced(moduleName) {
  if (forcedModules[moduleName]) {
    return {
      filePath: require.resolve(forcedModules[moduleName]),
      type: 'sourceFile',
    };
  }
  if (moduleName.startsWith('react/')) {
    return {
      filePath: require.resolve(path.join(localModules, moduleName)),
      type: 'sourceFile',
    };
  }
  return null;
}

/** @type {import('metro-config').MetroConfig} */
const config = {
  projectRoot,
  watchFolders: [repoRoot],
  resolver: {
    disableHierarchicalLookup: true,
    nodeModulesPaths: [localModules],
    extraNodeModules: {
      '@thinkup/react-native-sdk': sdkLib,
      ...forcedModules,
    },
    blockList: [
      new RegExp(`${escapeForRegex(path.join(repoRoot, 'node_modules'))}[/\\\\].*`),
      new RegExp(
        `${escapeForRegex(path.join(repoRoot, 'example', 'node_modules'))}[/\\\\].*`,
      ),
    ],
    resolveRequest: (context, moduleName, platform) => {
      const forced = resolveForced(moduleName);
      if (forced) {
        return forced;
      }
      if (moduleName === '@thinkup/react-native-sdk') {
        return {
          filePath: path.join(sdkLib, 'index.js'),
          type: 'sourceFile',
        };
      }
      return context.resolveRequest(context, moduleName, platform);
    },
  },
};

module.exports = mergeConfig(getDefaultConfig(projectRoot), config);
