<?php
/**
 * Class Page
 *
 * @package Packetery\Options
 */

declare( strict_types=1 );

namespace Packetery\Module\Options;

use DateTime;
use Packetery\Core\Api;
use Packetery\Core\Api\Soap\Request\SenderGetReturnRouting;
use Packetery\Core\CoreHelper;
use Packetery\Core\Entity\PacketStatus;
use Packetery\Core\Log;
use Packetery\Latte\Engine;
use Packetery\Module\Dashboard\DashboardPage;
use Packetery\Module\DiagnosticsLogger\DiagnosticsLogger;
use Packetery\Module\FormFactory;
use Packetery\Module\Forms\BugReportForm;
use Packetery\Module\Forms\DiagnosticsLoggingFormFactory;
use Packetery\Module\Framework\WpAdapter;
use Packetery\Module\MessageManager;
use Packetery\Module\ModuleHelper;
use Packetery\Module\Order\PacketAutoSubmitter;
use Packetery\Module\Order\PacketSynchronizer;
use Packetery\Module\PaymentGatewayHelper;
use Packetery\Module\Views\UrlBuilder;
use Packetery\Module\WcLogger;
use Packetery\Nette\Forms\Container;
use Packetery\Nette\Forms\Controls\BaseControl;
use Packetery\Nette\Forms\Controls\SubmitButton;
use Packetery\Nette\Forms\Form;
use Packetery\Nette\Http;

/**
 * Class Page
 *
 * @package Packetery\Options
 */
class Page {

	private const FORM_FIELDS_CONTAINER               = 'packetery';
	private const FORM_FIELD_PACKETA_LABEL_FORMAT     = 'packeta_label_format';
	private const FORM_FIELD_CARRIER_LABEL_FORMAT     = 'carrier_label_format';
	private const FORM_FIELD_FREE_SHIPPING_SHOWN      = 'free_shipping_shown';
	public const FORM_PICKUP_POINT_VALIDATION_ENABLED = 'pickup_point_validation_enabled';

	public const ACTION_VALIDATE_SENDER = 'validate-sender';

	public const SLUG = 'packeta-options';

	public const TAB_GENERAL            = 'general';
	public const TAB_ADVANCED           = 'advanced';
	public const TAB_SUPPORT            = 'support';
	public const TAB_PACKET_STATUS_SYNC = 'packet-status-sync';
	public const TAB_AUTO_SUBMISSION    = 'auto-submission';

	public const PARAM_TAB = 'tab';

	const PACKETA_SVG_LOGO = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDI1LjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IlZyc3R2YV8xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4PSIwcHgiIHk9IjBweCIKCSB2aWV3Qm94PSIwIDAgMzcgNDAiIHN0eWxlPSJmaWxsOiNhN2FhYWQiIHhtbDpzcGFjZT0icHJlc2VydmUiPgo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoJLnN0MHtmaWxsLXJ1bGU6ZXZlbm9kZDtjbGlwLXJ1bGU6ZXZlbm9kZDtmaWxsOiAjYTdhYWFkO30KPC9zdHlsZT4KPHBhdGggY2xhc3M9InN0MCIgZD0iTTE5LjQsMTYuMWwtMC45LDAuNGwtMC45LTAuNGwtMTMtNi41bDYuMi0yLjRsMTMuNCw2LjVMMTkuNCwxNi4xeiBNMzIuNSw5LjZsLTQuNywyLjNsLTEzLjUtNmw0LjItMS42CglMMzIuNSw5LjZ6Ii8+CjxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik0xOSwwbDE3LjIsNi42bC0yLjQsMS45bC0xNS4yLTZMMy4yLDguNkwwLjgsNi42TDE4LDBMMTksMEwxOSwweiBNMzQuMSw5LjFsMi44LTEuMWwtMi4xLDE3LjZsLTAuNCwwLjgKCUwxOS40LDQwbC0wLjUtMy4xbDEzLjQtMTJMMzQuMSw5LjF6IE0yLjUsMjYuNWwtMC40LTAuOEwwLDguMWwyLjgsMS4xbDEuOSwxNS43bDEzLjQsMTJMMTcuNiw0MEwyLjUsMjYuNXoiLz4KPHBhdGggY2xhc3M9InN0MCIgZD0iTTI4LjIsMTIuNGw0LjMtMi43bC0xLjcsMTQuMkwxOC42LDM1bDAuNi0xN2w1LjQtMy4zTDI0LjMsMjNsMy4zLTIuM0wyOC4yLDEyLjR6Ii8+CjxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik0xNy43LDE3LjlsMC42LDE3bC0xMi4yLTExTDQuNCw5LjhMMTcuNywxNy45eiIvPgo8L3N2Zz4K';

	/**
	 * PacketeryLatte_engine.
	 *
	 * @var Engine PacketeryLatte engine.
	 */
	private $latteEngine;

	/**
	 * Options Provider
	 *
	 * @var OptionsProvider
	 */
	private $optionsProvider;

	/**
	 * Form factory.
	 *
	 * @var FormFactory Form factory.
	 */
	private $formFactory;

	/**
	 * Packeta client.
	 *
	 * @var Api\Soap\Client
	 */
	private $packetaClient;

	/**
	 * Logger
	 *
	 * @var Log\ILogger
	 */
	private $logger;

	/**
	 * Message manager.
	 *
	 * @var MessageManager
	 */
	private $messageManager;

	/**
	 * @var Http\Request
	 */
	private $httpRequest;

	/**
	 * @var ModuleHelper
	 */
	private $moduleHelper;

	/**
	 * @var UrlBuilder
	 */
	private $urlBuilder;

	/**
	 * @var PacketSynchronizer
	 */
	private $packetSynchronizer;

	/**
	 * @var WpAdapter
	 */
	private $wpAdapter;

	/**
	 * @var string
	 */
	private $supportEmailAddress;

	/**
	 * @var BugReportForm
	 */
	private $bugReportForm;

	/**
	 * @var DiagnosticsLoggingFormFactory
	 */
	private $diagnosticsLoggingFormFactory;

	/** @var DiagnosticsLogger  */
	private $diagnosticsLogger;

