/**
 * ESLint rule to enforce filename matches exported name
 * 
 * The filename (without extension) should match the exported name exactly.
 * For example: AdminDashboardPageQuery.ts should export AdminDashboardPageQuery
 */

module.exports = {
  meta: {
    type: 'problem',
    docs: {
      description: 'Enforce filename matches exported name',
      category: 'Best Practices',
      recommended: true,
    },
    fixable: null,
    schema: [],
    messages: {
      filenameMismatch: 'Filename "{{filename}}" should match exported name "{{exportName}}"',
      noMatchFound: 'No export found that matches filename "{{filename}}"',
    },
  },

  create(context) {
    const filename = context.getFilename();
    
    // Extract base filename without extension
    const baseName = filename.split('/').pop(); // Get last part of path
    const nameWithoutExt = baseName?.replace(/\.(ts|tsx|js|jsx)$/, '');
    
    // Skip test files, index files, and type definition files
    if (!nameWithoutExt || 
        nameWithoutExt.endsWith('.test') || 
        nameWithoutExt.endsWith('.spec') ||
        nameWithoutExt === 'index' ||
        nameWithoutExt.endsWith('.d')) {
      return {};
    }

    let exportedName = null;

    return {
      // Track named exports
      ExportNamedDeclaration(node) {
        if (node.declaration) {
          if (node.declaration.id) {
            exportedName = node.declaration.id.name;
          } else if (node.declaration.declarations) {
            // Multiple const exports - use the first one
            const first = node.declaration.declarations[0];
            if (first.id && first.id.name) {
              exportedName = first.id.name;
            }
          }
        } else if (node.specifiers && node.specifiers.length > 0) {
          // Re-exports - use the first one
          exportedName = node.specifiers[0].exported.name;
        }
      },

      // Track default exports
      ExportDefaultDeclaration(node) {
        if (node.declaration && node.declaration.id) {
          exportedName = node.declaration.id.name;
        } else {
          exportedName = 'default';
        }
      },

      'Program:exit'() {
        if (!exportedName) {
          // No export found - this might be okay for some files
          return;
        }

        if (exportedName === 'default') {
          // Default exports don't need to match filename
          return;
        }

        if (exportedName !== nameWithoutExt) {
          context.report({
            node: context.getSourceCode().ast,
            messageId: 'filenameMismatch',
            data: {
              filename: nameWithoutExt,
              exportName: exportedName,
            },
          });
        }
      },
    };
  },
};
