const fs = require('fs-extra');
const path = require('node:path');
const ignore = require('ignore');

// Central default ignore patterns for discovery and filtering.
// These complement .gitignore and are applied regardless of VCS presence.
const DEFAULT_PATTERNS = [
  // Project/VCS
  '**/.bmad-method/**',
  '**/.git/**',
  '**/.svn/**',
  '**/.hg/**',
  '**/.bzr/**',
  // Package/build outputs
  '**/node_modules/**',
  '**/bower_components/**',
  '**/vendor/**',
  '**/packages/**',
  '**/build/**',
  '**/dist/**',
  '**/out/**',
  '**/target/**',
  '**/bin/**',
  '**/obj/**',
  '**/release/**',
  '**/debug/**',
  // Environments
  '**/.venv/**',
  '**/venv/**',
  '**/.virtualenv/**',
  '**/virtualenv/**',
  '**/env/**',
  // Logs & coverage
  '**/*.log',
  '**/npm-debug.log*',
  '**/yarn-debug.log*',
  '**/yarn-error.log*',
  '**/lerna-debug.log*',
  '**/coverage/**',
  '**/.nyc_output/**',
  '**/.coverage/**',
  '**/test-results/**',
  // Caches & temp
  '**/.cache/**',
  '**/.tmp/**',
  '**/.temp/**',
  '**/tmp/**',
  '**/temp/**',
  '**/.sass-cache/**',
  // IDE/editor
  '**/.vscode/**',
  '**/.idea/**',
  '**/*.swp',
  '**/*.swo',
  '**/*~',
  '**/.project',
  '**/.classpath',
  '**/.settings/**',
  '**/*.sublime-project',
  '**/*.sublime-workspace',
  // Lockfiles
  '**/package-lock.json',
  '**/yarn.lock',
  '**/pnpm-lock.yaml',
  '**/composer.lock',
  '**/Pipfile.lock',
  // Python/Java/compiled artifacts
  '**/*.pyc',
  '**/*.pyo',
  '**/*.pyd',
  '**/__pycache__/**',
  '**/*.class',
  '**/*.jar',
  '**/*.war',
  '**/*.ear',
  '**/*.o',
  '**/*.so',
  '**/*.dll',
  '**/*.exe',
  // System junk
  '**/lib64/**',
  '**/.venv/lib64/**',
  '**/venv/lib64/**',
  '**/_site/**',
  '**/.jekyll-cache/**',
  '**/.jekyll-metadata',
  '**/.DS_Store',
  '**/.DS_Store?',
  '**/._*',
  '**/.Spotlight-V100/**',
  '**/.Trashes/**',
  '**/ehthumbs.db',
  '**/Thumbs.db',
  '**/desktop.ini',
  // XML outputs
  '**/flattened-codebase.xml',
  '**/repomix-output.xml',
  // Images, media, fonts, archives, docs, dylibs
  '**/*.jpg',
  '**/*.jpeg',
  '**/*.png',
  '**/*.gif',
  '**/*.bmp',
  '**/*.ico',
  '**/*.svg',
  '**/*.pdf',
  '**/*.doc',
  '**/*.docx',
  '**/*.xls',
  '**/*.xlsx',
  '**/*.ppt',
  '**/*.pptx',
  '**/*.zip',
  '**/*.tar',
  '**/*.gz',
  '**/*.rar',
  '**/*.7z',
  '**/*.dylib',
  '**/*.mp3',
  '**/*.mp4',
  '**/*.avi',
  '**/*.mov',
  '**/*.wav',
  '**/*.ttf',
  '**/*.otf',
  '**/*.woff',
  '**/*.woff2',
  // Env files
  '**/.env',
  '**/.env.*',
  '**/*.env',
  // Misc
  '**/junit.xml',
];

async function readIgnoreFile(filePath) {
  try {
    if (!(await fs.pathExists(filePath))) return [];
    const content = await fs.readFile(filePath, 'utf8');
    return content
      .split('\n')
      .map((l) => l.trim())
      .filter((l) => l && !l.startsWith('#'));
  } catch {
    return [];
  }
}

// Backward compatible export matching previous signature
async function parseGitignore(gitignorePath) {
  return readIgnoreFile(gitignorePath);
}

async function loadIgnore(rootDir, extraPatterns = []) {
  const ig = ignore();
  const gitignorePath = path.join(rootDir, '.gitignore');
  const patterns = [...(await readIgnoreFile(gitignorePath)), ...DEFAULT_PATTERNS, ...extraPatterns];
  // De-duplicate
  const unique = [...new Set(patterns.map(String))];
  ig.add(unique);

  // Include-only filter: return true if path should be included
  const filter = (relativePath) => !ig.ignores(relativePath.replaceAll('\\', '/'));

  return { ig, filter, patterns: unique };
}

module.exports = {
  DEFAULT_PATTERNS,
  parseGitignore,
  loadIgnore,
};