	public function __construct(
		Engine $latteEngine,
		OptionsProvider $optionsProvider,
		FormFactory $formFactory,
		Api\Soap\Client $packetaClient,
		Log\ILogger $logger,
		MessageManager $messageManager,
		Http\Request $httpRequest,
		ModuleHelper $moduleHelper,
		UrlBuilder $urlBuilder,
		PacketSynchronizer $packetSynchronizer,
		WpAdapter $wpAdapter,
		string $supportEmailAddress,
		BugReportForm $bugReportForm,
		DiagnosticsLoggingFormFactory $diagnosticsLoggingFormFactory,
		DiagnosticsLogger $diagnosticsLogger
	) {
		$this->latteEngine                   = $latteEngine;
		$this->optionsProvider               = $optionsProvider;
		$this->formFactory                   = $formFactory;
		$this->packetaClient                 = $packetaClient;
		$this->logger                        = $logger;
		$this->messageManager                = $messageManager;
		$this->httpRequest                   = $httpRequest;
		$this->moduleHelper                  = $moduleHelper;
		$this->urlBuilder                    = $urlBuilder;
		$this->packetSynchronizer            = $packetSynchronizer;
		$this->supportEmailAddress           = $supportEmailAddress;
		$this->wpAdapter                     = $wpAdapter;
		$this->bugReportForm                 = $bugReportForm;
		$this->diagnosticsLoggingFormFactory = $diagnosticsLoggingFormFactory;
		$this->diagnosticsLogger             = $diagnosticsLogger;
	}

	public function register(): void {
		add_action( 'admin_init', [ $this, 'admin_init' ] );
		add_action( 'admin_init', [ $this, 'processActions' ] );
		add_filter( 'custom_menu_order', '__return_true' );
		add_filter( 'menu_order', [ $this, 'customMenuOrder' ] );
	}

	public function registerMenuPage(): void {
		$this->wpAdapter->addMenuPage(
			$this->wpAdapter->__( 'Packeta', 'packeta' ),
			$this->wpAdapter->__( 'Packeta', 'packeta' ),
			'manage_options',
			DashboardPage::SLUG,
			function () {},
			self::PACKETA_SVG_LOGO
		);
	}

	public function registerSubmenuPage(): void {
		$this->wpAdapter->addSubmenuPage(
			DashboardPage::SLUG,
			$this->wpAdapter->__( 'Settings', 'packeta' ),
			$this->wpAdapter->__( 'Settings', 'packeta' ),
			'manage_options',
			self::SLUG,
			array(
				$this,
				'render',
			),
			1
		);
	}

	/**
	 * Returns menu_order with Packeta item in last position.
	 *
	 * @param array|mixed $menuOrder WP $menu_order.
	 *
	 * @return array|mixed
	 */
	public function customMenuOrder( $menuOrder ) {
		if ( ! is_array( $menuOrder ) ) {
			WcLogger::logArgumentTypeError( __METHOD__, 'menuOrder', 'array', $menuOrder );

			return $menuOrder;
		}

		$currentPosition = array_search( self::SLUG, $menuOrder, true );

		if ( $currentPosition !== false ) {
			unset( $menuOrder[ $currentPosition ] );
			$menuOrder[] = self::SLUG;
		}

		return $menuOrder;
	}

	/**
	 * Get chosen keys by hashed choice data.
	 *
	 * @param array $choiceData Choice data.
	 * @param array $chosenHashedFormOrderStatuses Picked items.
	 *
	 * @return array
	 */
	private function getChosenKeys( array $choiceData, array $chosenHashedFormOrderStatuses ): array {
		$statuses = [];
		foreach ( $chosenHashedFormOrderStatuses as $hash => $chosen ) {
			if ( $chosen ) {
				$statuses[] = $choiceData[ $hash ]['key'];
			}
		}

		return $statuses;
	}

	/**
	 * Translate hashes to packet status keys.
	 *
	 * @param array $choiceData Choice data.
	 * @param array $formData   Picked items.
	 *
	 * @return array
	 */
	private function translateStatuses( array $choiceData, array $formData ): array {
		$statuses = [];
		foreach ( $formData as $hash => $value ) {
			if ( $value ) {
				$statuses[ $choiceData[ $hash ]['key'] ] = $value;
			}
		}

		return $statuses;
	}

	/**
	 * Gets status syncing packet statuses.
	 *
	 * @return array<string, array{key: int|string, default: bool, label:string}>
	 */
	public function getStatusSyncingPacketStatusesChoiceData(): array {
		$statuses = $this->packetSynchronizer->getDefaultPacketStatuses();

		return $this->createPacketStatusChoiceData( $statuses );
	}

	/**
	 * Gets all packet statuses.
	 *
	 * @return array<string, array{key: int|string, default: bool, label:string}>
	 */
	public function getAllPacketStatusesChoiceData(): array {
		$statuses = $this->packetSynchronizer->getPacketStatuses();

		return $this->createPacketStatusChoiceData( $statuses );
	}

	/**
	 * @param PacketStatus[] $statuses Packet statuses.
	 *
	 * @return array<string, array{key: int|string, default: bool, label:string}>
	 */
	private function createPacketStatusChoiceData( array $statuses ): array {
		$result = [];

		foreach ( $statuses as $status => $statusEntity ) {
			$result[ md5( $status ) ] = [
				'key'     => $status,
				'default' => $statusEntity->hasDefaultSynchronization(),
				'label'   => $statusEntity->getTranslatedName(),
			];
		}

		return $result;
	}

	/**
	 * Gets order statuses for form.
	 *
	 * @return array<string, array<string, int|string>>
	 */
	public static function getOrderStatusesChoiceData(): array {
		$orderStatuses            = wc_get_order_statuses();
		$orderStatusesTransformed = [];

		foreach ( $orderStatuses as $orderStatusKey => $orderStatusLabel ) {
			$orderStatusesTransformed[ md5( $orderStatusKey ) ] = [
				'key'   => $orderStatusKey,
				'label' => $orderStatusLabel,
			];
		}

		return $orderStatusesTransformed;
	}

