<?php

if (!class_exists('DependencyCheck')) {
  class DependencyCheck
  {
    public function checkDependencies()
    {
      $dependencies = [
        'php_version' => $this->checkPhpVersion(),
        'extensions' => $this->checkExtensions(),
        'permissions' => $this->checkPermissions(),
        'composer' => $this->checkComposer(),
        'database' => $this->checkDatabaseConnection()
      ];

      return $dependencies;
    }

    private function checkPhpVersion()
    {
      $requiredVersion = '7.4.0';
      $currentVersion = PHP_VERSION;

      return [
        'status' => version_compare($currentVersion, $requiredVersion, '>='),
        'required' => $requiredVersion,
        'current' => $currentVersion,
        'message' => version_compare($currentVersion, $requiredVersion, '>=')
          ? 'PHP version is compatible'
          : "PHP version $requiredVersion or higher is required"
      ];
    }

    private function checkExtensions()
    {
      $requiredExtensions = [
        'mysqli' => 'MySQL database support',
        'curl' => 'cURL for HTTP requests',
        'json' => 'JSON processing',
        'mbstring' => 'Multibyte string support',
        'openssl' => 'SSL/TLS support',
        'zip' => 'ZIP archive support'
      ];

      $extensions = [];
      foreach ($requiredExtensions as $ext => $description) {
        $extensions[$ext] = [
          'status' => extension_loaded($ext),
          'description' => $description,
          'message' => extension_loaded($ext)
            ? "$ext extension is loaded"
            : "$ext extension is missing"
        ];
      }

      return $extensions;
    }

    private function checkPermissions()
    {
      $directories = [
        'app/views' => 'Views directory',
        'vendor' => 'Vendor directory'
      ];

      $permissions = [];
      foreach ($directories as $path => $description) {
        $fullPath = realpath($path);
        $isWritable = is_writable($path);
        $isReadable = is_readable($path);

        $permissions[$path] = [
          'status' => $isWritable && $isReadable,
          'description' => $description,
          'writable' => $isWritable,
          'readable' => $isReadable,
          'message' => ($isWritable && $isReadable)
            ? "$description has proper permissions"
            : "$description needs read/write permissions"
        ];
      }

      return $permissions;
    }

    private function checkComposer()
    {
      $composerLock = file_exists('composer.lock');
      $vendorExists = is_dir('vendor');
      $autoloadExists = file_exists('vendor/autoload.php');

      return [
        'status' => $composerLock && $vendorExists && $autoloadExists,
        'composer_lock' => $composerLock,
        'vendor_dir' => $vendorExists,
        'autoload' => $autoloadExists,
        'message' => ($composerLock && $vendorExists && $autoloadExists)
          ? 'Composer dependencies are properly installed'
          : 'Please run "composer install" to install dependencies'
      ];
    }

    private function checkDatabaseConnection()
    {
      // Check if config file exists (check for both config.php.
      $config_file = '';
      if (file_exists('config.php')) {
        $config_file = 'config.php';
      } else {
        // No config file exists - this is expected during pre-installation
        return [
          'status' => true, // Mark as true since this is expected
          'message' => 'Database configuration will be set up during the installation process.',
          'configurable' => true
        ];
      }

      try {
        require_once $config_file;

        // Check if database constants are defined (support both formats)
        $host = '';
        $user = '';
        $pass = '';
        $name = '';
        
        if (defined('DB_HOST')) {
          $host = constant('DB_HOST');
          $user = defined('DB_USER') ? constant('DB_USER') : '';
          $pass = defined('DB_PASS') ? constant('DB_PASS') : '';
          $name = defined('DB_NAME') ? constant('DB_NAME') : '';
        } elseif (defined('MYSQL_HOST')) {
          $host = constant('MYSQL_HOST');
          $user = defined('MYSQL_USER') ? constant('MYSQL_USER') : '';
          $pass = defined('MYSQL_PASSWORD') ? constant('MYSQL_PASSWORD') : '';
          $name = defined('MYSQL_DATABASE') ? constant('MYSQL_DATABASE') : '';
        }
        
        if (empty($host) || empty($user) || empty($name)) {
          return [
            'status' => true, // Mark as true since this might be expected during setup
            'message' => 'Database configuration will be completed during installation.',
            'configurable' => true
          ];
        }

        // Test database connection
        $connection = new mysqli($host, $user, $pass, $name);

        if ($connection->connect_error) {
          return [
            'status' => false,
            'message' => 'Database connection failed: ' . $connection->connect_error,
            'configurable' => true
          ];
        }

        $connection->close();
        return [
          'status' => true,
          'message' => 'Database connection successful',
          'configurable' => false
        ];
      } catch (Exception $e) {
        // During pre-installation, database errors are expected
        return [
          'status' => true, // Mark as true since this is expected during pre-installation
          'message' => 'Database configuration will be set up during the installation process. Note: ' . $e->getMessage(),
          'configurable' => true
        ];
      }
    }


    public function displayCheck()
    {
      $dependencies = $this->checkDependencies();
      $allPassed = true;

      // Check if all dependencies pass
      if (!$dependencies['php_version']['status']) $allPassed = false;
      if (!$dependencies['composer']['status']) $allPassed = false;
      if (!$dependencies['database']['status']) $allPassed = false;

      foreach ($dependencies['extensions'] as $ext) {
        if (!$ext['status']) $allPassed = false;
      }

      foreach ($dependencies['permissions'] as $perm) {
        if (!$perm['status']) $allPassed = false;
      }

      // Include the view
      include 'app/views/dependency_check.php';
    }

    public function getStatusSummary()
    {
      try {
        $dependencies = $this->checkDependencies();

        $status = [
          'overall' => true,
          'php_ok' => $dependencies['php_version']['status'],
          'extensions_ok' => true,
          'permissions_ok' => true,
          'composer_ok' => $dependencies['composer']['status'],
          'database_ok' => $dependencies['database']['status']
        ];

        // Check extensions
        foreach ($dependencies['extensions'] as $ext) {
          if (!$ext['status']) {
            $status['extensions_ok'] = false;
            break;
          }
        }

        // Check permissions
        foreach ($dependencies['permissions'] as $perm) {
          if (!$perm['status']) {
            $status['permissions_ok'] = false;
            break;
          }
        }

        // Overall status - exclude database during pre-installation
        // Database check is not critical for pre-installation requirements
        $status['overall'] = $status['php_ok'] && $status['extensions_ok'] &&
          $status['permissions_ok'] && $status['composer_ok'];

        // Return JSON for AJAX requests
        if (isset($_GET['json'])) {
          header('Content-Type: application/json');
          echo json_encode($status);
          exit;
        }

        return $status;
        
      } catch (Exception $e) {
        // Handle errors gracefully
        $error_status = [
          'overall' => false,
          'php_ok' => false,
          'extensions_ok' => false,
          'permissions_ok' => false,
          'composer_ok' => false,
          'database_ok' => false,
          'error' => $e->getMessage()
        ];
        
        if (isset($_GET['json'])) {
          header('Content-Type: application/json');
          echo json_encode($error_status);
          exit;
        }
        
        return $error_status;
      }
    }
  }
}
