const fs = require('fs');
const path = require('path');

class AssetCategoryManager {
  constructor(relPath = '.') {
    this.assetDir = path.resolve(__dirname, relPath);
    this.cache = new Map();
  }

  getCategory(softwareType) {
    if (!softwareType) {
      throw new Error('softwareType is required');
    }

    if (this.cache.has(softwareType)) {
      return this.cache.get(softwareType);
    }

    const filePath = path.resolve(this.assetDir, `${softwareType}.json`);
    if (!fs.existsSync(filePath)) {
      throw new Error(`Asset data '${softwareType}' not found in ${this.assetDir}`);
    }

    const raw = fs.readFileSync(filePath, 'utf8');
    const parsed = JSON.parse(raw);
    this.cache.set(softwareType, parsed);
    return parsed;
  }

  hasCategory(softwareType) {
    const filePath = path.resolve(this.assetDir, `${softwareType}.json`);
    return fs.existsSync(filePath);
  }

  listCategories({ withMeta = false } = {}) {
    const files = fs.readdirSync(this.assetDir, { withFileTypes: true });

    return files
      .filter(
        (entry) =>
          entry.isFile() &&
          entry.name.endsWith('.json') &&
          entry.name !== 'index.json' &&
          entry.name !== 'assetData.json'
      )
      .map((entry) => path.basename(entry.name, '.json'))
      .map((name) => {
        if (!withMeta) {
          return name;
        }

        const data = this.getCategory(name);
        return {
          softwareType: data.softwareType || name,
          label: data.label || name,
          file: `${name}.json`
        };
      });
  }

  searchCategories(query) {
    const term = (query || '').trim().toLowerCase();
    if (!term) {
      return [];
    }

    return this.listCategories({ withMeta: true }).filter(
      ({ softwareType, label }) =>
        softwareType.toLowerCase().includes(term) ||
        label.toLowerCase().includes(term)
    );
  }

  clearCache() {
    this.cache.clear();
  }
}

const assetCategoryManager = new AssetCategoryManager();

module.exports = {
  AssetCategoryManager,
  assetCategoryManager,
  getCategory: (softwareType) => assetCategoryManager.getCategory(softwareType),
  listCategories: (options) => assetCategoryManager.listCategories(options),
  searchCategories: (query) => assetCategoryManager.searchCategories(query),
  hasCategory: (softwareType) => assetCategoryManager.hasCategory(softwareType),
  clearCache: () => assetCategoryManager.clearCache()
};