	/**
	 * Creates auto submission form.
	 *
	 * @return Form
	 */
	public function createAutoSubmissionForm(): Form {
		$gateways = PaymentGatewayHelper::getAvailablePaymentGateways();
		$form     = $this->formFactory->create( 'packetery_auto_submission_form' );
		$defaults = $this->optionsProvider->getOptionsByName( OptionNames::PACKETERY_AUTO_SUBMISSION );

		$form->addCheckbox( 'allow', __( 'Allow packet auto-submission', 'packeta' ) )
				->setRequired( false )
				->setDefaultValue( OptionsProvider::PACKET_AUTO_SUBMISSION_ALLOWED_DEFAULT );

		$eventChoices = [
			PacketAutoSubmitter::EVENT_ON_ORDER_CREATION_FE => __( 'On order creation at e-shop checkout', 'packeta' ),
			PacketAutoSubmitter::EVENT_ON_ORDER_PROCESSING => __( 'On order processing', 'packeta' ),
			PacketAutoSubmitter::EVENT_ON_ORDER_COMPLETED  => __( 'On order completed', 'packeta' ),
		];

		$paymentMethodEvents = $form->addContainer( 'payment_method_events' );
		foreach ( $gateways as $gateway ) {
			$paymentMethodEventsMethod = $paymentMethodEvents->addContainer(
				$this->optionsProvider->sanitizePaymentGatewayId( $gateway->id )
			);
			$paymentMethodEventsMethod->addSelect( 'event', $gateway->get_method_title(), $eventChoices )
				->setPrompt( __( 'Select event', 'packeta' ) )
				->checkDefaultValue( false );
		}

		$form->addSubmit( 'save', __( 'Save changes', 'packeta' ) );

		$form->setDefaults( $defaults );

		$form->onSuccess[] = [ $this, 'onAutoSubmissionFormSuccess' ];

		return $form;
	}

	/**
	 * On auto submission form success.
	 *
	 * @param Form  $form Form.
	 * @param array $values Form values.
	 *
	 * @return void
	 */
	public function onAutoSubmissionFormSuccess( Form $form, array $values ): void {
		update_option( OptionNames::PACKETERY_AUTO_SUBMISSION, $values );

		$this->messageManager->flash_message( __( 'Settings saved.', 'packeta' ), MessageManager::TYPE_SUCCESS, MessageManager::RENDERER_PACKETERY, 'plugin-options' );

		if ( wp_safe_redirect( $this->createLink( self::TAB_AUTO_SUBMISSION ) ) ) {
			exit;
		}
	}

	/**
	 * Creates settings form.
	 *
	 * @return Form
	 */
	private function createPacketStatusSyncForm(): Form {
		$form     = $this->formFactory->create( 'packetery_packet_status_sync_form' );
		$settings = $this->optionsProvider->getOptionsByName( OptionNames::PACKETERY_SYNC );

		$form->addText( 'max_status_syncing_packets', __( 'Number of orders synced during one cron call', 'packeta' ) )
				->setRequired( false )
				->addRule( Form::INTEGER )
				->addRule( Form::MIN, null, 0 )
				->setDefaultValue( OptionsProvider::MAX_STATUS_SYNCING_PACKETS_DEFAULT );

		$form->addText( 'max_days_of_packet_status_syncing', __( 'Number of days for which the order status is checked', 'packeta' ) )
				->setRequired( false )
				->addRule( Form::INTEGER )
				->addRule( Form::MIN, null, 0 )
				->setDefaultValue( OptionsProvider::MAX_DAYS_OF_PACKET_STATUS_SYNCING_DEFAULT );

		$orderStatusesTransformed = self::getOrderStatusesChoiceData();
		$orderStatusesContainer   = $form->addContainer( 'status_syncing_order_statuses' );

		foreach ( $orderStatusesTransformed as $orderStatusKeyHash => $orderStatusData ) {
			$item = $orderStatusesContainer->addCheckbox( $orderStatusKeyHash, $orderStatusData['label'] );
			if ( isset( $settings['status_syncing_order_statuses'] ) && in_array( $orderStatusData['key'], $settings['status_syncing_order_statuses'], true ) ) {
				$item->setDefaultValue( true );
			}
		}
		unset( $settings['status_syncing_order_statuses'] );

		$packetStatuses          = $this->getStatusSyncingPacketStatusesChoiceData();
		$packetStatusesContainer = $form->addContainer( 'status_syncing_packet_statuses' );

		foreach ( $packetStatuses as $packetStatusHash => $packetStatusData ) {
			$item = $packetStatusesContainer->addCheckbox( $packetStatusHash, $packetStatusData['label'] );
			if ( ! isset( $settings['status_syncing_packet_statuses'] ) ) {
				$item->setDefaultValue( $packetStatusData['default'] );
			} elseif ( in_array( $packetStatusData['key'], $settings['status_syncing_packet_statuses'], true ) ) {
				$item->setDefaultValue( true );
			}
		}
		unset( $settings['status_syncing_packet_statuses'] );

		$form->addCheckbox( 'allow_order_status_change', __( 'Allow order status change', 'packeta' ) )
			->setRequired( false )
			->setDefaultValue( false )
			->addCondition( Form::EQUAL, true )
			->toggle( '.order_status_change_content' );

		$orderStatusChangePacketStatuses = $form->addContainer( 'order_status_change_packet_statuses' );
		$orderStatuses                   = wc_get_order_statuses();
		$packetStatuses                  = $this->getAllPacketStatusesChoiceData();
		foreach ( $packetStatuses as $packetStatusHash => $packetStatusData ) {
			$item         = $orderStatusChangePacketStatuses->addSelect( $packetStatusHash, $packetStatusData['label'], $orderStatuses )
				->setPrompt( __( 'Order status', 'packeta' ) );
			$targetStatus = $settings['order_status_change_packet_statuses'][ $packetStatusData['key'] ] ?? null;
			if ( $targetStatus !== null && array_key_exists( $targetStatus, $orderStatuses ) ) {
				$item->setDefaultValue( $targetStatus );
			}
		}
		unset( $settings['order_status_change_packet_statuses'] );

		$form->setDefaults( $settings );

		$form->addSubmit( 'save', __( 'Save changes', 'packeta' ) );

		$form->onSuccess[] = [ $this, 'onPacketStatusSyncFormSuccess' ];

		return $form;
	}

	/**
	 * On packet status sync form success.
	 *
	 * @param Form  $form Form.
	 * @param array $values Values.
	 *
	 * @return void
	 */
	public function onPacketStatusSyncFormSuccess( Form $form, array $values ): void {
		$values['status_syncing_order_statuses']       = $this->getChosenKeys(
			self::getOrderStatusesChoiceData(),
			$values['status_syncing_order_statuses']
		);
		$values['status_syncing_packet_statuses']      = $this->getChosenKeys(
			$this->getStatusSyncingPacketStatusesChoiceData(),
			$values['status_syncing_packet_statuses']
		);
		$values['order_status_change_packet_statuses'] = $this->translateStatuses(
			$this->getAllPacketStatusesChoiceData(),
			$values['order_status_change_packet_statuses']
		);

		if ( $values['max_status_syncing_packets'] === '' ) {
			unset( $values['max_status_syncing_packets'] );
		}

		if ( $values['max_days_of_packet_status_syncing'] === '' ) {
			unset( $values['max_days_of_packet_status_syncing'] );
		}

		update_option( OptionNames::PACKETERY_SYNC, $values );

		$this->messageManager->flash_message( __( 'Settings saved.', 'packeta' ), MessageManager::TYPE_SUCCESS, MessageManager::RENDERER_PACKETERY, 'plugin-options' );

		if ( wp_safe_redirect( $this->createLink( self::TAB_PACKET_STATUS_SYNC ) ) ) {
			exit;
		}
	}

