import { Plugin } from 'vite';
import { readdir, readFile } from 'fs/promises';
import { join, resolve } from 'path';

interface ListenerInfo {
  eventName: string;
  importPath: string;
  fileName: string;
}

export function AutoRegistryEventsPlugin(): Plugin {
  return {
    name: 'AutoRegistryEventsPlugin',

    // Add configResolved hook to run earlier
    configResolved(config) {
      console.log('🔧 Config resolved, mode:', config.command);
    },

    // Add buildStart hook
    async buildStart() {
      console.log('🚀 BuildStart hook triggered');
      await generateRegistryFile();
    },

    // Add configureServer hook for dev mode
    configureServer(server) {
      console.log('🔧 Configure server hook triggered');
      // Generate registry file immediately for dev mode
      generateRegistryFile().catch(console.error);
    },

    // Add resolveId hook to handle the import
    resolveId(id, importer) {
      if (id === './auto-listeners-registry' && importer?.includes('src/index.ts')) {
        console.log('🔍 Resolving auto-listeners-registry import');
        const registryPath = resolve(process.cwd(), 'src/auto-listeners-registry.ts');
        return registryPath;
      }
    }
  };
}

async function generateRegistryFile() {
  console.log('🔍 Discovering event listeners...');

  // Generate the auto-registry file during build
  const listenersDir = resolve(process.cwd(), 'src/listeners');
  const listeners = await discoverListeners(listenersDir);

  console.log(`📦 Found ${listeners.length} event listeners`);

  // Generate the auto-registry file
  const registryCode = generateAutoRegistry(listeners);
  const registryPath = resolve(process.cwd(), 'src/auto-listeners-registry.ts');

  // Write the auto-registry file
  const fs = await import('fs/promises');
  await fs.writeFile(registryPath, registryCode);

  console.log('✅ Auto-registry file generated at:', registryPath);
}

async function discoverListeners(listenersDir: string): Promise<ListenerInfo[]> {
  const listeners: ListenerInfo[] = [];

  try {
    const files = await readdir(listenersDir);
    const tsFiles = files.filter(file => file.endsWith('.ts') && !file.endsWith('.d.ts'));

    for (const file of tsFiles) {
      const filePath = join(listenersDir, file);
      const content = await readFile(filePath, 'utf-8');

      // Check if it's a function-based listener
      const eventNameMatch = content.match(/export const eventName = (EcommerceEvents\.\w+);/);
      const hasDefaultExport = content.includes('export default (payload:');

      if (eventNameMatch && hasDefaultExport) {
        // Check if the default export function has meaningful logic
        if (hasActualLogic(content)) {
          const eventName = eventNameMatch[1];
          const importPath = `./listeners/${file.replace('.ts', '')}`;
          const fileName = file.replace('.ts', '');

          listeners.push({
            eventName,
            importPath,
            fileName
          });
        } else {
          console.log(`⏭️  Skipping listener ${file} - no meaningful logic detected`);
        }
      }
    }
  } catch (error) {
    console.warn('Warning: Could not discover listeners:', error);
  }

  return listeners;
}

/**
 * Check if the listener function contains meaningful logic beyond console.log and placeholder comments
 */
function hasActualLogic(content: string): boolean {
  // Extract the default export function body
  const defaultExportMatch = content.match(/export default \(payload:[^)]+\):[^{]*{([^}]*)}/s);
  if (!defaultExportMatch) {
    return false;
  }

  const functionBody = defaultExportMatch[1];

  // Remove comments and whitespace for analysis
  const cleanBody = functionBody
    .replace(/\/\/.*$/gm, '') // Remove single-line comments
    .replace(/\/\*[\s\S]*?\*\//g, '') // Remove multi-line comments
    .replace(/\s+/g, ' ') // Normalize whitespace
    .trim();

  // Check if the function body is empty after removing comments
  if (!cleanBody) {
    return false;
  }

  // Check if the only content is console.log statements
  const consoleLogRegex = /console\.(log|warn|error|info|debug)\s*\([^)]*\)\s*;?/g;
  const bodyWithoutConsoleLogs = cleanBody.replace(consoleLogRegex, '').trim();

  // If nothing remains after removing console.log statements, it's not meaningful logic
  if (!bodyWithoutConsoleLogs) {
    return false;
  }

  // Additional check for common placeholder patterns
  const placeholderPatterns = [
    /add\s+your\s+custom\s+tracking\s+logic\s+here/i,
    /todo/i,
    /implement\s+your\s+logic/i,
    /your\s+code\s+here/i
  ];

  // If the remaining content only contains placeholder text, it's not meaningful
  const hasOnlyPlaceholders = placeholderPatterns.some(pattern =>
    pattern.test(bodyWithoutConsoleLogs) && bodyWithoutConsoleLogs.replace(pattern, '').trim() === ''
  );

  return !hasOnlyPlaceholders;
}

function generateAutoRegistry(listeners: ListenerInfo[]): string {
  const toCamelCase = (str: string) => str.replace(/-([a-z])/g, (g) => g[1].toUpperCase());

  const imports = listeners.map(listener => {
    const camelCaseName = toCamelCase(listener.fileName);
    return `import ${camelCaseName}Handler, { eventName as ${camelCaseName}EventName } from '${listener.importPath}';`;
  }).join('\n');

  const registrations = listeners.map(listener => {
    const camelCaseName = toCamelCase(listener.fileName);
    return `listeners.set(${camelCaseName}EventName, ${camelCaseName}Handler);`;
  }).join('\n');

  return `// Auto-generated listeners registry - DO NOT EDIT MANUALLY
// This file is generated by the Vite listeners plugin

${imports}

const listeners: Map<string, (payload: any) => void> = new Map();

${registrations}

export { listeners };
`;
}