// Import the espree parser which is used by ESLint
import { parse } from 'espree';

/**
 * Helper function to check if a type is exported in an index file
 * @param {string} indexContent - Content of the index.ts file
 * @param {string} fileName - Name of the file
 * @returns {boolean} True if the type is exported
 */
export default function checkExportInIndexFile(indexContent, fileName) {
  try {
    const baseName = fileName.replace(/\.(ts|tsx)$/, '');
    const validContent = indexContent.replace(/type /g, '');
    // Check for AST-based export detection (more reliable)
    const ast = parse(validContent, {
      ecmaVersion: 2020,
      sourceType: 'module',
      ecmaFeatures: { jsx: true },
    });

    const listExportDeclarationType = ['ExportNamedDeclaration', 'ExportAllDeclaration', 'ExportDefaultDeclaration'];

    // Process all top-level statements and make sure the checking file is exported with source
    const exportDirect = ast.body.some(node => listExportDeclarationType.includes(node.type) && node?.source?.value === `./${baseName}`);

    if (exportDirect) {
      return true;
    } else {
      const exportsFromAST = [];
      ast.body.forEach(node => {
        if (node.type === 'ExportNamedDeclaration') {
          // Check for named exports without source. E.g: export { Alert, IAlertProps };
          // Each specifier is a named export
          if (node.specifiers) {
            node.specifiers.forEach(specifier => {
              if (specifier.exported && specifier.exported.name === baseName) {
                // Check if the export has a source which is defined in the same file
                const sourceNode = ast.body.find(n => n.type === 'ImportDeclaration' && n.source.value === `./${baseName}`);
                if (sourceNode && sourceNode.source.value === `./${baseName}`) {
                  exportsFromAST.push(baseName);
                }
              }
            });
          }
          // Check for variable declarations. E.g: export const Alert = lazy(() => import('./Alert'));
          if (node.declaration) {
            if (node.declaration.id && node.declaration.id.name === baseName) {
              exportsFromAST.push(baseName);
            } else if (node.declaration.declarations) {
              node.declaration.declarations.forEach(decl => {
                if (decl.id.name === baseName && decl?.init?.arguments?.find(a => a?.body?.source?.value === `./${baseName}`)) {
                  exportsFromAST.push(baseName);
                }
              });
            }
          }
        }
      });
      return exportsFromAST.includes(baseName);
    }
  } catch (e) {
    // If AST parsing fails, fall back to regex
    console.error('AST parsing failed, falling back to regex:', e);
  }
}