	public function createAdvancedForm(): Form {
		$form     = $this->formFactory->create( 'packetery_advanced_form' );
		$defaults = $this->optionsProvider->getOptionsByName( OptionNames::PACKETERY_ADVANCED );

		$form->addCheckbox( 'new_carrier_settings_enabled', __( 'Advanced carrier settings', 'packeta' ) )
			->setRequired( false )
			->setDefaultValue( OptionsProvider::DEFAULT_VALUE_CARRIER_SETTINGS );

		$form->addSubmit( 'save', __( 'Save changes', 'packeta' ) );

		$form->setDefaults( $defaults );

		$form->onSuccess[] = [ $this, 'onAdvancedFormSuccess' ];

		return $form;
	}

	public function onAdvancedFormSuccess( Form $form, array $values ): void {
		update_option( OptionNames::PACKETERY_ADVANCED, $values );

		$this->messageManager->flash_message( __( 'Settings saved.', 'packeta' ), MessageManager::TYPE_SUCCESS, MessageManager::RENDERER_PACKETERY, 'plugin-options' );

		if ( wp_safe_redirect( $this->createLink( self::TAB_ADVANCED ) ) ) {
			exit;
		}
	}

	/**
	 * Creates settings form.
	 *
	 * @return Form
	 */
	public function create_form(): Form {
		$form = $this->formFactory->create();
		$form->setAction( 'options.php' );

		$container = $form->addContainer( self::FORM_FIELDS_CONTAINER );
		$container->addText( 'api_password', __( 'API password', 'packeta' ) )
			->setRequired()
			->addRule( $form::PATTERN, __( 'API password must be 32 characters long and must contain valid characters!', 'packeta' ), '[a-z\d]{32}' );
		$container->addText( 'sender', __( 'Sender', 'packeta' ) )
			->setRequired();

		$packetaLabelFormats = $this->optionsProvider->getPacketaLabelFormats();
		$container->addSelect(
			self::FORM_FIELD_PACKETA_LABEL_FORMAT,
			__( 'Packeta Label Format', 'packeta' ),
			$packetaLabelFormats
		)->checkDefaultValue( false )->setDefaultValue( OptionsProvider::DEFAULT_VALUE_PACKETA_LABEL_FORMAT );

		$carrierLabelFormats = $this->optionsProvider->getCarrierLabelFormat();
		$container->addSelect(
			self::FORM_FIELD_CARRIER_LABEL_FORMAT,
			__( 'Carrier Label Format', 'packeta' ),
			$carrierLabelFormats
		)->checkDefaultValue( false )->setDefaultValue( OptionsProvider::DEFAULT_VALUE_CARRIER_LABEL_FORMAT );

		$gateways        = PaymentGatewayHelper::getAvailablePaymentGateways();
		$enabledGateways = [];
		foreach ( $gateways as $gateway ) {
			$enabledGateways[ $gateway->id ] = $gateway->get_method_title();
		}
		$container->addMultiSelect(
			'cod_payment_methods',
			__( 'Payment methods that represent cash on delivery', 'packeta' ),
			$enabledGateways
		)->checkDefaultValue( false );

		$container->addText( 'packaging_weight', __( 'Weight of packaging material', 'packeta' ) . ' (kg)' )
			->setRequired()
			->addRule( Form::FLOAT )
			->addRule( Form::MIN, null, 0 )
			->setDefaultValue( 0 );

		$container->addCheckbox( 'default_weight_enabled', __( 'Enable default weight', 'packeta' ) )
			->addCondition( Form::EQUAL, true )
				->toggle( '#packetery-default-weight-value' );

		$container->addText( 'default_weight', __( 'Default weight', 'packeta' ) . ' (kg)' )
			->addConditionOn( $form[ self::FORM_FIELDS_CONTAINER ]['default_weight_enabled'], Form::EQUAL, true )
				->setRequired()
				->addRule( Form::FLOAT )
				->addRule( Form::MIN, null, 0.1 );

		$container->addSelect(
			'dimensions_unit',
			__( 'Units used for dimensions', 'packeta' ),
			[
				OptionsProvider::DIMENSIONS_UNIT_CM => 'cm',
				OptionsProvider::DEFAULT_DIMENSIONS_UNIT_MM => 'mm',
			]
		)
		->setDefaultValue( $this->optionsProvider::DEFAULT_DIMENSIONS_UNIT_MM );

		$container->addCheckbox( 'default_dimensions_enabled', __( 'Enable default dimensions', 'packeta' ) )
			->addCondition( Form::EQUAL, true )
				->toggle( '#packetery-default-dimensions-value' );

		$container->addText( 'default_length', __( 'Length', 'packeta' ) )
			->addConditionOn( $form[ self::FORM_FIELDS_CONTAINER ]['default_dimensions_enabled'], Form::EQUAL, true )
				->setRequired()
			->addConditionOn( $form[ self::FORM_FIELDS_CONTAINER ]['dimensions_unit'], Form::EQUAL, $this->optionsProvider::DEFAULT_DIMENSIONS_UNIT_MM )
				->addRule( Form::INTEGER, __( 'Provide a full number!', 'packeta' ) )
				->addRule( Form::MIN, 'Value must be greater than 0', 1 )
			->elseCondition()
				->addRule( Form::FLOAT, __( 'Provide a decimal value!', 'packeta' ) )
				->addRule( Form::MIN, 'Value must be greater than 0', 0.1 )
			->endCondition();

		$container->addText( 'default_height', __( 'Height', 'packeta' ) )
			->addConditionOn( $form[ self::FORM_FIELDS_CONTAINER ]['default_dimensions_enabled'], Form::EQUAL, true )
				->setRequired()
			->addConditionOn( $form[ self::FORM_FIELDS_CONTAINER ]['dimensions_unit'], Form::EQUAL, $this->optionsProvider::DEFAULT_DIMENSIONS_UNIT_MM )
				->addRule( Form::INTEGER, __( 'Provide a full number!', 'packeta' ) )
				->addRule( Form::MIN, 'Value must be greater than 0', 1 )
			->elseCondition()
				->addRule( Form::FLOAT, __( 'Provide a decimal value!', 'packeta' ) )
				->addRule( Form::MIN, 'Value must be greater than 0', 0.1 )
			->endCondition();

		$container->addText( 'default_width', __( 'Width', 'packeta' ) )
			->addConditionOn( $form[ self::FORM_FIELDS_CONTAINER ]['default_dimensions_enabled'], Form::EQUAL, true )
				->setRequired()
			->addConditionOn( $form[ self::FORM_FIELDS_CONTAINER ]['dimensions_unit'], Form::EQUAL, $this->optionsProvider::DEFAULT_DIMENSIONS_UNIT_MM )
				->addRule( Form::INTEGER, __( 'Provide a full number!', 'packeta' ) )
				->addRule( Form::MIN, 'Value must be greater than 0', 1 )
			->elseCondition()
				->addRule( Form::FLOAT, __( 'Provide a decimal value!', 'packeta' ) )
				->addRule( Form::MIN, 'Value must be greater than 0', 0.1 )
			->endCondition();

		$container->addCheckbox( 'replace_shipping_address_with_pickup_point_address', __( 'Replace shipping address with pickup point address', 'packeta' ) )
			->setRequired( false );

		$container->addSelect(
			'checkout_detection',
			__( 'Force checkout type', 'packeta' ),
			[
				OptionsProvider::AUTOMATIC_CHECKOUT_DETECTION => __( 'Automatic detection', 'packeta' ),
				OptionsProvider::CLASSIC_CHECKOUT_DETECTION => __( 'Classic checkout', 'packeta' ),
				OptionsProvider::BLOCK_CHECKOUT_DETECTION => __( 'Block-based checkout', 'packeta' ),
			]
		);

		$container->addSelect(
			'checkout_widget_button_location',
			__( 'Widget button location in checkout', 'packeta' ),
			[
				'after_shipping_rate'     => __( 'After shipping rate', 'packeta' ),
				'after_transport_methods' => __( 'After transport methods', 'packeta' ),
			]
		);

		$container->addCheckbox( 'hide_checkout_logo', __( 'Hide Packeta checkout logo', 'packeta' ) )
			->setRequired( false )
			->setDefaultValue( OptionsProvider::HIDE_CHECKOUT_LOGO_DEFAULT );

		$container->addCheckbox( 'auto_email_info_insertion', __( 'Automatically insert packet and pickup point information into emails', 'packeta' ) )
			->setRequired( false )
			->setDefaultValue( OptionsProvider::AUTO_EMAIL_INFO_INSERTION_DEFAULT )
			->addCondition( Form::EQUAL, true )
				->toggle( '#packetery-email-hook' );

		$container->addSelect(
			'email_hook',
			__( 'Hook used to view information in email', 'packeta' ),
			[
				'woocommerce_email_footer'             => 'woocommerce_email_footer',
				'woocommerce_email_before_order_table' => 'woocommerce_email_before_order_table',
				'woocommerce_email_after_order_table'  => 'woocommerce_email_after_order_table',
				'woocommerce_email_order_meta'         => 'woocommerce_email_order_meta',
			]
		);

		$container->addCheckbox( 'force_packet_cancel', __( 'Force order cancellation', 'packeta' ) )
			->setRequired( false )
			->setDefaultValue( OptionsProvider::FORCE_PACKET_CANCEL_DEFAULT );

		$container->addCheckbox( 'widget_auto_open', __( 'Automatically open widget when shipping was selected', 'packeta' ) )
			->setRequired( false )
			->setDefaultValue( OptionsProvider::WIDGET_AUTO_OPEN_DEFAULT );

		$container->addCheckbox( self::FORM_FIELD_FREE_SHIPPING_SHOWN, __( 'Display the FREE shipping text in checkout', 'packeta' ) )
			->setRequired( false )
			->setDefaultValue( OptionsProvider::DISPLAY_FREE_SHIPPING_IN_CHECKOUT_DEFAULT );

		$container->addCheckbox( 'prices_include_tax', __( 'Prices include tax', 'packeta' ) )
			->setRequired( false )
			->setDefaultValue( OptionsProvider::PRICES_INCLUDE_TAX_DEFAULT );

		$container->addCheckbox( self::FORM_PICKUP_POINT_VALIDATION_ENABLED, __( 'Validate the pickup point using the API before accepting the order', 'packeta' ) )
			->setRequired( false )
			->setDefaultValue( OptionsProvider::PICKUP_POINT_VALIDATION_ENABLED_DEFAULT );

		$form->addSubmit( 'save', __( 'Save changes', 'packeta' ) );

		if ( $this->optionsProvider->has_any( OptionNames::PACKETERY ) ) {
			$container->setDefaults( $this->optionsProvider->getOptionsByName( OptionNames::PACKETERY ) );
		}

		return $form;
	}

