<?php

/**
 * Copyright 2024-2025 Simply.IN Sp. z o.o.
 *
 * NOTICE OF LICENSE
 *
 * Licensed under the EUPL-1.2 or later.
 * You may not use this work except in compliance with the Licence.
 *
 * Copy of the Licence is available at:
 * https://joinup.ec.europa.eu/software/page/eupl
 * It is bundled with this package in the file LICENSE.txt
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the Licence is distributed on an as is basis,
 * without warranties or conditions of any kind, either express or implied.
 * Check the Licence for the specific language governing permissions
 * and limitations under the License.
 *
 * @author   Simply.IN Sp. z o.o.
 * @copyright 2024-2025 Simply.IN Sp. z o.o.
 * @license   https://joinup.ec.europa.eu/software/page/eupl
 */

declare(strict_types=1);

namespace SimplyIn\BackOffice;

use Context;
use PrestaShop\PrestaShop\Adapter\SymfonyContainer;
use RuntimeException;
use Simplyin;
use SimplyIn\Form\DataProvider\SettingsDataProvider;
use Symfony\Component\Form\FormFactoryInterface;
use Tools;
use Twig\Environment;

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

final class ConfigurationScreen
{
    public function __construct(private readonly Simplyin $module)
    {
    }

    public function render(): string
    {
        $controller = $this->buildController();
        $result = $controller->process();
        $context = Context::getContext();

        $pageController = $context->controller;
        if ($pageController !== null) {
            foreach ($result['confirmations'] as $msg) {
                $pageController->confirmations[] = $msg;
            }
            foreach ($result['errors'] as $msg) {
                $pageController->errors[] = $msg;
            }
        }

        if (Tools::isSubmit('submitSimplyinModule') && $this->module->orderSyncService !== null) {
            $this->module->orderSyncService->refreshPending();
            $this->module->orderSyncService->synchronizePending();
        }

        $context->smarty->assign([
            'module_path' => _MODULE_DIR_ . $this->module->name . '/',
            // The intro copy links to "the merchant panel" to generate an API key — must be the
            // panel matching the currently selected environment, or Test would be told to
            // generate a key in the Production panel and vice versa.
            'merchant_panel_url' => (new ConfigurationRepository())->getEnvironment()->merchantPanelUrl(),
        ]);
        $output = $context->smarty->fetch(
            _PS_MODULE_DIR_ . $this->module->name . '/views/templates/admin/help.tpl',
        );

        return $output . $result['html'];
    }

    private function buildController(): ConfigurationController
    {
        $repository = new ConfigurationRepository();
        $dataProvider = new SettingsDataProvider($repository);

        $container = SymfonyContainer::getInstance();
        if ($container === null) {
            throw new RuntimeException('Symfony container is not available.');
        }

        // PS9 (Symfony 6.4) makes core "form.factory"/"twig" private in the compiled
        // container; the module publishes public aliases (see config/admin/services.yml).
        // Fall back to the core id for PS8, where those services are still public.
        /** @var FormFactoryInterface $formFactory */
        $formFactory = $container->has('simplyin.form_factory')
            ? $container->get('simplyin.form_factory')
            : $container->get('form.factory');
        /** @var Environment $twig */
        $twig = $container->has('simplyin.twig')
            ? $container->get('simplyin.twig')
            : $container->get('twig');

        return new ConfigurationController(
            $this->module,
            $repository,
            $dataProvider,
            $formFactory,
            $twig,
        );
    }
}
