function getDbDriver(dbType) {
  const type = dbType.toLowerCase();
  if (type.includes('postgres')) {
    return 'postgresql';
  } else if (type.includes('mariadb')) {
    return 'mariadb';
  }
  return 'mysql';
}

function buildTablePlusUrl(driver, dbConfig, connectionName) {
  const encodedUser = encodeURIComponent(dbConfig.user);
  const encodedPassword = encodeURIComponent(dbConfig.password);
  const encodedDatabase = encodeURIComponent(dbConfig.database);
  const encodedName = encodeURIComponent(connectionName);

  return `${driver}://${encodedUser}:${encodedPassword}@${dbConfig.host}:${dbConfig.port}/${encodedDatabase}?enviroment=local&name=${encodedName}&safeModeLevel=0&advancedSafeModeLevel=0`;
}

function getProjectServices(project) {
  const commonServices = ['all'];

  if (project.type === 'ddev') {
    commonServices.push('web', 'db');
  } else {
    commonServices.push('appserver', 'database');
  }

  if (project.services && project.services.length > 0) {
    project.services.forEach(service => {
      const serviceName = typeof service === 'object' ? service.name : service;
      if (!commonServices.includes(serviceName)) {
        commonServices.push(serviceName);
      }
    });
  }

  return commonServices;
}

function buildLogCommand(type, service) {
  let command;
  if (service === 'all') {
    command = type === 'ddev' ? 'ddev logs' : 'lando logs';
  } else {
    command = type === 'ddev' ? `ddev logs -s ${service}` : `lando logs -s ${service}`;
  }
  return command;
}

function buildSshCommand(type) {
  return type === 'ddev' ? 'ddev ssh' : 'lando ssh';
}

function generateSnapshotName() {
  const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5);
  return `snapshot-${timestamp}`;
}

function buildMailHogUrl(projectName) {
  return `http://${projectName}.ddev.site:8026`;
}

function filterUrls(urls, projectType) {
  if (projectType === 'ddev') {
    return urls;
  }
  return urls.filter(url => {
    return !url.startsWith('http://') && !url.includes('localhost');
  });
}

function formatMenuLabel(app) {
  const statusIcon = app.running ? '\u{1F7E2}' : '';
  const typeIcon = app.type === 'ddev' ? '\u{1F537}' : '\u{1F536}';
  const recipeLabel = app.recipe && app.recipe !== 'unknown' ? ` (${app.recipe})` : '';
  return `${statusIcon}${typeIcon} ${app.displayName || app.name}${recipeLabel}`;
}

function parseLandoRecipe(landoYmlContent) {
  const recipeMatch = landoYmlContent.match(/recipe:\s*(\w+)/);
  return recipeMatch ? recipeMatch[1] : null;
}

function parseLandoName(landoYmlContent) {
  const nameMatch = landoYmlContent.match(/name:\s*(.+)/);
  return nameMatch ? nameMatch[1].trim() : null;
}

function parseLandoDbType(landoYmlContent) {
  const dbMatch = landoYmlContent.match(/database:\s*\n\s*type:\s*([\w:\.]+)/);
  if (dbMatch) {
    const [dbType, dbVersion] = dbMatch[1].split(':');
    return { type: dbType, version: dbVersion || 'latest' };
  }
  return null;
}

function detectDbTypeFromService(serviceName) {
  if (serviceName.includes('mysql')) return 'mysql';
  if (serviceName.includes('mariadb')) return 'mariadb';
  if (serviceName.includes('postgres')) return 'postgres';
  return 'mysql'; // Lando default
}

// Well-known DDEV add-ons and their web UI ports/paths
const DDEV_ADDON_SERVICES = {
  'phpmyadmin': { label: 'phpMyAdmin', port: 8036, path: '/' },
  'adminer': { label: 'Adminer', port: 9100, path: '/' },
  'mailhog': { label: 'MailHog', port: 8026, path: '/' },
  'mailpit': { label: 'Mailpit', port: 8026, path: '/' },
  'redis-commander': { label: 'Redis Commander', port: 8081, path: '/' },
  'elasticsearch': { label: 'Elasticsearch', port: 9200, path: '/' },
  'solr': { label: 'Solr', port: 8983, path: '/solr/' },
  'memcached': { label: 'Memcached', port: null, path: null },
  'redis': { label: 'Redis', port: null, path: null },
  'varnish': { label: 'Varnish', port: null, path: null },
};