	/**
	 *  Admin_init callback.
	 */
	public function admin_init(): void {
		add_filter( 'pre_update_option_packetery', [ $this, 'validatePacketeryOptions' ] );

		// Registered callback is called when the form is submitted.
		register_setting( self::FORM_FIELDS_CONTAINER, self::FORM_FIELDS_CONTAINER, [ $this, 'sanitizePacketeryOptions' ] );

		add_settings_section( 'packetery_main', __( 'Main Settings', 'packeta' ), function () {}, self::SLUG );
	}

	/**
	 * Validates packetery options.
	 *
	 * @param array $options Options to be validated.
	 *
	 * @return array
	 */
	public function validatePacketeryOptions( array $options ): array {
		$form = $this->create_form();
		/**
		 * Packetery container.
		 *
		 * @var Container $packeteryContainer
		 */
		$packeteryContainer = $form[ self::FORM_FIELDS_CONTAINER ];
		$packeteryContainer->setValues( $options );
		if ( $form->isValid() === false ) {
			foreach ( $packeteryContainer->getControls() as $control ) {
				if ( $control->hasErrors() === false ) {
					continue;
				}

				add_settings_error( OptionNames::PACKETERY, esc_attr( $control->getName() ), "{$control->getCaption()}: {$control->getError()}" );
			}
		}

		$apiPassword = $packeteryContainer['api_password'];
		if ( $apiPassword instanceof BaseControl && $apiPassword->hasErrors() === false ) {
			$this->packetaClient->setApiPassword( $apiPassword->getValue() );
		}

		$this->validateSender( $options['sender'] );

		return $options;
	}

