const fs = require('fs');
const path = require('path');
const yaml = require('js-yaml');

const SKIP_DIRS = ['node_modules', '.git', 'vendor', 'dist', 'build', '.cache'];

function findLandoProjects(baseDir, depth = 0, maxDepth = 2) {
  const projects = [];

  if (depth > maxDepth) {
    return projects;
  }

  try {
    const items = fs.readdirSync(baseDir, { withFileTypes: true });

    items.forEach(item => {
      if (item.isDirectory()) {
        if (SKIP_DIRS.includes(item.name)) {
          return;
        }

        const projectPath = path.join(baseDir, item.name);
        const landoYmlPath = path.join(projectPath, '.lando.yml');

        if (fs.existsSync(landoYmlPath)) {
          try {
            const landoYml = fs.readFileSync(landoYmlPath, 'utf8');
            const nameMatch = landoYml.match(/name:\s*(.+)/);
            const appName = nameMatch ? nameMatch[1].trim() : item.name;

            projects.push({
              name: appName,
              displayName: item.name,
              dir: projectPath,
              type: 'lando'
            });
          } catch (error) {
            projects.push({
              name: item.name,
              displayName: item.name,
              dir: projectPath,
              type: 'lando'
            });
          }
        } else {
          const subProjects = findLandoProjects(projectPath, depth + 1, maxDepth);
          projects.push(...subProjects);
        }
      }
    });
  } catch (error) {
    // Directory not readable, skip
  }

  return projects;
}

function findDDEVProjects(baseDir, depth = 0, maxDepth = 2) {
  const projects = [];

  if (depth > maxDepth) {
    return projects;
  }

  try {
    const items = fs.readdirSync(baseDir, { withFileTypes: true });

    items.forEach(item => {
      if (item.isDirectory()) {
        if (SKIP_DIRS.includes(item.name)) {
          return;
        }

        const projectPath = path.join(baseDir, item.name);
        const ddevConfigPath = path.join(projectPath, '.ddev', 'config.yaml');

        if (fs.existsSync(ddevConfigPath)) {
          try {
            const ddevConfigYaml = fs.readFileSync(ddevConfigPath, 'utf8');
            const config = yaml.load(ddevConfigYaml);
            const appName = config.name || item.name;

            projects.push({
              name: appName,
              displayName: item.name,
              dir: projectPath,
              type: 'ddev'
            });
          } catch (error) {
            projects.push({
              name: item.name,
              displayName: item.name,
              dir: projectPath,
              type: 'ddev'
            });
          }
        } else {
          const subProjects = findDDEVProjects(projectPath, depth + 1, maxDepth);
          projects.push(...subProjects);
        }
      }
    });
  } catch (error) {
    // Directory not readable, skip
  }

  return projects;
}

function filterApps(appList, showLando, showDDEV) {
  return appList.filter(app => {
    if (app.type === 'lando' && !showLando) return false;
    if (app.type === 'ddev' && !showDDEV) return false;
    return true;
  });
}

function sortByName(a, b) {
  const nameA = (a.displayName || a.name).toLowerCase();
  const nameB = (b.displayName || b.name).toLowerCase();
  return nameA.localeCompare(nameB);
}

function normalizeLandoName(name) {
  return name.toLowerCase().replace(/[\s-]/g, '');
}

function mergeLandoProjects(runningContainers, scannedProjects) {
  const apps = {};

  runningContainers.forEach(container => {
    if (container.app !== '_global_' && container.src && container.src[0] && container.src[0] !== 'unknown') {
      const appName = container.app;
      if (!apps[appName]) {
        const landoYmlPath = container.src[0];
        const dir = path.dirname(landoYmlPath);
        const displayName = path.basename(dir);

        apps[appName] = {
          landoYmlPath,
          dir,
          displayName,
          running: container.running
        };
      }
    }
  });

  scannedProjects.forEach(project => {
    const normalizedName = normalizeLandoName(project.name);
    if (!apps[normalizedName]) {
      apps[normalizedName] = {
        landoYmlPath: path.join(project.dir, '.lando.yml'),
        dir: project.dir,
        displayName: project.displayName,
        running: false
      };
    }
  });

  return apps;
}

function mergeDDEVProjects(runningDDEVProjects, scannedDDEVProjects) {
  const apps = {};

  runningDDEVProjects.forEach(ddevProject => {
    const appName = ddevProject.name;
    if (appName) {
      apps[appName] = {
        name: appName,
        displayName: ddevProject.name,
        dir: ddevProject.approot || '',
        status: ddevProject.status || 'unknown',
        running: ddevProject.status === 'running',
        urls: ddevProject.primary_url ? [ddevProject.primary_url] : [],
        type: ddevProject.type || 'unknown'
      };
    }
  });

  scannedDDEVProjects.forEach(project => {
    if (!apps[project.name]) {
      apps[project.name] = {
        name: project.name,
        displayName: project.displayName,
        dir: project.dir,
        status: 'Stopped',
        running: false,
        urls: [],
        type: 'unknown'
      };
    }
  });

  return apps;
}

module.exports = {
  SKIP_DIRS,
  findLandoProjects,
  findDDEVProjects,
  filterApps,
  sortByName,
  normalizeLandoName,
  mergeLandoProjects,
  mergeDDEVProjects
};
