<?php
/**
 * 2026 Paysera
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Academic Free License (AFL 3.0)
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://opensource.org/licenses/afl-3.0.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@prestashop.com so we can send you a copy immediately.
 *
 * @author Paysera <plugins@paysera.com>
 * @copyright 2026 Paysera
 * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
 * International Registered Trademark & Property of Paysera
 */

declare(strict_types=1);

namespace Paysera\PrestashopPayments\Service;

if (!defined('_PS_VERSION_')) {
    exit;
}

use Psr\Log\LoggerInterface;
use Symfony\Bridge\Twig\Extension\FormExtension;
use Twig\Environment;
use Twig\Loader\FilesystemLoader;

class TwigEnvironmentFactory
{
    private ?Environment $twig;

    public function __construct(
        private TwigExtensionRegistry $extensionRegistry,
        private LoggerInterface $logger,
        private string $modulePath
    ) {
        $this->twig = null;
    }

    public function create(): Environment
    {
        if ($this->twig !== null) {
            return $this->twig;
        }

        $twig = $this->createTwigEnvironment();
        $this->extensionRegistry->registerExtensions($twig);
        $this->twig = $twig;

        return $twig;
    }

    private function createTwigEnvironment(): Environment
    {
        $loader = $this->createLoader();
        $cacheDir = $this->getCacheDirectory();
        $this->ensureCacheDirectoryExists($cacheDir);

        return new Environment($loader, [
            'cache' => $cacheDir,
            'debug' => $this->isDebugMode(),
            'auto_reload' => $this->isDebugMode(),
        ]);
    }

    private function createLoader(): FilesystemLoader
    {
        $loader = new FilesystemLoader();
        $loader->addPath($this->modulePath . 'views/templates/hook');
        $loader->addPath($this->modulePath . 'views/templates/front');

        $formThemePath = dirname((new \ReflectionClass(FormExtension::class))->getFileName()) . '/../Resources/views/Form';
        if (is_dir($formThemePath)) {
            $loader->addPath($formThemePath);
        }

        return $loader;
    }

    private function getCacheDirectory(): string
    {
        if (defined('_PS_CACHE_DIR_')) {
            return _PS_CACHE_DIR_ . 'twig/';
        }

        return sys_get_temp_dir() . '/prestashop_twig_cache/';
    }

    private function ensureCacheDirectoryExists(string $cacheDir): void
    {
        if (!is_dir($cacheDir) && !@mkdir($cacheDir, 0755, true) && !is_dir($cacheDir)) {
            $this->logger->warning(sprintf('Failed to create cache directory: %s', $cacheDir));
            throw new \RuntimeException(sprintf('Unable to create cache directory: %s', $cacheDir));
        }
    }

    private function isDebugMode(): bool
    {
        return defined('_PS_MODE_DEV_') && _PS_MODE_DEV_;
    }
}