	/**
	 * Sanitize options.
	 *
	 * @param array $options Options to be sanitized.
	 *
	 * @return array
	 */
	public function sanitizePacketeryOptions( array $options ): array {
		$form = $this->create_form();
		/**
		 * Packetery container.
		 *
		 * @var Container $packeteryContainer
		 */
		$packeteryContainer = $form[ self::FORM_FIELDS_CONTAINER ];
		if ( ! isset( $options['auto_email_info_insertion'] ) ) {
			$options['auto_email_info_insertion'] = false;
		}
		$packeteryContainer->setValues( $options );
		if ( $form->isValid() === false ) {
			foreach ( $packeteryContainer->getControls() as $control ) {
				if ( $control->hasErrors() === false ) {
					continue;
				}

				$options[ $control->getName() ] = '';
			}
		}

		$apiPassword = $packeteryContainer['api_password'];

		if ( $apiPassword instanceof BaseControl && $apiPassword->hasErrors() === false ) {
			$apiPass            = $apiPassword->getValue();
			$options['api_key'] = substr( $apiPass, 0, 16 );
			$this->packetaClient->setApiPassword( $apiPass );
		} else {
			$options['api_key'] = '';
		}

		if ( $packeteryContainer['default_weight'] instanceof BaseControl ) {
			$defaultWeight             = $packeteryContainer['default_weight']->getValue();
			$options['default_weight'] = is_numeric( $defaultWeight ) ? CoreHelper::trimDecimalPlaces( (float) $defaultWeight, 3 ) : $defaultWeight;
		}

		foreach ( [ 'default_length', 'default_width', 'default_height' ] as $dimension ) {
			if ( $packeteryContainer[ $dimension ] instanceof BaseControl ) {
				$options[ $dimension ] = is_numeric( $packeteryContainer[ $dimension ]->getValue() )
					? CoreHelper::trimDecimalPlaces( (float) $packeteryContainer[ $dimension ]->getValue(), 1 )
					: $packeteryContainer[ $dimension ]->getValue();
			}
		}

		if ( $packeteryContainer['force_packet_cancel'] instanceof BaseControl ) {
			$options['force_packet_cancel'] = (int) $packeteryContainer['force_packet_cancel']->getValue();
		}

		if ( $packeteryContainer['free_shipping_shown'] instanceof BaseControl ) {
			$options['free_shipping_shown'] = (int) $packeteryContainer['free_shipping_shown']->getValue();
		}

		$previousOptions = $this->optionsProvider->getOptionsByName( OptionNames::PACKETERY );
		if ( ! isset( $options['default_weight_enabled'] ) ) {
			if ( isset( $previousOptions['default_weight'] ) ) {
				$options['default_weight'] = $previousOptions['default_weight'];
			} else {
				unset( $options['default_weight'] );
			}
		}
		if ( ! isset( $options['default_dimensions_enabled'] ) ) {
			foreach ( [ 'default_length', 'default_width', 'default_height' ] as $dimension ) {
				if ( isset( $previousOptions[ $dimension ] ) ) {
					$options[ $dimension ] = $previousOptions[ $dimension ];
				} else {
					unset( $options[ $dimension ] );
				}
			}
		}

		if ( $options['api_key'] === '' ) {
			$options[ self::FORM_PICKUP_POINT_VALIDATION_ENABLED ] = false;
		}

		return $options;
	}

	/**
	 * Validates sender.
	 *
	 * @param string $senderLabel Sender label.
	 *
	 * @return bool|null
	 */
	private function validateSender( string $senderLabel ): ?bool {
		$senderValidationRequest  = new SenderGetReturnRouting( $senderLabel );
		$senderValidationResponse = $this->packetaClient->senderGetReturnRouting( $senderValidationRequest );

		$senderValidationLog         = new Log\Record();
		$senderValidationLog->action = Log\Record::ACTION_SENDER_VALIDATION;

		$senderValidationLog->status = Log\Record::STATUS_SUCCESS;
		$senderValidationLog->title  = __( 'Sender validation was successful', 'packeta' );

		if ( $senderValidationResponse->hasFault() ) {
			$senderValidationLog->status = Log\Record::STATUS_ERROR;
			$senderValidationLog->params = [
				'errorMessage' => $senderValidationResponse->getFaultString(),
			];
			$senderValidationLog->title  = __( 'Sender could not be validated', 'packeta' );
		}

		$this->logger->add( $senderValidationLog );

		$senderExists = $senderValidationResponse->senderExists();

		if ( $senderExists === false ) {
			$this->messageManager->flash_message( __( 'Specified sender does not exist', 'packeta' ), MessageManager::TYPE_INFO, MessageManager::RENDERER_PACKETERY, 'plugin-options' );
		}

		if ( $senderExists === null ) {
			$this->messageManager->flash_message( __( 'Unable to check specified sender', 'packeta' ), MessageManager::TYPE_INFO, MessageManager::RENDERER_PACKETERY, 'plugin-options' );
		}

		return $senderExists;
	}

	/**
	 * Process actions.
	 *
	 * @return void
	 */
	public function processActions(): void {
		$action = $this->httpRequest->getQuery( 'action' );
		if ( $action === self::ACTION_VALIDATE_SENDER ) {
			$result = $this->validateSender( $this->optionsProvider->get_sender() );

			if ( $result === true ) {
				$this->messageManager->flash_message( __( 'Specified sender has been validated.', 'packeta' ), MessageManager::TYPE_SUCCESS, MessageManager::RENDERER_PACKETERY, 'plugin-options' );
			}

			$doRedirect = wp_safe_redirect(
				add_query_arg(
					[
						'page' => self::SLUG,
					],
					get_admin_url( null, 'admin.php' )
				)
			);

			if ( $doRedirect ) {
				exit;
			}
		}

		$packetStatusSyncForm = $this->createPacketStatusSyncForm();
		if (
			$packetStatusSyncForm['save'] instanceof SubmitButton &&
			$packetStatusSyncForm['save']->isSubmittedBy()
		) {
			$packetStatusSyncForm->fireEvents();
		}

		$autoSubmissionForm = $this->createAutoSubmissionForm();
		if (
			$autoSubmissionForm['save'] instanceof SubmitButton &&
			$autoSubmissionForm['save']->isSubmittedBy()
		) {
			$autoSubmissionForm->fireEvents();
		}

		$advancedForm = $this->createAdvancedForm();
		if (
			$advancedForm['save'] instanceof SubmitButton &&
			$advancedForm['save']->isSubmittedBy()
		) {
			$advancedForm->fireEvents();
		}

		$bugReportForm = $this->bugReportForm->createForm();
		if (
			$bugReportForm['submit'] instanceof SubmitButton &&
			$bugReportForm['submit']->isSubmittedBy() &&
			$bugReportForm->isSuccess()
		) {
			$bugReportForm->fireEvents();
		}

		$diagnosticsLoggingForm = $this->diagnosticsLoggingFormFactory->createForm();
		if (
			$diagnosticsLoggingForm['save'] instanceof SubmitButton &&
			$diagnosticsLoggingForm['save']->isSubmittedBy() &&
			$diagnosticsLoggingForm->isSuccess()
		) {
			$diagnosticsLoggingForm->fireEvents();
		}
	}

