<?php
/**
 * Akeeba Backup Restoration Script
 *
 * @package   brs
 * @copyright Copyright (c)2025 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license   GNU General Public License version 3, or later
 */

namespace Akeeba\BRS\Platform\Cli\Step;

defined('_AKEEBA') or die();

use Akeeba\BRS\Framework\Cli\AbstractInstallationStep;
use Akeeba\BRS\Framework\Cli\Exception\ExecutionException;
use Akeeba\BRS\Framework\Uri\Factory as UriFactory;

class Setup extends AbstractInstallationStep
{
	/** @inheritDoc */
	public function isApplicable(): bool
	{
		return true;
	}

	/** @inheritDoc */
	public function validate(): void
	{
		// TODO Refactor the Model so that validation is separate from execution.
	}

	/** @inheritDoc */
	public function execute(): void
	{
		$this->setURLsInHelper();

		$output = $this->getContainer()->get('output');

		$output->heading('Writing new configuration file');

		$model = $this->getContainer()->get('mvcFactory')->model('Setup');

		foreach ($this->configuration as $k => $v)
		{
			$model->setState($k, $v);
		}

		$writtenConfiguration = $model->applySettings();

		if (!$writtenConfiguration)
		{
			throw new ExecutionException('Could not write to the site configuration file.');
		}
	}

	protected function getDefaultConfiguration(): array
	{
		$configModel = $this->getContainer()->get('mvcFactory')->model('Configuration');

		return [
			'superuserid'             => 0,
			'superuseremail'          => null,
			'superuserpassword'       => null,
			'superuserpasswordrepeat' => null,
			'blogname'                => $configModel->get('blogname', 'Restored website'),
			'blogdescription'         => $configModel->get('blogdescription', 'Restored website'),
			'homeurl'                 => $configModel->get('homeurl', ''),
			'siteurl'                 => $configModel->get('siteurl', ''),
			'dbcharset'               => $configModel->get('dbcharset', 'utf8mb4'),
			'dbcollation'             => $configModel->get('dbcollation', ''),
			'removephpini'            => false,
			'removehtpasswd'          => false,
			'htaccessHandling'        => 'none',
			'disable_autoprepend'     => false,
		];
	}

	private function setURLsInHelper(): void
	{
		$homeUrl      = trim($this->configuration['homeurl'] ?? '' ?: '');
		$siteUrl      = trim($this->configuration['siteurl'] ?? '' ?: '');
		$normativeUrl = $homeUrl ?: $siteUrl;

		if (empty($normativeUrl))
		{
			throw new ExecutionException('You need to set the siteurl or homeurl in your config.yml.php file.');
		}

		$uriFactory   = $this->getContainer()->get('uri');
		$normativeUri = $uriFactory->instance($normativeUrl);
		$path         = rtrim($normativeUri->getPath(), '/');

		$root = [
			'prefix' => $normativeUri->toString(['scheme', 'host', 'port']),
			'path'   => $path,
		];

		$path .= '/installation';

		$base = [
			'prefix' => $normativeUri->toString(['scheme', 'host', 'port']),
			'path'   => $path . '/index.php',
		];

		$normativeUri->setPath($path);

		$isPHP83Plus = version_compare(PHP_VERSION, '8.3', 'ge');
		$refClass    = new \ReflectionClass(UriFactory::class);

		$refProp = $refClass->getProperty('instances');
		$refProp->setAccessible(true);
		$instances           = $refProp->getValue();
		$instances['SERVER'] = $normativeUri;

		if ($isPHP83Plus)
		{
			$refClass->setStaticPropertyValue('instances', $instances);
		}
		else
		{
			$refProp->setValue($instances);
		}

		$refProp = $refClass->getProperty('root');
		$refProp->setAccessible(true);

		if ($isPHP83Plus)
		{
			$refClass->setStaticPropertyValue('root', $root);
		}
		else
		{
			$refProp->setValue($root);
		}

		$refProp = $refClass->getProperty('base');
		$refProp->setAccessible(true);

		if ($isPHP83Plus)
		{
			$refClass->setStaticPropertyValue('base', $base);
		}
		else
		{
			$refProp->setValue($base);
		}
	}
}