/**
 * Detect installed DDEV add-ons by scanning docker-compose files in .ddev directory.
 * Returns an array of { name, label, hasWebUI, port, path }.
 */
function detectDDEVAddons(ddevDir) {
  const fs = require('fs');
  const path = require('path');
  const addons = [];
  const seen = new Set();

  try {
    const items = fs.readdirSync(ddevDir);

    items.forEach(item => {
      // DDEV add-ons create docker-compose.*.yaml files
      const match = item.match(/^docker-compose\.(.+)\.yaml$/);
      if (match) {
        const addonName = match[1].toLowerCase();

        // Skip the main docker-compose file patterns
        if (addonName === 'override' || addonName === 'yaml') return;
        if (seen.has(addonName)) return;
        seen.add(addonName);

        const knownAddon = DDEV_ADDON_SERVICES[addonName];

        addons.push({
          name: addonName,
          label: knownAddon ? knownAddon.label : addonName.charAt(0).toUpperCase() + addonName.slice(1),
          hasWebUI: knownAddon ? knownAddon.port !== null : false,
          port: knownAddon ? knownAddon.port : null,
          path: knownAddon ? knownAddon.path : null,
        });
      }
    });
  } catch (error) {
    // .ddev directory not readable, skip
  }

  return addons;
}

/**
 * Build URL to access a DDEV add-on's web UI.
 */
function buildAddonUrl(projectName, addon) {
  if (!addon.hasWebUI || !addon.port) return null;
  return `http://${projectName}.ddev.site:${addon.port}${addon.path || '/'}`;
}

/**
 * Detect multisite configuration from DDEV config.
 * DDEV supports additional_hostnames and additional_fqdns in config.yaml.
 * Returns { hostnames: string[], fqdns: string[] }.
 */
function parseDDEVMultisiteConfig(ddevConfigYaml) {
  const yaml = require('js-yaml');

  try {
    const config = typeof ddevConfigYaml === 'string' ? yaml.load(ddevConfigYaml) : ddevConfigYaml;

    const hostnames = config.additional_hostnames || [];
    const fqdns = config.additional_fqdns || [];

    return { hostnames, fqdns };
  } catch (error) {
    return { hostnames: [], fqdns: [] };
  }
}

/**
 * Build all site URLs for a multisite DDEV project.
 * Returns array of { label, url } objects.
 */
function buildMultisiteUrls(projectName, multisiteConfig) {
  const sites = [];

  // Primary site
  sites.push({
    label: `${projectName}.ddev.site`,
    url: `https://${projectName}.ddev.site`
  });

  // Additional hostnames (get .ddev.site suffix)
  if (multisiteConfig.hostnames && multisiteConfig.hostnames.length > 0) {
    multisiteConfig.hostnames.forEach(hostname => {
      sites.push({
        label: `${hostname}.ddev.site`,
        url: `https://${hostname}.ddev.site`
      });
    });
  }

  // Additional FQDNs (used as-is)
  if (multisiteConfig.fqdns && multisiteConfig.fqdns.length > 0) {
    multisiteConfig.fqdns.forEach(fqdn => {
      sites.push({
        label: fqdn,
        url: `https://${fqdn}`
      });
    });
  }

  return sites;
}

module.exports = {
  getDbDriver,
  buildTablePlusUrl,
  getProjectServices,
  buildLogCommand,
  buildSshCommand,
  generateSnapshotName,
  buildMailHogUrl,
  filterUrls,
  formatMenuLabel,
  parseLandoRecipe,
  parseLandoName,
  parseLandoDbType,
  detectDbTypeFromService,
  DDEV_ADDON_SERVICES,
  detectDDEVAddons,
  buildAddonUrl,
  parseDDEVMultisiteConfig,
  buildMultisiteUrls
};