	/**
	 *  Renders page.
	 */
	public function render(): void {
		$activeTab = ( $this->httpRequest->getQuery( self::PARAM_TAB ) ?? self::TAB_GENERAL );

		$latteParams = [];
		if ( $activeTab === self::TAB_PACKET_STATUS_SYNC ) {
			$latteParams = [ 'form' => $this->createPacketStatusSyncForm() ];
		} elseif ( $activeTab === self::TAB_AUTO_SUBMISSION ) {
			$latteParams = [ 'form' => $this->createAutoSubmissionForm() ];
		} elseif ( $activeTab === self::TAB_ADVANCED ) {
			$latteParams = [ 'form' => $this->createAdvancedForm() ];
		} elseif ( $activeTab === self::TAB_GENERAL ) {
			$latteParams = [ 'form' => $this->create_form() ];
		} elseif ( $activeTab === self::TAB_SUPPORT ) {
			$latteParams = [
				'bugReportFormEnabled'   => false,
				'bugReportForm'          => $this->bugReportForm->createForm(),
				'diagnosticsLoggingForm' => $this->diagnosticsLoggingFormFactory->createForm(),
				'hasPacketaLog'          => is_file( $this->diagnosticsLogger->getPacketaLogPath() ),
			];
		}

		if ( ! extension_loaded( 'soap' ) ) {
			$latteParams['error'] = __( 'This plugin requires an active SOAP library for proper operation. Contact your web hosting administrator.', 'packeta' );
		}

		$latteParams['apiPasswordLink'] = trim( $this->latteEngine->renderToString( PACKETERY_PLUGIN_DIR . '/template/options/help-block-link.latte', [ 'href' => 'https://client.packeta.com/support' ] ) );

		$latteParams['exportLink'] = add_query_arg(
			[
				'page'   => self::SLUG,
				'action' => Exporter::ACTION_EXPORT_SETTINGS,
			],
			get_admin_url( null, 'admin.php' )
		);

		$latteParams['deleteDiagnosticsLogsLink'] = add_query_arg(
			[
				'page'   => self::SLUG,
				'action' => DiagnosticsLogger::ACTION_DELETE_PACKETA_LOG,
				'tab'    => self::TAB_SUPPORT,
			],
			get_admin_url( null, 'admin.php' )
		);

		$latteParams['activeTab']               = ( $this->httpRequest->getQuery( self::PARAM_TAB ) ?? self::TAB_GENERAL );
		$latteParams['generalTabLink']          = $this->createLink();
		$latteParams['advancedTabLink']         = $this->createLink( self::TAB_ADVANCED );
		$latteParams['supportTabLink']          = $this->createLink( self::TAB_SUPPORT );
		$latteParams['packetStatusSyncTabLink'] = $this->createLink( self::TAB_PACKET_STATUS_SYNC );
		$latteParams['autoSubmissionTabLink']   = $this->createLink( self::TAB_AUTO_SUBMISSION );

		$latteParams['canValidateSender']    = (bool) $this->optionsProvider->get_sender();
		$latteParams['senderValidationLink'] = add_query_arg(
			[
				'page'   => self::SLUG,
				'action' => self::ACTION_VALIDATE_SENDER,
			],
			get_admin_url( null, 'admin.php' )
		);

		$lastExport       = null;
		$lastExportOption = get_option( OptionNames::LAST_SETTINGS_EXPORT );
		if ( $lastExportOption !== false ) {
			$date = DateTime::createFromFormat( DATE_ATOM, $lastExportOption );
			if ( $date !== false ) {
				$date->setTimezone( wp_timezone() );
				$lastExport = $date->format( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ) );
			}
		}
		if ( $lastExport !== null ) {
			$latteParams['lastExport'] = $lastExport;
		}

