<?php
declare(strict_types=1);

/**
 * Database bootstrap.
 *
 * Production secrets must be provided through MAVELA_DB_* environment
 * variables or an untracked config.local.php file. See config.local.example.php.
 */
$serverName = strtolower((string)($_SERVER['SERVER_NAME'] ?? $_SERVER['HTTP_HOST'] ?? php_uname('n')));
$serverName = preg_replace('/:\d+$/', '', $serverName) ?: $serverName;
$workspacePath = strtolower(str_replace('\\', '/', __DIR__));
$isLocalWorkspace = str_contains($workspacePath, '/xampp/htdocs/')
  || str_contains($workspacePath, '/wamp64/www/')
  || str_contains($workspacePath, '/laragon/www/');
$isLocalHost = $isLocalWorkspace
  || $serverName === ''
  || $serverName === 'localhost'
  || $serverName === '127.0.0.1'
  || $serverName === '::1'
  || str_ends_with($serverName, '.local')
  || str_ends_with($serverName, '.test');

$forcedEnv = strtolower(trim((string)getenv('MAVELA_APP_ENV')));
$appEnv = in_array($forcedEnv, ['local', 'production'], true)
  ? $forcedEnv
  : ($isLocalHost ? 'local' : 'production');

if (!defined('MAVELA_APP_ENV')) {
  define('MAVELA_APP_ENV', $appEnv);
}
if (!defined('MAVELA_IS_LOCAL')) {
  define('MAVELA_IS_LOCAL', $appEnv === 'local');
}

$localConfig = [];
$localConfigPath = __DIR__ . '/config.local.php';
if (is_file($localConfigPath)) {
  $loadedConfig = require $localConfigPath;
  if (!is_array($loadedConfig)) {
    throw new RuntimeException('config.local.php must return an array.');
  }
  $localConfig = $loadedConfig;
}

$configValue = static function (string $environmentName, string $localKey, ?string $default = null) use ($localConfig): ?string {
  $environmentValue = getenv($environmentName);
  if ($environmentValue !== false && trim((string)$environmentValue) !== '') {
    return (string)$environmentValue;
  }
  if (array_key_exists($localKey, $localConfig) && trim((string)$localConfig[$localKey]) !== '') {
    return (string)$localConfig[$localKey];
  }
  return $default;
};

$host = $configValue('MAVELA_DB_HOST', 'db_host', 'localhost');
$db = $configValue('MAVELA_DB_NAME', 'db_name', MAVELA_IS_LOCAL ? 'royafbmp_mavela_db' : null);
$user = $configValue('MAVELA_DB_USER', 'db_user', MAVELA_IS_LOCAL ? 'royafbmp_mavela' : null);
$pass = $configValue('MAVELA_DB_PASS', 'db_pass', MAVELA_IS_LOCAL ? 'Mavela@2026' : null);
$charset = 'utf8mb4';

if ($host === null || $db === null || $user === null || $pass === null) {
  error_log('Mavela configuration error: production database credentials are incomplete.');
  http_response_code(500);
  exit('The system is not configured yet. Add the database settings described in config.local.example.php.');
}

$dsn = "mysql:host={$host};dbname={$db};charset={$charset}";
$options = [
  PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
  PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
  PDO::ATTR_EMULATE_PREPARES => false,
  PDO::ATTR_STRINGIFY_FETCHES => false,
];

function try_start_local_mysql_server(string $host, string $user, string $pass, string $charset, array $options): bool {
  if (!MAVELA_IS_LOCAL || strtolower($host) !== 'localhost' || strtolower($user) !== 'root') {
    return false;
  }

  $candidateExecutables = [
    'C:/xampp/mysql/bin/mysqld.exe',
    'C:/xampp/mysql/bin/mariadbd.exe',
  ];

  foreach ($candidateExecutables as $executablePath) {
    if (!is_file($executablePath)) {
      continue;
    }

    $command = 'cmd /c start /b "" "' . str_replace('/', '\\', $executablePath) . '" --console > nul 2>&1';
    @shell_exec($command);

    for ($attempt = 0; $attempt < 8; $attempt++) {
      try {
        $probe = new PDO("mysql:host={$host};charset={$charset}", $user, $pass, $options);
        $probe = null;
        return true;
      } catch (PDOException $probeException) {
        usleep(500000);
      }
    }
  }

  return false;
}

try {
  $pdo = new PDO($dsn, $user, $pass, $options);
} catch (PDOException $e) {
  // A local XAMPP-style installation may create its first database automatically.
  if (MAVELA_IS_LOCAL && (int)$e->getCode() === 1049 && strtolower((string)$host) === 'localhost' && strtolower((string)$user) === 'root') {
    $bootstrap = new PDO("mysql:host={$host};charset={$charset}", $user, $pass, $options);
    $safeDatabaseName = str_replace('`', '``', (string)$db);
    $bootstrap->exec("CREATE DATABASE IF NOT EXISTS `{$safeDatabaseName}` CHARACTER SET {$charset} COLLATE utf8mb4_unicode_ci");
    $pdo = new PDO($dsn, $user, $pass, $options);
  } elseif (MAVELA_IS_LOCAL && in_array((int)$e->getCode(), [2002, 2003], true) && strtolower((string)$host) === 'localhost' && strtolower((string)$user) === 'root') {
    if (try_start_local_mysql_server($host, $user, $pass, $charset, $options)) {
      $pdo = new PDO($dsn, $user, $pass, $options);
    } else {
      error_log('Mavela database connection failed: ' . $e->getMessage());
      http_response_code(500);
      exit('The database connection is unavailable. Please start your local MySQL server and try again.');
    }
  } else {
    error_log('Mavela database connection failed: ' . $e->getMessage());
    http_response_code(500);
    exit('The database connection is unavailable. Please contact the system administrator.');
  }
}
