<?php

namespace KimaAI;

use KimaAI\Lib\AbstractMain;
use KimaAI\Surfaces\ClassesSurface;

use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;

defined('ABSPATH') || exit;

/**
 * Class Main.
 *
 * @property ClassesSurface $classes The classes surface.
 */
class Main extends AbstractMain {

  /**
   * The API namespace constant.
   *
   * @var string
   */
  public const API_V1_NAMESPACE = 'kimaai/v1';

  /**
   * The WP CLI namespace constant.
   *
   * @var string
   */
  public const WP_CLI_NAMESPACE = 'kimaai';

  /**
   * {@inheritDoc}
   */
  protected function getContainer(): ?ContainerInterface {
    $generated_dir = __DIR__ . '/Generated';

    $is_dev = $this->isDevelopment();

    // Determine if Pro is currently usable.
    $is_premium = false;
    if (\function_exists(__NAMESPACE__ . '\\kimaai_fs')) {
      $is_premium = kimaai_fs()->can_use_premium_code__premium_only();
    }

    // Use different cache IDs for free/pro and versioned per plugin version.
    $variant = $is_premium ? 'pro' : 'free';
    $cache_id = $variant . '_' . \KIMAAI_VERSION; // e.g. "pro_1.3.6"
    $safe_id = \preg_replace('/[^A-Za-z0-9_]/', '_', $cache_id);

    $container_class = 'ContainerKimaAI_' . $safe_id;
    $container_n_s = 'KimaAI\\Generated';
    $cache_file = $generated_dir . '/' . $container_class . '.php';
    $fqcn = $container_n_s . '\\' . $container_class;

    // In production: use compiled container if present.
    if (!$is_dev && is_readable($cache_file)) {
      require_once $cache_file;
      return new $fqcn();
    }

    // Build fresh container.
    $builder = new ContainerBuilder();

    $builder->setParameter('kimaai.plugin_file', \KIMAAI_PLUGIN_FILE);
    $builder->setParameter('kimaai.plugin_path', \KIMAAI_PLUGIN_PATH);
    $builder->setParameter('kimaai.plugin_url', \KIMAAI_PLUGIN_URL);
    $builder->setParameter('kimaai.version', \KIMAAI_VERSION);
    $builder->setParameter('kimaai.premium', $is_premium);

    // Core services.
    $loader = new PhpFileLoader($builder, new FileLocator(\KIMAAI_PLUGIN_PATH . 'app/Lib'));
    $loader->load('services.php');

    // Pro services only when premium is active.
    if ($is_premium) {
      $pro_lib_path = \KIMAAI_PLUGIN_PATH . 'premium/app/Lib';
      if (is_dir($pro_lib_path)) {
        $pro_loader = new PhpFileLoader($builder, new FileLocator($pro_lib_path));
        $pro_loader->load('services.php');
      }
    }

    // Compile with optimization.
    $builder->compile(true);

    // In dev: don't use the compiled cache at all, just return the in-memory container.
    if ($is_dev) {
      return $builder;
    }

    // In production: dump the compiled container for next requests.
    if (!is_dir($generated_dir)) {
      @mkdir($generated_dir, 0775, true); // phpcs:ignore
    }

    // phpcs:ignore
    if (is_writable($generated_dir)) {
      $dumper = new PhpDumper($builder);
      $code = $dumper->dump([
        'class' => $container_class,
        'namespace' => $container_n_s,
      ]);

      file_put_contents($cache_file, $code); // phpcs:ignore
      require_once $cache_file;
      return new $fqcn();
    }

    // Fallback when we can't write to disk.
    return $builder;
  }

  /**
   * {@inheritDoc}
   */
  protected function getName() {
    return 'kimaai';
  }

  /**
   * {@inheritDoc}
   */
  protected function getSurfaces() {
    $surfaces = [
      'classes' => ClassesSurface::class,
    ];

    // Only expose the pro surface if premium is enabled.
    if (
      function_exists(__NAMESPACE__ . '\\kimaai_fs')
      && kimaai_fs()->can_use_premium_code__premium_only()
    ) {
      $surfaces['pro'] = \KimaAI\Pro\Surfaces\ProSurface::class;
    }

    return $surfaces;
  }
}