		$latteParams['forcePacketCancelDescription'] = __( 'Cancel the packet for an order even if the cancellation in the Packeta system will not be successful.', 'packeta' );
		$latteParams['messages']                     = $this->messageManager->renderToString( MessageManager::RENDERER_PACKETERY, 'plugin-options' );
		$latteParams['isCzechLocale']                = $this->moduleHelper->isCzechLocale();
		$latteParams['logoZasilkovna']               = $this->urlBuilder->buildAssetUrl( 'public/images/logo-zasilkovna.svg' );
		$latteParams['logoPacketa']                  = $this->urlBuilder->buildAssetUrl( 'public/images/logo-packeta.svg' );
		$advancedCarrierSettingsDescription          = sprintf(
			// translators: first %s is line break, second one is e-mail address
			__( 'When this feature is active, Packeta carriers will appear as separate shipping methods under WooCommerce → Settings → Shipping. After enabling or disabling this feature, you need to reconfigure your shipping methods in WooCommerce.%1$sIf you encounter any issues, please contact us at %2$s.', 'packeta' ),
			'<br>',
			'<a href="mailto:' . $this->supportEmailAddress . '">' . $this->supportEmailAddress . '</a>'
		);
		$latteParams['translations'] = [
			'packeta'                                => __( 'Packeta', 'packeta' ),
			'title'                                  => __( 'Options', 'packeta' ),
			'general'                                => __( 'General', 'packeta' ),
			'packetAutoSubmission'                   => __( 'Packet auto-submission', 'packeta' ),
			'packetAutoSubmissionMappingDescription' => __( 'Choose events for payment methods that will trigger packet submission', 'packeta' ),
			// translators: %s represents URL.
			'apiPasswordCanBeFoundAt%sUrl'           => __( 'API password can be found at %s', 'packeta' ),

			'saveChanges'                            => __( 'Save changes', 'packeta' ),
			'validateSender'                         => __( 'Validate sender', 'packeta' ),
			'advanced'                               => __( 'Advanced', 'packeta' ),
			'support'                                => __( 'Support', 'packeta' ),
			'optionsExportInfo1'                     => __(
				'By clicking the button, you will export the settings of your plugin into a separate file. The export does not contain any sensitive information about your e-shop. Please send the resulting file to the technical support of Packeta (you can find the e-mail address here:',
				'packeta'
			),
			'optionsExportInfo2'                     => __(
				') along with the description of your problem. For a better understanding of your problem, we recommend adding screenshots, which show the problem (if possible).',
				'packeta'
			),
			'exportPluginSettings'                   => __( 'Export the plugin settings', 'packeta' ),
			'settingsExportDatetime'                 => __( 'Date and time of the last export of settings', 'packeta' ),
			'settingsNotYetExported'                 => __( 'The settings have not been exported yet.', 'packeta' ),
			'bugReportTitle'                         => $this->wpAdapter->__( 'Report a bug', 'packeta' ),
			'bugReportDescription'                   => $this->wpAdapter->__( 'If you encounter any issues with the Packeta plugin, please use this form to report them. Your message will be sent to our technical support team along with system information.', 'packeta' ),
			'bugReportInfo'                          => $this->wpAdapter->__( 'We will also zip the following files and attach them to the email, if available: WooCommerce Log, Diagnostics Log, Tracy Log, Wordpress Debug Log, WooCommerce System Status Log, Packeta plugin settings export.', 'packeta' ),
			'exportSettingsTitle'                    => $this->wpAdapter->__( 'Export settings', 'packeta' ),
			'diagnosticsLoggingTitle'                => $this->wpAdapter->__( 'Diagnostics logging', 'packeta' ),
			'senderDescription'                      => sprintf(
				/* translators: 1: emphasis start 2: emphasis end 3: client section link start 4: client section link end */
				esc_html__( 'Fill here %1$ssender label%2$s - you will find it in %3$sclient section%4$s - user information - field \'Indication\'.', 'packeta' ),
				'<strong>',
				'</strong>',
				'<a href="https://client.packeta.com/senders" target="_blank">',
				'</a>'
			),
			'advancedCarrierSettingsDescription'     => $advancedCarrierSettingsDescription,
			'packagingWeightDescription'             => __( 'This parameter is used to determine the weight of the packaging material. This value is automatically added to the total weight of each order that contains products with non-zero weight. This value is also taken into account when evaluating the weight rules in the cart.', 'packeta' ),
			'defaultWeightDescription'               => __( 'This value is automatically added to the total weight of each order that contains products with zero weight.', 'packeta' ),
			'defaultDimensionsDescription'           => __( 'These dimensions will be applied to the packet by default, if required by the carrier.', 'packeta' ),
			'setCheckoutDetectionDescription'        => __( 'If you have trouble displaying the widget button in the checkout, you can force what type of checkout you are using.', 'packeta' ),
			'packetStatusSyncTabLinkLabel'           => __( 'Packet status tracking', 'packeta' ),
			'statusSyncingOrderStatusesLabel'        => __( 'Order statuses, for which cron will check the packet status', 'packeta' ),
			'statusSyncingOrderStatusesDescription'  => __( 'Cron will automatically track all orders with these statuses and check if the shipment status has changed.', 'packeta' ),
			'statusSyncingPacketStatusesLabel'       => __( 'Packet statuses that are being checked', 'packeta' ),
			'statusSyncingPacketStatusesDescription' => __( 'If an order has a shipment with one of these selected statuses, the shipment status will be tracked.', 'packeta' ),
			'numberOfDaysToCheckDescription'         => __( 'Number of days after the creation of an order, during which the order status will be checked.', 'packeta' ),
			'widgetAutoOpenDescription'              => __( 'If this option is active, the widget for selecting pickup points will open automatically after selecting the shipping method at the checkout.', 'packeta' ),
			'autoOrderStatusChangeDescription'       => __( 'Change order status after data submission to Packeta.', 'packeta' ),
			'freeShippingTextDescription'            => __( 'If enabled, "FREE" will be displayed after the name of the shipping method, if free shipping is applied.', 'packeta' ),
			'orderStatusChangeSettings'              => __( 'Order status change settings', 'packeta' ),
			'dimensionsLabel'                        => __( 'Dimensions', 'packeta' ),
			'autoEmailInfoInsertionDescription'      => __( 'When enabled, the plugin automatically adds packet and pickup point details to emails. Disable this if you prefer to insert them manually using shortcodes.', 'packeta' ),
			'diagnosticsLoggingDescription'          => $this->wpAdapter->__( 'If some plugin functionality is not working correctly, you can enable diagnostic logging. After enabling it, please repeat the action that is not working as expected. The log will then record important function calls, passed parameters, and their results. Once you have reproduced the issue, disable diagnostic logging again. This information can help developers troubleshoot the problem. You can find the log in the packeta.log file, which is stored by default in wp-content/plugins/packeta/log.', 'packeta' ),
			'diagnosticsLoggingLink'                 => $this->wpAdapter->__( 'Delete log', 'packeta' ),
			'bugReportScreenshotsTitle'              => $this->wpAdapter->__( 'If possible, please provide screenshots showing the problem. You can do it this way:', 'packeta' ),
			'bugReportScreenshotsFirstStep'          => sprintf(
			/* translators: 1: ImgBB link start 2: ImgBB link end */
				$this->wpAdapter->__( 'Go to %1$sImgBB%2$s and upload your screenshots.', 'packeta' ),
				'<a href="https://imgbb.com/" target="_blank">',
				'</a>'
			),
			'bugReportScreenshotsSecondStep'         => $this->wpAdapter->__( 'Copy the link(s) generated after uploading', 'packeta' ),
			'bugReportScreenshotsThirdStep'          => $this->wpAdapter->__( 'Paste the link(s) into your message.', 'packeta' ),
			'message'                                => $this->wpAdapter->__( 'Message', 'packeta' ),
		];

		$this->latteEngine->render( PACKETERY_PLUGIN_DIR . '/template/options/page.latte', $latteParams );
	}

	/**
	 * Creates tab link.
	 *
	 * @param string|null $tab Tab ID.
	 * @return string
	 */
	public function createLink( ?string $tab = null ): string {
		$params = [
			'page' => self::SLUG,
		];

		if ( $tab !== null ) {
			$params[ self::PARAM_TAB ] = $tab;
		}

		return add_query_arg(
			$params,
			get_admin_url( null, 'admin.php' )
		);
	}
}
