import { listDirectory, readWorkspaceFile } from '@/lib/tauri-bridge';

const CODE_EXT = new Set(['.ts', '.tsx', '.js', '.jsx', '.py', '.go', '.rs', '.json']);

export interface WorkspaceMetadataTree {
  framework?: string;
  target_files: string[];
  symbols_extracted: number;
  dependency_graph?: {
    file_count: number;
    imports: Record<string, string[]>;
    entrypoints: string[];
  };
  files_matched: string[];
}

async function walkFiles(root: string, rel = '', depth = 0, max = 120): Promise<string[]> {
  if (depth > 4) return [];
  const dirPath = rel ? `${root}/${rel}`.replace(/\\/g, '/') : root;
  const entries = await listDirectory(dirPath, 200);
  const files: string[] = [];
  for (const entry of entries) {
    const path = rel ? `${rel}/${entry.name}` : entry.name;
    if (entry.isDir) {
      if (['node_modules', '.git', 'dist', 'build', '.next', 'target'].includes(entry.name)) continue;
      const nested = await walkFiles(root, path, depth + 1, max);
      files.push(...nested);
      if (files.length >= max) break;
    } else {
      const ext = entry.name.includes('.') ? `.${entry.name.split('.').pop()}` : '';
      if (CODE_EXT.has(ext)) files.push(path);
      if (files.length >= max) break;
    }
  }
  return files;
}

function detectFramework(pkg: Record<string, unknown>): string {
  const deps = {
    ...(pkg.dependencies as Record<string, string> | undefined),
    ...(pkg.devDependencies as Record<string, string> | undefined),
  };
  if (deps.next) return 'Next.js';
  if (deps.express) return 'Express';
  if (deps.vite || deps['@vitejs/plugin-react']) return 'Vite';
  if (deps.react) return 'React';
  return 'Unknown';
}

function extractImports(content: string, file: string): string[] {
  const imports: string[] = [];
  const ext = file.split('.').pop()?.toLowerCase();
  if (ext === 'py') {
    for (const m of content.matchAll(/^(?:from\s+(\S+)|import\s+(\S+))/gm)) {
      imports.push(m[1] || m[2] || '');
    }
  } else {
    for (const m of content.matchAll(/import\s+.*?\s+from\s+['"]([^'"]+)['"]/g)) {
      imports.push(m[1]);
    }
    for (const m of content.matchAll(/require\s*\(\s*['"]([^'"]+)['"]\s*\)/g)) {
      imports.push(m[1]);
    }
  }
  return imports.filter(Boolean).slice(0, 20);
}

/** Local metadata tree — no remote Hyper-Loop file access required. */
export async function scanLocalWorkspaceMetadata(
  workspaceRoot: string,
  userPrompt: string,
): Promise<WorkspaceMetadataTree> {
  const files = await walkFiles(workspaceRoot);
  const promptLower = userPrompt.toLowerCase();
  const matched = files.filter((f) => {
    const base = f.toLowerCase();
    return promptLower.split(/\W+/).some((w) => w.length > 3 && base.includes(w));
  });

  const targetFiles = matched.length ? matched.slice(0, 8) : files.slice(0, 8);
  const imports: Record<string, string[]> = {};
  let symbols = 0;

  for (const file of targetFiles.slice(0, 12)) {
    try {
      const content = await readWorkspaceFile(workspaceRoot, file);
      imports[file] = extractImports(content, file);
      symbols += (content.match(/\b(function|class|def|export|interface)\b/g) || []).length;
    } catch {
      // skip unreadable
    }
  }

  let framework = 'Unknown';
  try {
    const pkgRaw = await readWorkspaceFile(workspaceRoot, 'package.json');
    framework = detectFramework(JSON.parse(pkgRaw) as Record<string, unknown>);
  } catch {
    // no package.json
  }

  const entrypoints = files.filter((f) =>
    /^(src\/)?(main|index|app|server)\.(tsx?|jsx?|py)$/.test(f.replace(/\\/g, '/')),
  );

  return {
    framework,
    target_files: targetFiles,
    files_matched: matched,
    symbols_extracted: symbols,
    dependency_graph: {
      file_count: files.length,
      imports,
      entrypoints: entrypoints.slice(0, 6),
    },
  };
}
