<?php
namespace WPO\WC\PDF_Invoices_Pro;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly
}

if ( ! class_exists( '\\WPO\\WC\\PDF_Invoices_Pro\\Settings' ) ) :

class Settings {

	public function __construct() {
		add_action( 'admin_enqueue_scripts', array( $this, 'load_scripts_styles' ) );

		add_action( 'wp_ajax_wcpdf_pro_filename_existence_check', array($this, 'filename_existence_check' ));
		add_action( 'wp_ajax_wcpdf_i18n_get_translations', array($this, 'get_translations' ));
		add_action( 'wp_ajax_wcpdf_i18n_save_translations', array($this, 'save_translations' ));

		add_filter( 'wpo_wcpdf_settings_fields_general', array( $this, 'settings_fields_general_i18n' ), 10, 1 );
		add_filter( 'wpo_wcpdf_non_historical_settings', array( $this, 'non_historical_pro_settings' ), 10, 1 );

		add_action( 'admin_init', array( $this, 'add_pro_document_settings' ), 1 );
		add_action( 'wpo_wcpdf_document_settings_categories', array( $this, 'add_pro_settings_categories' ), 10, 3 );
		add_action( 'wpo_wcpdf_document_settings_categories', array( $this, 'add_invoice_pro_settings_categories' ), 10, 3 );

		add_filter( 'wpo_wcpdf_preview_excluded_settings', array( $this, 'preview_excluded_pro_settings' ), 10, 1 );

		add_filter( 'wpo_wcpdf_document_is_allowed', array( $this, 'disable_document_for' ), 1, 2 );

		add_filter( 'wpo_wcpdf_html_filters', array( $this, 'show_zero_taxes' ), 10, 2 );

		// Add Pro settings under the General tab.
		add_filter( 'wpo_wcpdf_settings_fields_general', array( $this, 'add_pro_general_settings' ), 10, 5 );
		add_filter( 'wpo_wcpdf_general_settings_categories', array( $this, 'add_pro_general_settings_categories' ), 10, 2 );

		// Add Pro settings under the Advanced tab.
		add_filter( 'wpo_wcpdf_settings_fields_debug', array( $this, 'add_pro_debug_settings' ), 10, 4 );
		add_filter( 'wpo_wcpdf_settings_debug_categories', array( $this, 'add_pro_debug_settings_categories' ), 10, 1 );
	}

	/**
	 * Add Pro settings to the General tab.
	 *
	 * @param array $settings_fields
	 * @param string $page
	 * @param string $option_group
	 * @param string $option_name
	 * @param \WPO\IPS\Settings\SettingsGeneral $settings_general
	 *
	 * @return array
	 */
	public function add_pro_general_settings( array $settings_fields, string $page, string $option_group, string $option_name, \WPO\IPS\Settings\SettingsGeneral $settings_general ): array {
		// load invoice to reuse method to get wc emails
		$invoice = wcpdf_get_document( 'invoice', null );

		$new_setting_fields = array(
			/**
			 * Address customization section
			 */
			array(
				'type'     => 'section',
				'id'       => 'address_customization',
				'title'    => __( 'Customer Address Customization', 'wpo_wcpdf_pro' ),
				'callback' => 'section',
			),
			array(
				'type'			=> 'setting',
				'id'			=> 'placeholders_info',
				'title'			=> __( 'Placeholders information', 'wpo_wcpdf_pro' ),
				'callback'		=> 'html_section',
				'section'		=> 'address_customization',
				'args'			=> array(
					'option_name' => $option_name,
					'id'          => 'placeholders_info',
					'html'        => $this->custom_address_fields_section(),
				)
			),
			array(
				'type'     => 'setting',
				'id'       => 'billing_address',
				'title'    => __( 'Billing address', 'wpo_wcpdf_pro' ),
				'callback' => 'i18n_wrap',
				'section'  => 'address_customization',
				'args'     => array(
					'callback'    => 'textarea',
					'option_name' => $option_name,
					'id'          => 'billing_address',
					'width'       => '42',
					'height'      => '8',
				)
			),
			array(
				'type'     => 'setting',
				'id'       => 'shipping_address',
				'title'    => __( 'Shipping address', 'wpo_wcpdf_pro' ),
				'callback' => 'i18n_wrap',
				'section'  => 'address_customization',
				'args'     => array(
					'callback'    => 'textarea',
					'option_name' => $option_name,
					'id'          => 'shipping_address',
					'width'       => '42',
					'height'      => '8',
				)
			),
			array(
				'type'     => 'setting',
				'id'       => 'remove_whitespace',
				'title'    => __( 'Remove empty lines', 'wpo_wcpdf_pro' ),
				'callback' => 'checkbox',
				'section'  => 'address_customization',
				'args'     => array(
					'option_name' => $option_name,
					'id'          => 'remove_whitespace',
					'description' => __( 'Enable this option if you want to remove empty lines left over from empty address/placeholder replacements', 'wpo_wcpdf_pro' ),
				)
			),
			array(
				'type'     => 'setting',
				'id'       => 'placeholders_allow_line_breaks',
				'title'    => __( 'Allow line breaks within custom fields', 'wpo_wcpdf_pro' ),
				'callback' => 'checkbox',
				'section'  => 'address_customization',
				'args'     => array(
					'option_name' => $option_name,
					'id'          => 'placeholders_allow_line_breaks',
				)
			),

			/**
			 * Multilingual section
			 */
			array(
				'type'     => 'section',
				'id'       => 'multilingual',
				'title'    => __( 'Multilingual settings', 'wpo_wcpdf_pro' ),
				'callback' => 'section',
			),
			array(
				'type'     => 'setting',
				'id'       => 'document_language',
				'title'    => __( 'Document language', 'wpo_wcpdf_pro' ),
				'callback' => 'select',
				'section'  => 'multilingual',
				'args'     => array(
					'option_name' => $option_name,
					'id'          => 'document_language',
					'options'     => $this->get_multilingual_document_language_options(),
					'description' => sprintf(
						'%s<br>%s: %s',
						__( 'Select the source of the document language used for PDF translation.', 'wpo_wcpdf_pro' ),
						/* translators: documentation link */
						__( 'To understand this setting better, please read this documentation page', 'wpo_wcpdf_pro' ),
						'<a href="https://docs.wpovernight.com/woocommerce-pdf-invoices-packing-slips/multilingual-support/#how-is-the-pdf-language-determined/" target="_blank">'.__( 'How is the PDF language determined?', 'wpo_wcpdf_pro' ).'</a>'
					)
				),
			),

			/**
			 * Static files section.
			 */
			array(
				'type'     => 'section',
				'id'       => 'static_files',
				'title'    => __( 'Static files', 'wpo_wcpdf_pro' ),
				'callback' => 'section',
			),
			array(
				'type'     => 'setting',
				'id'       => 'static_file',
				'title'    => __( 'Static files', 'wpo_wcpdf_pro' ),
				'callback' => ( class_exists( '\\SitePress') || class_exists( '\\Polylang' ) || class_exists( '\\TRP_Translate_Press' ) ) ? 'i18n_wrap' : array( $this, 'multiple_file_upload_callback' ),
				'section'  => 'static_files',
				'args'     => array(
					'callback'             => ( class_exists( '\\SitePress') || class_exists( '\\Polylang' ) || class_exists( '\\TRP_Translate_Press' ) ) ? array( $this, 'multiple_file_upload_callback' ) : '',
					'option_name'          => $option_name,
					'id'                   => 'static_file',
					'uploader_title'       => __( 'Select a file to attach', 'wpo_wcpdf_pro' ),
					'uploader_button_text' => __( 'Set file', 'wpo_wcpdf_pro' ),
					'remove_button_text'   => __( 'Remove file', 'wpo_wcpdf_pro' ),
					'total_files_number'   => apply_filters( 'wpo_wcpdf_total_static_files_number', 3 ),
				)
			),
			array(
				'type'     => 'setting',
				'id'       => 'static_file_attach_to_email_ids',
				'title'    => __( 'Attach to:', 'wpo_wcpdf_pro' ),
				'callback' => 'multiple_checkboxes',
				'section'  => 'static_files',
				'args'     => array(
					'option_name'     => $option_name,
					'id'              => 'static_file_attach_to_email_ids',
					'fields_callback' => array( $invoice, 'get_wc_emails' ),
					'description'     => ! is_writable( WPO_WCPDF()->main->get_tmp_path( 'attachments' ) )
						? '<span class="wpo-warning">' . sprintf(
							/* translators: %s: temp folder path */
							__( 'It looks like the temp folder (%s) is not writable, check the permissions for this folder! Without having write access to this folder, the plugin will not be able to email invoices.', 'wpo_wcpdf_pro' ),
							'<code>' . WPO_WCPDF()->main->get_tmp_path( 'attachments' ) . '</code>'
						) . '</span>'
						: '',
				)
			),
		);

		return apply_filters( 'wpo_wcpdf_pro_settings_fields_general', array_merge( $settings_fields, $new_setting_fields ), $this );
	}

	/**
	 * @param array $settings_categories
	 * @param \WPO\IPS\Settings\SettingsGeneral $settings_general
	 *
	 * @return array
	 */
	public function add_pro_general_settings_categories( array $settings_categories, \WPO\IPS\Settings\SettingsGeneral $settings_general ): array {
		$settings_categories = $settings_categories + array(
			'address_customization' => array(
				'title'   => __( 'Customer Address Customization', 'wpo_wcpdf_pro' ),
				'members' => array( 'placeholders_info', 'billing_address', 'shipping_address', 'remove_whitespace', 'placeholders_allow_line_breaks' ),
			),
			'multilingual' => array(
				'title'   => __( 'Multilingual', 'wpo_wcpdf_pro' ),
				'members' => array( 'document_language' ),
			),
			'static_files' => array(
				'title'   => __( 'Static Files', 'wpo_wcpdf_pro' ),
				'members' => array( 'static_file', 'static_file_attach_to_email_ids' ),
			),
		);

		return apply_filters( 'wpo_wcpdf_pro_general_settings_categories', $settings_categories, $settings_general, $this );
	}

	public function add_pro_document_settings() {
		add_filter( 'wpo_wcpdf_settings_fields_documents_invoice', array( $this, 'pro_invoice_settings' ), 9, 4 );
		add_filter( 'wpo_wcpdf_settings_fields_documents_packing_slip', array( $this, 'pro_packing_slip_settings' ), 9, 4 );
		add_filter( 'wpo_wcpdf_settings_fields_documents_credit_note', array( $this, 'pro_credit_note_settings' ), 9, 4 );

		// add title, filename and keep PDF settings
		$documents = WPO_WCPDF()->documents->get_documents('all');
		foreach ( $documents as $document ) {
			add_filter( 'wpo_wcpdf_settings_fields_documents_'.$document->slug, function( $settings_fields, $page, $option_group, $option_name ) use ( $document ) {
				$new_setting = array(
					array(
						'type'     => 'setting',
						'id'       => 'title',
						'title'    => __( 'Document title', 'wpo_wcpdf_pro' ),
						'callback' => 'i18n_wrap',
						'section'  => 'custom',
						'args'     => array(
							'callback'    => 'text_input',
							'option_name' => $option_name,
							'id'          => 'title',
							'placeholder' => $document->get_title(),
						)
					),
					array(
						'type'     => 'setting',
						'id'       => 'filename',
						'title'    => __( 'PDF filename', 'wpo_wcpdf_pro' ),
						'callback' => 'i18n_wrap',
						'section'  => 'custom',
						'args'     => array(
							'callback'    => 'text_input',
							'option_name' => $option_name,
							'id'          => 'filename',
							// 'placeholder' => $document->get_type().'-######.pdf',
							'description' => __( 'Leave empty to use default. Placeholders like {{document_number}} and {{order_number}} can be used to include document numbers in the filename.', 'wpo_wcpdf_pro' ),
						)
					),
					array(
						'type'     => 'setting',
						'id'       => 'number_title',
						'title'    => __( 'Document number label', 'wpo_wcpdf_pro' ),
						'callback' => 'i18n_wrap',
						'section'  => 'custom',
						'args'     => array(
							'callback'    => 'text_input',
							'option_name' => $option_name,
							'id'          => 'number_title',
							'placeholder' => $document->get_number_title(),
						)
					),
					array(
						'type'     => 'setting',
						'id'       => 'date_title',
						'title'    => __( 'Document date label', 'wpo_wcpdf_pro' ),
						'callback' => 'i18n_wrap',
						'section'  => 'custom',
						'args'     => array(
							'callback'    => 'text_input',
							'option_name' => $option_name,
							'id'          => 'date_title',
							'placeholder' => $document->get_date_title(),
						)
					),
					array(
						'type'     => 'setting',
						'id'       => 'archive_pdf',
						'title'    => __( 'Keep PDF on server', 'wpo_wcpdf_pro' ),
						'callback' => 'checkbox',
						'section'  => 'custom',
						'args'     => array(
							'option_name' => $option_name,
							'id'          => 'archive_pdf',
							'description' => __( 'Stores the PDF when generated for the first time and reloads this copy each time the document is requested. Please note this can take up considerable disk space on you server.' , 'wpo_wcpdf_pro' ),
						)
					),
					array(
						'type'     => 'setting',
						'id'       => 'show_zero_taxes',
						'title'    => __( 'Show zero taxes', 'wpo_wcpdf_pro' ),
						'callback' => 'checkbox',
						'args'     => array(
							'option_name' => $option_name,
							'id'          => 'show_zero_taxes',
							'description' => __( 'When enabled and configured, the document will show taxes even if they equal zero.', 'wpo_wcpdf_pro' )
						)
					),
				);

				if ( $document->get_type() != 'credit-note' ) {
					$auto_generate_for_statuses = array(
						'type'     => 'setting',
						'id'       => 'auto_generate_for_statuses',
						'title'    => __( 'Create automatically for:', 'wpo_wcpdf_pro' ),
						'callback' => 'select',
						'section'  => 'custom',
						'args'     => array(
							'option_name'      => $option_name,
							'id'               => 'auto_generate_for_statuses',
							'options_callback' => 'wc_get_order_statuses',
							'multiple'         => true,
							'enhanced_select'  => true,
							'placeholder'      => __( 'Select one or more statuses', 'wpo_wcpdf_pro' ),
							'description'      => __( 'The document will be created automatically when the order reaches the status(es) selected above.', 'wpo_wcpdf_pro' ),
						)
					);
					array_push( $new_setting, $auto_generate_for_statuses );
				}

				/**
				 * Expand 'Disable for' option 
				 */

				// Unset the original 'Disable for statuses' setting from the free plugin
				foreach ( $settings_fields as $key => $setting ) {
					if ( $setting['id'] == 'disable_for_statuses' ) {
						unset( $settings_fields[$key] );
					}
				}

				$disable_for = array(
					'type'     => 'setting',
					'id'       => 'disable_for',
					'title'    => __( 'Disable for:', 'wpo_wcpdf_pro' ),
					'callback' => array( $this, 'requirements_callback' ),
					'section'  => 'custom',
					'args'     => array(
						'id'            => 'disable_for',
						'document_type' => $document->get_type(),
						'requirements'  => array(
							array(
								'title'    => __( 'Disable when' , 'wpo_wcpdf_pro' ),
								'callback' => 'select',
								'args'     => array(
									'option_name'      => $option_name,
									'id'               => 'disable_for_require',
									'options'          => array( 
										'one' => __( 'Any requirement is met' , 'wpo_wcpdf_pro' ),
										'all' => __( 'All requirements are met' , 'wpo_wcpdf_pro' ),
									),
									'description'      => __( 'Please select if the document should be disabled when any one of the below requirements are met, or only when all requirements are met.', 'wpo_wcpdf_pro' ),
								),
							),
							array(
								'title'    => __( 'Order status' , 'wpo_wcpdf_pro' ),
								'callback' => 'select',
								'args'     => array(
									'option_name'      => $option_name,
									'id'               => 'disable_for_statuses',
									'options_callback' => 'wc_get_order_statuses',
									'multiple'         => true,
									'enhanced_select'  => true,
									'placeholder'      => __( 'Select one or more statuses', 'wpo_wcpdf_pro' ),
								),
							),
							array(
								'title'    => __( 'Payment method' , 'wpo_wcpdf_pro' ),
								'callback' => 'select',
								'args'     => array(
									'option_name'      => $option_name,
									'id'               => 'disable_for_payment_methods',
									'options_callback' => array( $this, 'get_payment_gateways' ),
									'multiple'         => true,
									'enhanced_select'  => true,
									'placeholder'      => __( 'Select one or more payment methods', 'wpo_wcpdf_pro' ),
								),
							),
							array(
								'title'    => __( 'Billing country' , 'wpo_wcpdf_pro' ),
								'callback' => 'select',
								'args'     => array(
									'option_name'      => $option_name,
									'id'               => 'disable_for_billing_countries',
									'options'          => WC()->countries->countries,
									'multiple'         => true,
									'enhanced_select'  => true,
									'placeholder'      => __( 'Select one or more countries', 'wpo_wcpdf_pro' ),
								),
							),
						),
					),
				);
				array_push( $new_setting, $disable_for );

				$settings_fields = $this->move_setting_after_id( $settings_fields, $new_setting, 'enabled' );
				
				return $settings_fields;
			}, 10, 4 );
		}
	}

	/**
	 * Add settings categories for all document types
	 * 
	 * @param array $settings_categories
	 * @param string $output_format
	 * @param object $document
	 * 
	 * @return array
	 */
	public function add_pro_settings_categories( array $settings_categories, string $output_format, object $document ): array {
		$settings_categories = WPO_WCPDF()->settings->add_single_setting_field_to_category(
			$settings_categories, 
			'show_zero_taxes', 
			'document_details'
		);

		return apply_filters( 'wpo_wcpdf_pro_settings_categories', $settings_categories, $document );
	}

	public function add_invoice_pro_settings_categories( array $settings_categories, string $output_format, object $document ) {
		if ( version_compare( WPO_WCPDF()->version, '3.9.1-beta-1', '<' ) ) {
			return $settings_categories;
		}

		if ( 'invoice' === $document->get_type() ) {
			// General category
			$settings_categories = WPO_WCPDF()->settings->add_single_setting_field_to_category( $settings_categories, 'title', 'general', 2 );
			$settings_categories = WPO_WCPDF()->settings->add_multiple_setting_fields_to_category(
				$settings_categories,
				array( 'auto_generate_for_statuses', 'disable_for' ),
				'general',
				WPO_WCPDF()->settings->get_setting_position( $settings_categories, 'general', 'attach_to_email_ids' ) + 1
			);

			// Document display category
			$settings_categories = WPO_WCPDF()->settings->add_multiple_setting_fields_to_category( $settings_categories, array( 'number_title', 'date_title' ), 'document_details', 1 );
			$settings_categories = WPO_WCPDF()->settings->add_multiple_setting_fields_to_category(
				$settings_categories,
				array( 'display_shop_coc', 'display_shop_vat', 'shop_vat_label', 'shop_coc_label', ),
				'document_details',
				WPO_WCPDF()->settings->get_setting_position( $settings_categories, 'document_details', 'display_customer_notes' ) + 1
			);

			// Due date settings
			$settings_categories = WPO_WCPDF()->settings->add_multiple_setting_fields_to_category(
				$settings_categories,
				array( 'due_date_title', 'due_date_allowed_statuses','due_date_allowed_payment_methods'),
				'document_details',
				WPO_WCPDF()->settings->get_setting_position( $settings_categories, 'document_details', 'due_date' ) + 1
			);

			// Advanced category
			$settings_categories = WPO_WCPDF()->settings->add_single_setting_field_to_category( $settings_categories, 'filename', 'advanced', 1 );
			$settings_categories = WPO_WCPDF()->settings->add_single_setting_field_to_category(
				$settings_categories,
				'archive_pdf',
				'advanced',
				WPO_WCPDF()->settings->get_setting_position( $settings_categories, 'advanced', 'reset_number_yearly' ) + 1
			);
		}

		return apply_filters( 'wpo_wcpdf_pro_invoice_settings_categories', $settings_categories, $document );
	}

	public function pro_invoice_settings( $settings_fields, $page, $option_group, $option_name ) {
		$due_date_settings = array(
			array(
				'type'     => 'setting',
				'id'       => 'due_date_title',
				'title'    => 'Due date label',
				'callback' => 'i18n_wrap',
				'section'  => 'invoice',
				'args'     => array(
					'callback'    => 'text_input',
					'option_name' => $option_name,
					'id'          => 'due_date_title',
					'placeholder' => __( 'Due date:', 'wpo_wcpdf_pro' ),
				)
			),
			array(
				'type'     => 'setting',
				'id'       => 'due_date_allowed_statuses',
				'title'    => __( 'Due date allowed order statuses', 'wpo_wcpdf_pro' ),
				'callback' => 'select',
				'section'  => 'invoice',
				'args'     => array(
					'option_name'      => $option_name,
					'id'               => 'due_date_allowed_statuses',
					'options_callback' => 'wc_get_order_statuses',
					'multiple'         => true,
					'enhanced_select'  => true,
					'placeholder'      => __( 'Select one or more statuses', 'wpo_wcpdf_pro' ),
					'description'      => __( 'The due date will only be displayed in the PDF invoices from orders that match any of the selected statuses above. Leave it empty to display it for all order statuses.', 'wpo_wcpdf_pro' ),
				)
			),
			array(
				'type'     => 'setting',
				'id'       => 'due_date_allowed_payment_methods',
				'title'    => __( 'Due date allowed payment methods', 'wpo_wcpdf_pro' ),
				'callback' => 'select',
				'section'  => 'invoice',
				'args'     => array(
					'option_name'      => $option_name,
					'id'               => 'due_date_allowed_payment_methods',
					'options_callback' => array( $this, 'get_payment_gateways' ),
					'multiple'         => true,
					'enhanced_select'  => true,
					'placeholder'      => __( 'Select one or more payment methods', 'wpo_wcpdf_pro' ),
					'description'      => __( 'The due date will only be displayed in the PDF invoice from orders that have been placed with any of the payment methods selected above. Leave it empty to display it for all payment methods.', 'wpo_wcpdf_pro' ),
				)
			),
			array(
				'type'     => 'setting',
				'id'       => 'display_shop_vat',
				'title'    => __( 'Display VAT number', 'wpo_wcpdf_pro' ),
				'callback' => 'checkbox',
				'section'  => 'invoice',
				'args'     => array(
					'option_name'  => $option_name,
					'id'           => 'display_shop_vat',
					'description'  => __( 'Displays the shop VAT number on the invoice. You can set it under the General settings tab.', 'wpo_wcpdf_pro' ),
				),
			),
			array(
				'type'     => 'setting',
				'id'       => 'shop_vat_label',
				'title'    => __( 'VAT number label', 'wpo_wcpdf_pro' ),
				'callback' => 'i18n_wrap',
				'section'  => 'custom',
				'args'     => array(
					'callback'    => 'text_input',
					'option_name' => $option_name,
					'id'          => 'shop_vat_label',
					'placeholder' => __( 'VAT', 'wpo_wcpdf_pro' ),
				)
			),
			array(
				'type'     => 'setting',
				'id'       => 'display_shop_coc',
				'title'    => __( 'Display COC number', 'wpo_wcpdf_pro' ),
				'callback' => 'checkbox',
				'section'  => 'invoice',
				'args'     => array(
					'option_name'  => $option_name,
					'id'           => 'display_shop_coc',
					'description'  => __( 'Displays the shop Chamber of Commerce number on the invoice. You can set it under the General settings tab.', 'wpo_wcpdf_pro' ),
				),
			),
			array(
				'type'     => 'setting',
				'id'       => 'shop_coc_label',
				'title'    => __( 'COC number label', 'wpo_wcpdf_pro' ),
				'callback' => 'i18n_wrap',
				'section'  => 'custom',
				'args'     => array(
					'callback'    => 'text_input',
					'option_name' => $option_name,
					'id'          => 'shop_coc_label',
					'placeholder' => __( 'COC', 'wpo_wcpdf_pro' ),
				)
			),
		);

		$settings_fields = $this->move_setting_after_id( $settings_fields, $due_date_settings, 'due_date' );

		return $settings_fields;
	}

	public function pro_credit_note_settings( $settings_fields, $page, $option_group, $option_name ) {
		$auto_generate_on_refunds = array(
			array(
				'type'     => 'setting',
				'id'       => 'auto_generate_on_refunds',
				'title'    => __( 'Create automatically after refunding', 'wpo_wcpdf_pro' ),
				'callback' => 'checkbox',
				'section'  => 'credit_note',
				'args'     => array(
					'option_name' => $option_name,
					'id'          => 'auto_generate_on_refunds',
					'description' => __( 'The Credit Note will be created automatically when a (partial or full) refund is created for an order.', 'wpo_wcpdf_pro' ),
				)
			),
		);

		$settings_fields = $this->move_setting_after_id( $settings_fields, $auto_generate_on_refunds, 'enabled' );
		return $settings_fields;
	}

	public function pro_packing_slip_settings( $settings_fields, $page, $option_group, $option_name ) {
		// load packing slip to reuse method to get wc emails
		$packing_slip = wcpdf_get_document( 'packing-slip', null );

		// new settings
		$new_settings = array(
			array(
				'type'     => 'setting',
				'id'       => 'attach_to_email_ids',
				'title'    => __( 'Attach to:', 'wpo_wcpdf_pro' ),
				'callback' => 'multiple_checkboxes',
				'section'  => 'packing_slip',
				'args'     => array(
					'option_name'     => $option_name,
					'id'              => 'attach_to_email_ids',
					'fields_callback' => array( $packing_slip, 'get_wc_emails' ),
					'description'     => ! is_writable( WPO_WCPDF()->main->get_tmp_path( 'attachments' ) )
						? '<span class="wpo-warning">' . sprintf(
							/* translators: %s: temp folder path */
							__( 'It looks like the temp folder (%s) is not writable, check the permissions for this folder! Without having write access to this folder, the plugin will not be able to email invoices.', 'wpo_wcpdf_pro' ),
							'<code>' . WPO_WCPDF()->main->get_tmp_path( 'attachments' ) . '</code>'
						) . '</span>'
						: '',
				)
			),
			array(
				'type'     => 'setting',
				'id'       => 'disable_for_statuses',
				'title'    => __( 'Disable for:', 'wpo_wcpdf_pro' ),
				'callback' => 'select',
				'section'  => 'packing_slip',
				'args'     => array(
					'option_name'      => $option_name,
					'id'               => 'disable_for_statuses',
					'options_callback' => 'wc_get_order_statuses',
					'multiple'         => true,
					'enhanced_select'  => true,
					'placeholder'      => __( 'Select one or more statuses', 'wpo_wcpdf_pro' ),
				)
			),
		);
		$settings_fields = $this->move_setting_after_id( $settings_fields, $new_settings, 'enabled' );

		// packing slip number setting
		$number_setting = array(
			array(
				'type'     => 'setting',
				'id'       => 'display_date',
				'title'    => __( 'Display packing slip date', 'wpo_wcpdf_pro' ),
				'callback' => 'checkbox',
				'section'  => 'packing_slip',
				'args'     => array(
					'option_name' => $option_name,
					'id'          => 'display_date',
				)
			),
			array(
				'type'     => 'setting',
				'id'       => 'display_number',
				'title'    => __( 'Display packing slip number', 'wpo_wcpdf_pro' ),
				'callback' => 'select',
				'section'  => 'packing_slip',
				'args'     => array(
					'option_name' => $option_name,
					'id'      => 'display_number',					
					'options' => array(
						''                    => __( 'No', 'wpo_wcpdf_pro' ),
						'packing_slip_number' => __( 'Packing Slip Number', 'wpo_wcpdf_pro' ),
						'order_number'        => __( 'Order Number', 'wpo_wcpdf_pro' ),
					),					
					'description' => sprintf(
						'<strong>%s</strong> %s <a href="https://docs.wpovernight.com/woocommerce-pdf-invoices-packing-slips/invoice-numbers-explained/#why-is-the-pdf-invoice-number-different-from-the-woocommerce-order-number">%s</a>',
						__( 'Warning!', 'wpo_wcpdf_pro' ),
						__( 'Using the Order Number as packing slip number is not recommended as this may lead to gaps in the packing slip number sequence (even when order numbers are sequential).', 'wpo_wcpdf_pro' ),
						__( 'More information', 'wpo_wcpdf_pro' )
					),
				)
			),
			array(
				'type'     => 'setting',
				'id'       => 'next_packing_slip_number',
				'title'    => __( 'Next packing slip number (without prefix/suffix etc.)', 'wpo_wcpdf_pro' ),
				'callback' => 'next_number_edit',
				'section'  => 'packing_slip',
				'args'     => array(
					'store_callback' => array( $packing_slip, 'get_sequential_number_store' ),
					'size'           => '10',
					'description'    => __( 'This is the number that will be used for the next document. By default, numbering starts from 1 and increases for every new document. Note that if you override this and set it lower than the current/highest number, this could create duplicate numbers!', 'wpo_wcpdf_pro' ),
				)
			),
			array(
				'type'     => 'setting',
				'id'       => 'number_format',
				'title'    => __( 'Number format', 'wpo_wcpdf_pro' ),
				'callback' => 'multiple_text_input',
				'section'  => 'packing_slip',
				'args'     => array(
					'option_name' => $option_name,
					'id'          => 'number_format',
					'fields'      => array(
						'prefix'  => array(
							'label'       => __( 'Prefix' , 'wpo_wcpdf_pro' ),
							'size'        => 20,
							'description' => __( 'If set, this value will be used as number prefix.' , 'wpo_wcpdf_pro' ) . ' ' . sprintf(
								/* translators: 1. document type, 2-3 placeholders */
								__( 'You can use the %1$s year and/or month with the %2$s or %3$s placeholders respectively.', 'wpo_wcpdf_pro' ),
								strtolower( __( 'Packing Slip', 'wpo_wcpdf_pro' ) ), '<strong>[packing_slip_year]</strong>', '<strong>[packing_slip_month]</strong>'
							) . ' ' . __( 'Check the Docs article below to see all the available placeholders for prefix/suffix.', 'wpo_wcpdf_pro' ),
						),
						'suffix'  => array(
							'label'       => __( 'Suffix' , 'wpo_wcpdf_pro' ),
							'size'        => 20,
							'description' => __( 'If set, this value will be used as number suffix.' , 'wpo_wcpdf_pro' ) . ' ' . sprintf(
								/* translators: 1. document type, 2-3 placeholders */
								__( 'You can use the %1$s year and/or month with the %2$s or %3$s placeholders respectively.', 'wpo_wcpdf_pro' ),
								strtolower( __( 'Packing Slip', 'wpo_wcpdf_pro' ) ), '<strong>[packing_slip_year]</strong>', '<strong>[packing_slip_month]</strong>'
							) . ' ' . __( 'Check the Docs article below to see all the available placeholders for prefix/suffix.', 'wpo_wcpdf_pro' ),
						),
						'padding' => array(
							'label'       => __( 'Padding' , 'wpo_wcpdf_pro' ),
							'size'        => 20,
							'type'        => 'number',
							/* translators: document type */
							'description' => sprintf( __( 'Enter the number of digits you want to use as padding. For instance, enter <code>6</code> to display the %s number <code>123</code> as <code>000123</code>, filling it with zeros until the number set as padding is reached.' , 'wpo_wcpdf_pro' ), strtolower( __( 'Packing Slip', 'wpo_wcpdf_pro' ) ) ),
						),
					),
					/* translators: document type */
					'description' => __( 'For more information about setting up the number format and see the available placeholders for the prefix and suffix, check this article:', 'wpo_wcpdf_pro' ) . sprintf( ' <a href="https://docs.wpovernight.com/woocommerce-pdf-invoices-packing-slips/number-format-explained/" target="_blank">%s</a>', __( 'Number format explained', 'wpo_wcpdf_pro') ) . '.<br><br>'. sprintf( __( '<strong>Note</strong>: Changes made to the number format will only be reflected on new orders. Also, if you have already created a custom %s number format with a filter, the above settings will be ignored.', 'wpo_wcpdf_pro' ), strtolower( __( 'Packing Slip', 'wpo_wcpdf_pro' ) ) ),
				)
			),
			array(
				'type'     => 'setting',
				'id'       => 'my_account_buttons',
				'title'    => __( 'Allow My Account download', 'wpo_wcpdf_pro' ),
				'callback' => 'select',
				'section'  => 'packing_slip',
				'args'     => array(
					'option_name' => $option_name,
					'id'          => 'my_account_buttons',
					'options'     => array(
						'never'     => __( 'Never' , 'wpo_wcpdf_pro' ),
						'available' => __( 'Only when a packing slip is already created/emailed' , 'wpo_wcpdf_pro' ),
						'custom'    => __( 'Only for specific order statuses (define below)' , 'wpo_wcpdf_pro' ),
						'always'    => __( 'Always' , 'wpo_wcpdf_pro' ),
					),
					'custom'      => array(
						'type' => 'multiple_checkboxes',
						'args' => array(
							'option_name'     => $option_name,
							'id'              => 'my_account_restrict',
							'fields_callback' => array( $packing_slip, 'get_wc_order_status_list' ),
						),
					),
				)
			),
			array(
				'type'     => 'setting',
				'id'       => 'reset_number_yearly',
				'title'    => __( 'Reset packing slip number yearly', 'wpo_wcpdf_pro' ),
				'callback' => 'checkbox',
				'section'  => 'packing_slip',
				'args'     => array(
					'option_name' => $option_name,
					'id'          => 'reset_number_yearly',
				)
			),
		);
		$settings_fields = $this->move_setting_after_id( $settings_fields, $number_setting, 'display_customer_notes' );


		// insert refunded qty setting
		$subtract_refunded_qty = array(
			array(
				'type'     => 'setting',
				'id'       => 'subtract_refunded_qty',
				'title'    => __( 'Subtract refunded item quantities from packing slip', 'wpo_wcpdf_pro' ),
				'callback' => 'checkbox',
				'section'  => 'packing_slip',
				'args'     => array(
					'option_name' => $option_name,
					'id'          => 'subtract_refunded_qty',
				)
			),
		);
		$settings_fields = $this->move_setting_after_id( $settings_fields, $subtract_refunded_qty, 'display_customer_notes' );

		$hide_virtual_downloadable_products = array(
			array(
				'type'     => 'setting',
				'id'       => 'hide_virtual_downloadable_products',
				'title'    => __( 'Hide products', 'wpo_wcpdf_pro' ),
				'callback' => 'select',
				'section'  => 'packing_slip',
				'args'     => array(
					'option_name' => $option_name,
					'id'          => 'hide_virtual_downloadable_products',
					'options'     => apply_filters( 'wpo_wcpdf_hide_products_options', array(
						''                         => __( 'No', 'wpo_wcpdf_pro' ),
						'virtual'                  => __( 'Only Virtual', 'wpo_wcpdf_pro' ),
						'downloadable'             => __( 'Only Downloadable', 'wpo_wcpdf_pro' ),
						'virtual_or_downloadable'  => __( 'Virtual or Downloadable', 'wpo_wcpdf_pro' ),
						'virtual_and_downloadable' => __( 'Virtual and Downloadable', 'wpo_wcpdf_pro' ),
					), 'packing-slip' ),
				),
			),
		);
		$settings_fields = $this->move_setting_after_id( $settings_fields, $hide_virtual_downloadable_products, 'display_customer_notes' );

		return $settings_fields;
	}

	public function settings_fields_general_i18n( $settings_fields ) {
		$i18n_wrap = array(
			'header_logo',
			'shop_name',
			'shop_address',            // Legacy, since version 4.5.0 of the free plugin
			'shop_address_line_1',
			'shop_address_line_2',
			'shop_address_city',
			'shop_address_postcode',
			'shop_address_state',
			'shop_address_country',
			'shop_address_additional',
			'footer',
			'extra_1',
			'extra_2',
			'extra_3'
		);

		foreach ( $settings_fields as $key => $settings_field ) {
			if ( $settings_field['type'] == 'setting' && in_array( $settings_field['id'], $i18n_wrap ) ) {
				$settings_field['args']['callback'] = $settings_field['callback'];
				$settings_field['callback']         = 'i18n_wrap';
				$settings_fields[$key]              = $settings_field;
			}
		}

		return $settings_fields;
	}

	public function move_setting_after_id( $settings, $insert_settings, $after_setting_id ) {
		$pos = 1; // this is already +1 to insert after the actual pos
		foreach ( $settings as $setting ) {
			if ( isset( $setting['id'] ) && $setting['id'] == $after_setting_id ) {
				$section = $setting['section'];
				break;
			} else {
				$pos++;
			}
		}

		// replace section
		if ( isset( $section ) ) {
			foreach ( $insert_settings as $key => $insert_setting ) {
				$insert_settings[$key]['section'] = $section;
			}
		} else {
			$empty_section = array(
				array(
					'type'     => 'section',
					'id'       => 'custom',
					'title'    => '',
					'callback' => 'section',
				),
			);
			$insert_settings = array_merge( $empty_section,$insert_settings );
		}
		// insert our api settings
		$new_settings = array_merge( array_slice( $settings, 0, $pos, true ), $insert_settings, array_slice( $settings, $pos, NULL, true ) );

		return $new_settings;
	}

	public function get_translations () {
		check_ajax_referer( 'wcpdf_i18n_translations', 'security' );
		if ( empty( $_POST ) ) {
			die();
		}
		extract( $_POST );
		
		$languages    = function_exists( 'wpo_wcpdf_get_multilingual_languages' ) ? wpo_wcpdf_get_multilingual_languages() : array();
		$input_type   = strtolower( $input_type );
		$translations = get_option( 'wpo_wcpdf_translations' );

		printf( '<div id="%s-translations" class="translations">', $input_attributes['id'] )
		?>
			<ul>
				<?php foreach ( $languages as $lang => $data ) {
					$translation_id = $data['language_code'].'_'.$input_attributes['id'];
					printf('<li><a href="#%s">%s</a></li>', $translation_id, $data['native_name']);
				}
				?>
			</ul>
			<?php foreach ( $languages as $lang => $data ) {
				$translation_id = $data['language_code'].'_'.$input_attributes['id'];
				$value          = isset( $translations[$input_attributes['name']][$data['language_code']] ) ? $translations[$input_attributes['name']][$data['language_code']] : '';
				printf( '<div id="%s">', $translation_id );
				switch ( $input_type ) {
					case 'textarea':
						printf( '<textarea cols="%1$s" rows="%2$s" data-language="%3$s">%4$s</textarea>', $input_attributes['cols'], $input_attributes['rows'], $data['language_code'], $value);
						break;
					case 'input':
						printf( '<input type="text" size="%1$s" value="%2$s" data-language="%3$s"/>', $input_attributes['size'], $value, $data['language_code'] );
						break;
				}
				$spinner = '<div class="spinner"></div>';
				printf( '<div><button class="wpo-wcpdf-i18n-translations-save button button-primary">%s</button>%s</div>', __( 'Save translations', 'wpo_wcpdf_pro' ), $spinner );
				echo '</div>';
			}
			?>
		
		</div>
		<?php

		die();
	}
	public function save_translations () {
		check_ajax_referer( 'wcpdf_i18n_translations', 'security' );
		if (empty($_POST)) {
			die();
		}
		extract($_POST);

		$translations = get_option( 'wpo_wcpdf_translations' );
		$translations[$setting] = $strings;
		update_option( 'wpo_wcpdf_translations', $translations );

		die();
	}

	/**
	 * Scripts & styles for settings page
	 */
	public function load_scripts_styles ( $hook ) {
		// only load on our own settings page
		// maybe find a way to refer directly to WPO\WC\PDF_Invoices\Settings::$options_page_hook ?
		if ( ! ( $hook == 'woocommerce_page_wpo_wcpdf_options_page' || $hook == 'settings_page_wpo_wcpdf_options_page' || ( isset( $_GET['page'] ) && $_GET['page'] == 'wpo_wcpdf_options_page' ) ) ) {
			return;				
		}

		wp_enqueue_script(
			'wcpdf-file-upload-js',
			WPO_WCPDF_Pro()->plugin_url() . '/assets/js/file-upload.js',
			array(),
			WPO_WCPDF_PRO_VERSION
		);

		wp_enqueue_style(
			'wcpdf-pro-settings-styles',
			WPO_WCPDF_Pro()->plugin_url() . '/assets/css/settings-styles.css',
			array(),
			WPO_WCPDF_PRO_VERSION
		);

		wp_enqueue_script(
			'wcpdf-pro-settings-js',
			WPO_WCPDF_Pro()->plugin_url() . '/assets/js/pro-settings.js',
			array(),
			WPO_WCPDF_PRO_VERSION
		);
		wp_localize_script(
			'wcpdf-pro-settings-js',
			'wpo_wcpdf_pro_settings',
			array(
				'ajaxurl'                   => admin_url( 'admin-ajax.php' ), // URL to WordPress ajax handling page
				'nonce'                     => wp_create_nonce( 'wpo_wcpdf_pro_settings' ),
				'unique_identifier_warning' => sprintf(
					/* translators: 1. order number placeholder, 2. document number placeholder */
					__( 'Warning! Your filename does not contain a unique identifier (%1$s, %2$s), or it is incorrectly formatted.', 'wpo_wcpdf_pro' ),
					'<code>{{order_number}}</code>',
					'<code>{{document_number}}</code>'
				),
				'incorrect_brace_warning'   => __( 'Warning! It looks like you have used incorrect braces in your filename. Make sure to use double curly braces.', 'wpo_wcpdf_pro' ),
				'copied'                    => __( 'Copied', 'wpo_wcpdf_pro' ),
			)
		);

		if ( class_exists( '\\SitePress' ) || class_exists( '\\Polylang' ) || class_exists( '\\TRP_Translate_Press' ) ) {
			wp_enqueue_style(
				'wcpdf-i18n',
				WPO_WCPDF_Pro()->plugin_url() . '/assets/css/wcpdf-i18n.css',
				array(),
				WPO_WCPDF_PRO_VERSION
			);
			wp_enqueue_script(
				'wcpdf-i18n-settings',
				WPO_WCPDF_Pro()->plugin_url() . '/assets/js/wcpdf-i18n-settings.js',
				array( 'jquery', 'jquery-ui-tabs' ),
				WPO_WCPDF_PRO_VERSION
			);
			wp_localize_script(
				'wcpdf-i18n-settings',
				'wpo_wcpdf_i18n',
				array(  
					'ajaxurl'        => admin_url( 'admin-ajax.php' ), // URL to WordPress ajax handling page
					'nonce'          => wp_create_nonce('wcpdf_i18n_translations'),
					'translate_text' => __( 'Translate', 'wpo_wcpdf_pro' ),
					// 'icon'		=> WPO_WCPDF_Pro()->plugins_url() . '/images/some-img.png',
				)
			);
		}

		wp_enqueue_media();
	}

	/**
	 * Requirements callback.
	 */
	public function requirements_callback( $args ) {

		$document_settings = get_option( 'wpo_wcpdf_documents_settings_'.$args['document_type'] );
		$current_set_requirements = 0;

		printf( '<select id="%s">', $args['id'] );
		printf( '<option selected="selected" disabled="disabled" value="">%s</option>', __( 'Select additional requirements' , 'wpo_wcpdf_pro' ) );

		foreach ( $args['requirements'] as $requirement ) {
			$disabled = '';
			if ( $requirement['args']['id'] !== 'disable_for_require' ) {			
				if ( isset( $document_settings[$requirement['args']['id']] ) ) {
					$disabled = 'disabled="disabled"';
					$current_set_requirements++;
				}
				printf( '<option value="%s" %s>%s</option>', $requirement['args']['id'], $disabled, $requirement['title'] );
			}
		}
		echo '</select>';

		?>
		<div class="requirements" <?php echo $current_set_requirements === 0 ? 'style="display: none"' : ''; ?>>
		<?php 

		foreach ( $args['requirements'] as $requirement ) {
			$hidden = !isset( $document_settings[$requirement['args']['id']] ) || ( $requirement['args']['id'] == 'disable_for_require' && $current_set_requirements < 2 ) ? 'style="display: none"' : '';

			printf( '<div class="requirement" data-requirement_id="%s" %s><p>%s</p>', $requirement['args']['id'], $hidden, $requirement['title'] );
			if ( isset( $requirement['callback'] ) ) {
				$callback = $requirement['callback'];
				WPO_WCPDF()->settings->callbacks->$callback( $requirement['args'] );
			}
			echo $requirement['args']['id'] !== 'disable_for_require' ? '<span class="dashicons dashicons-trash remove-requirement"></span></div>' : '</div>';
		}
		echo '</div>';
	}

	public function get_payment_gateways() {
		$payment_gateways = array();
		foreach ( WC()->payment_gateways->payment_gateways() as $gateway ) {
			$payment_gateways[$gateway->id] = $gateway->get_title();
		}

		$payment_gateways['n/a'] = __( 'Not available (N/A)', 'wpo_wcpdf_pro' );

		return $payment_gateways;
	}

	public function disable_document_for( $allowed, $document ) {
		if ( ! $document->exists() && ! empty( $document->order ) ) {
			// Reset the status requirement from the free plugin
			if ( $document->is_enabled() && $allowed === false ) {
				$allowed = true;
			}

			// Get latest document settings
			$document_settings = $document->get_settings( true );

			$requirements = array(
				'disable_for_statuses'          => 'get_status',
				'disable_for_payment_methods'   => 'get_payment_method',
				'disable_for_billing_countries' => 'get_billing_country',
			);

			if ( ! empty( $set_requirements = array_intersect_key( $requirements, $document_settings ) ) ) {
				$require_all = isset( $document_settings['disable_for_require'] ) && $document_settings['disable_for_require'] == 'all' ? true : false;

				foreach ( $set_requirements as $requirement => $getter ) {
					$requirement_settings = $document_settings[ $requirement ];

					if ( 'disable_for_statuses' === $requirement ) {
						$requirement_settings = array_map( function( $status ) {
							return ( 'wc-' === substr( $status, 0, 3 ) ) ? substr( $status, 3 ) : $status;
						}, $document_settings[ $requirement ] );
					}
					
					$order = $document->order;
			
					if ( $order instanceof \WC_Order_Refund ) { // credit note
						$order = wc_get_order( $order->get_parent_id() );
					}

					if ( is_callable( array( $order, $getter ) ) ) {
						$value = $order->$getter();

						// 'N/A' order payment method results in an empty string if we call $order->get_payment_method()
						// and therefore, we need to set the $value to 'n/a' in that case.
						if ( 'disable_for_payment_methods' === $requirement && '' === $value ) {
							$value = 'n/a';
						}

						if ( $require_all ) {
							if ( ! in_array( $value, $requirement_settings ) ) {
								return $allowed;
							}
						} elseif ( in_array( $value, $requirement_settings ) ) {
							return false;
						}
					}
				}
				if ( $require_all ) {
					// If we got here requirements were set and were all met
					return false;
				}
			}
		} 
		return $allowed;
	}

	public function preview_excluded_pro_settings( $excluded_settings ) {
		$excluded_pro_settings = array(
			'disable_for_require',
			'disable_for_payment_methods',
			'disable_for_billing_countries',
			'due_date_allowed_statuses',
			'due_date_allowed_payment_methods',
			'filename',
		);

		foreach ( $excluded_pro_settings as $excluded_pro_setting ) {
			if ( ! in_array( $excluded_pro_setting, $excluded_settings ) ) {
				$excluded_settings[] = $excluded_pro_setting;
			}
		}

		return $excluded_settings;
	}

	/**
	 * File upload callback.
	 *
	 * @param array $args Field arguments.
	 * 
	 * @return void.
	 */
	public function file_upload_callback( array $args ): void {
		extract( WPO_WCPDF()->settings->callbacks->normalize_settings_args( $args ) );
		
		$options         = get_option( $menu );
		$is_multilingual = class_exists( '\\SitePress' ) || class_exists( '\\Polylang' ) || class_exists( '\\TRP_Translate_Press' );
	
		// multilingual file
		if ( $is_multilingual && isset( $lang ) && isset( $options[ $id ][ $lang ] ) ) {
			$current = $options[ $id ][ $lang ];
			
		// non-multilingual file
		} elseif ( ! $is_multilingual && isset( $options[ $id ] ) ) {
			$current = $options[ $id ];
			
		// no file set
		} else {
			$current = array(
				'id'       => '',
				'filename' => '',
			);
		}

		printf( '<input id="%1$s_id" name="%2$s[%1$s][id]" value="%3$s" type="hidden"/>', $id, $menu, $current['id'] );
		printf( '<input id="%1$s_filename" name="%2$s[%1$s][filename]" size="50" value="%3$s" readonly="readonly"/>', $id, $menu, $current['filename'] );
		if ( ! empty( $current['id'] ) ) {
			printf( '<span class="button remove_file_button" data-input_id="%1$s">%2$s</span>', $id, $remove_button_text );
		}
		printf( '<span class="button upload_file_button %4$s" data-uploader_title="%1$s" data-uploader_button_text="%2$s" data-remove_button_text="%3$s" data-input_id="%4$s">%2$s</span>', $uploader_title, $uploader_button_text, $remove_button_text, $id );

		// Displays option description.
		if ( isset( $description ) ) {
			printf( '<p class="description">%s</p>', $description );
		}
	}

	/**
	 * Multiple file upload callback.
	 *
	 * @param array $args Field arguments.
	 * 
	 * @return void.
	 */
	public function multiple_file_upload_callback( array $args ): void {
		extract( WPO_WCPDF()->settings->callbacks->normalize_settings_args( $args ) );
		
		$options         = get_option( $option_name );
		$is_multilingual = class_exists( '\\SitePress') || class_exists( '\\Polylang' ) || class_exists( '\\TRP_Translate_Press' );

		// multilingual file
		if ( $is_multilingual && isset( $lang ) && isset( $options[ $id ][ $lang ] ) ) {
			$current = $options[ $id ][ $lang ];
			
		// non-multilingual file
		} elseif ( ! $is_multilingual && isset( $options[ $id ] ) ) {
			$current = $options[ $id ];
			
		// no file set
		} else {
			$current = array(
				'id'       => '',
				'filename' => '',
			);
		}
		
		$total_files_number = $total_files_number ?? 3;

		for ( $i = 0; $i < $total_files_number; $i++ ) {
			$file_id  = isset( $current[ $i ] ) ? $current[ $i ]['id'] : '';
			$filename = isset( $current[ $i ] ) ? $current[ $i ]['filename'] : '';

			echo '<div class="static-file-row">';
			printf( '<input id="%1$s_%2$s_id" name="%3$s[%2$s][id]" value="%4$s" type="hidden" class="static-file-id"/>', $id, $i, $setting_name, $file_id );
			printf( '<input id="%1$s_%2$s_filename" name="%3$s[%2$s][filename]" size="50" value="%4$s" type="text" readonly="readonly" class="static-file-filename"/>', $id, $i, $setting_name, $filename );
			if ( ! empty( $file_id ) ) {
				printf( '<span class="button remove_file_button" data-input_id="%1$s_%2$s">%3$s</span>', $id, $i, $remove_button_text );
			}
			printf( '<span class="button upload_file_button %4$s" data-uploader_title="%1$s" data-uploader_button_text="%2$s" data-remove_button_text="%3$s" data-input_id="%4$s_%5$s">%2$s</span>', $uploader_title, $uploader_button_text, $remove_button_text, $id, $i );
			echo '</div>';
		}
	
		// Displays option description.
		if ( isset( $description ) ) {
			printf( '<p class="description">%s</p>', $description );
		}
	}

	/**
	 * Display placeholders for Custom Address fields.
	 *
	 * @return string.
	 */
	public function custom_address_fields_section(): string {
		$placeholders = array(
			'billing' => array(
				'billing_address',
				'billing_first_name',
				'billing_last_name',
				'billing_company',
				'billing_address_1',
				'billing_address_2',
				'billing_city',
				'billing_postcode',
				'billing_country',
				'billing_country_code',
				'billing_state',
				'billing_state_code',
				'billing_email',
				'billing_phone',
			),
			'shipping' => array(
				'shipping_address',
				'shipping_first_name',
				'shipping_last_name',
				'shipping_company',
				'shipping_address_1',
				'shipping_address_2',
				'shipping_city',
				'shipping_postcode',
				'shipping_country',
				'shipping_country_code',
				'shipping_state',
				'shipping_state_code',
			),
			'custom_fields' => array(
				'custom_field_name'
			)
		);

		ob_start();
		?>
		<p><?php esc_html_e( 'Customize the formatting of shipping and billing addresses in PDF documents, and add custom fields as needed.', 'wpo_wcpdf_pro') ?></p>
		<p>
			<?php
				printf(
					/* translators: %s: HTML tags */
					esc_html__( 'You can use the placeholders below along with regular text and HTML tags such as %s, and others.', 'wpo_wcpdf_pro'),
					'<code>' . implode( '</code>, <code>', array_map( 'esc_html', array( '<h1>', '<h2>', '<b>' ) ) ) . '</code>'
				);
			?>
		</p>
		<p>
			<?php
				printf(
					/** translators: %s: placeholder */
					esc_html__( 'You can also add your own custom fields using the double brace syntax, e.g., %s, replacing %s with the actual meta key of your custom field.' ),
					'<code>{{custom_field_name}}</code>',
					'<code>custom_field_name</code>'
				);
			?>
		</p>
		<div class="wpo-wcpdf-accordion">
			<h3 class="header"><?php esc_html_e( 'Billing fields', 'wpo_wcpdf_pro' ); ?></h3>
			<div class="content">
				<ul class="wpo-wcpdf-placeholders">
				<?php foreach ( $placeholders['billing'] as $placeholder ) : ?>
					<li class="placeholder-container">
						<button class="wpo-wcpdf-copy-button" title="<?php esc_attr_e( 'Copy to clipboard', 'wpo_wcpdf_pro'); ?>"></button>
						<span class="wpo-wcpdf-copy-value">{{<?php echo esc_html( $placeholder ); ?>}}</span>
					</li>
				<?php endforeach; ?>
				</ul>
			</div>
		</div>
		<div class="wpo-wcpdf-accordion">
			<h3 class="header"><?php esc_html_e( 'Shipping fields', 'wpo_wcpdf_pro' ); ?></h3>
			<div class="content">
				<ul class="wpo-wcpdf-placeholders">
				<?php foreach ( $placeholders['shipping'] as $placeholder ) : ?>
					<li class="placeholder-container">
						<button class="wpo-wcpdf-copy-button" title="<?php esc_attr_e( 'Copy to clipboard', 'wpo_wcpdf_pro'); ?>"></button>
						<span class="wpo-wcpdf-copy-value">{{<?php echo esc_html( $placeholder ); ?>}}</span>
					</li>
				<?php endforeach; ?>
				</ul>
			</div>
		</div>
		<div class="wpo-wcpdf-accordion">
			<h3 class="header"><?php esc_html_e( 'Custom fields', 'wpo_wcpdf_pro' ); ?></h3>
			<div class="content">
				<ul class="wpo-wcpdf-placeholders">
				<?php foreach ( $placeholders['custom_fields'] as $placeholder ) : ?>
					<li class="placeholder-container">
						<button class="wpo-wcpdf-copy-button" title="<?php esc_attr_e( 'Copy to clipboard', 'wpo_wcpdf_pro'); ?>"></button>
						<span class="wpo-wcpdf-copy-value">{{<?php echo esc_html( $placeholder ); ?>}}</span>
					</li>
				<?php endforeach; ?>
				</ul>
			</div>
		</div>
		<p><?php esc_html_e( 'Leave empty to use the default formatting.', 'wpo_wcpdf_pro' ); ?></p>
		<?php

		return ob_get_clean();
	}

	public function filename_existence_check() {
		check_ajax_referer( 'wpo_wcpdf_pro_settings', 'nonce' );

		if( empty( $_POST['filename'] ) || empty( $_POST['document_type'] || empty( $_POST['language'] ) ) ) {
			die();
		}

		$filename      = sanitize_text_field( $_POST['filename'] );
		$document_type = sanitize_text_field( $_POST['document_type'] );
		$language      = sanitize_text_field( $_POST['language'] );
		$documents     = WPO_WCPDF()->documents->get_documents();

		foreach ( $documents as $document ) {
			if ( $document->type != $document_type ) {
				$custom_filename = $document->get_settings_text( 'filename', false, false );
				if ( ! empty( WPO_WCPDF_Pro()->multilingual_full ) && 'default' !== $language ) {
					if ( class_exists( __NAMESPACE__ . '\\Language_Switcher' ) ) {
						$custom_filename = Language_Switcher::get_i18n_setting( 'filename', $custom_filename, $document, $language );
					} else {
						if ( function_exists( 'wcpdf_log_error' ) ) {
							wcpdf_log_error( sprintf(
								'[%s] Language_Switcher class not found while trying to localize "filename" for document "%s" (order #%d, language "%s") — using fallback filename.',
								__METHOD__,
								method_exists( $document, 'get_type' ) ? $document->get_type() : 'unknown',
								( isset( $document->order ) && is_object( $document->order ) && method_exists( $document->order, 'get_id' ) )
									? (int) $document->order->get_id()
									: 0,
								is_string( $language ) ? $language : 'unknown'
							) );
						}
					}
				}

				if ( $custom_filename == $filename ) {
					/* translators: document title */
					wp_send_json( array( 'error' => sprintf( __( 'This filename is already in use in the %s document! Please choose a new unique filename.', 'wpo_wcpdf_pro' ), $document->title ) ) );
				}
			}
		}

		wp_send_json( array( 'success' => __( 'Filename is unique!', 'wpo_wcpdf_pro' ) ) );

		die();
	}

	public function non_historical_pro_settings( $settings ) {
		$settings[] = 'auto_generate_for_statuses';
		return $settings;
	}

	/**
	 * Get the available languages for multilingual documents.
	 *
	 * @return array
	 */
	private function get_multilingual_document_language_options(): array {
		// Retrieve available languages
		$languages = function_exists( 'wpo_wcpdf_get_multilingual_languages' ) ? wpo_wcpdf_get_multilingual_languages() : array();
		if ( empty( $languages ) ) {
			$available_locales = WPO_WCPDF_Pro()->functions->get_wp_available_languages();
			foreach ( $available_locales as $locale ) {
				$wp_languages_list  = WPO_WCPDF_Pro()->functions->get_wp_language_list();
				if ( ! empty( $wp_languages_list[ $locale ] ) && ! empty( $wp_languages_list[ $locale ]['native_name'] ) ) {
					$languages[ $locale ] = $wp_languages_list[ $locale ]['native_name'];
				}
			}
		}
	
		// Retrieve user language settings
		$user_language = array();
		if ( ! class_exists( '\\SitePress' ) && ! class_exists( '\\Polylang' ) && ! class_exists( '\\TRP_Translate_Press' ) ) {
			$user_language = array(
				'user' => __( 'Active user language', 'wpo_wcpdf_pro' ),
			);
		}
	
		// Retrieve multilingual plugins with HTML support
		$multilingual_html_plugins = array();
		foreach ( WPO_WCPDF_Pro()->functions->get_active_multilingual_plugins() as $slug => $plugin ) {
			if ( 'html' === $plugin['support'] ) {
				$multilingual_html_plugins[ $slug ] = sprintf(
					/* translators: multilingual plugin name */
					__( '%s order language', 'wpo_wcpdf_pro' ),
					$plugin['name']
				);
			}
		}
	
		// Merge all options into a single array
		return array( '' => __( 'Select...', 'wpo_wcpdf_pro' ) ) 
			+ $multilingual_html_plugins 
			+ $user_language 
			+ array(
				'order' => __( 'Order/customer language', 'wpo_wcpdf_pro' ),
				'admin' => __( 'Site default language', 'wpo_wcpdf_pro' ),
			) 
			+ $languages;
	}

	/**
	 * Show zero taxes in the document.
	 * 
	 * @param array $filters
	 * @param object $document
	 * 
	 * @return array
	 */
	public function show_zero_taxes( array $filters, object $document ): array {
		if (
			! in_array( $document->get_type(), array( 'bulk', 'summary' ) ) &&
			is_callable( array( $document, 'get_setting' ) ) &&
			! empty( $document->get_setting( 'show_zero_taxes' ) )
		) {
			$filters[] = array(
				'hook_name'     => 'woocommerce_order_hide_zero_taxes',
				'callback'      => function( $return ) use ( $document ) {
					return ! wc_string_to_bool( $document->get_setting( 'show_zero_taxes' ) );
				},
				'priority'      => 10,
				'accepted_args' => 1
			);
		}
	
		return $filters;
	}

	/**
	 * Add Pro settings to the debug tab.
	 *
	 * @param array $settings_fields
	 * @param string $page
	 * @param string $option_group
	 * @param string $option_name
	 *
	 * @return array
	 */
	public function add_pro_debug_settings( array $settings_fields, string $page, string $option_group, string $option_name ): array {
		$rest_api_setting_field = array(
			'type'     => 'setting',
			'id'       => 'enable_rest_api',
			'title'    => __( 'Enable REST API', 'wpo_wcpdf_pro' ),
			'callback' => 'checkbox',
			'section'  => 'debug_settings',
			'args'     => array(
				'option_name' => $option_name,
				'id'          => 'enable_rest_api',
				'disabled'    => WPO_WCPDF_Pro()->dependencies->is_rest_api_supported() ? '' : 'disabled',
				'description' => WPO_WCPDF_Pro()->dependencies->is_rest_api_supported()
					? sprintf(
						/* translators: 1, 2. Opening anchor tag, 3. Closing anchor tag */
						__( 'Enable to allow operations on documents using REST API. %1$sSee documentation.%3$s<br>This plugin uses the WooCommerce REST API to work, you can enable it %2$shere%3$s.', 'wpo_wcpdf_pro' ),
						'<a href="https://docs.wpovernight.com/woocommerce-pdf-invoices-packing-slips/using-the-rest-api/" target="_blank">',
						'<a href="' . esc_url( admin_url( 'admin.php?page=wc-settings&tab=advanced&section=keys' ) ) . '">',
						'</a>'
					)
					: sprintf(
						/* translators: WordPress version */
						esc_html__( 'The REST API requires WordPress %s or higher.', 'wpo_wcpdf_pro' ),
						'<strong>' . WPO_WCPDF_Pro()->dependencies->rest_api_wp_min_version . '</strong>'
					)
			)
		);

		$danger_zone_key = null;

		foreach ( $settings_fields as $index => $setting_field ) {
			if ( ! empty( $setting_field['id'] ) && 'enable_danger_zone_tools' === $setting_field['id'] ) {
				$danger_zone_key = $index;
			}
		}

		if ( ! is_null( $danger_zone_key ) ) {
			// Insert the new array before the Danger zone.
			array_splice( $settings_fields, $danger_zone_key, 0, array( $rest_api_setting_field ) );
		} else {
			// If Danger zone not found, just append to the end.
			$settings_fields[] = $rest_api_setting_field;
		}

		return $settings_fields;
	}
	
	/**
	 * Add Pro settings categories to the debug tab.
	 * 
	 * @param array $categories
	 * @return array
	 */
	public function add_pro_debug_settings_categories( array $settings_categories ): array {
		$settings_categories = WPO_WCPDF()->settings->add_single_setting_field_to_category(
			$settings_categories, 
			'enable_rest_api', 
			'advanced_experimental',
			1
		);

		return apply_filters( 'wpo_wcpdf_pro_debug_settings_categories', $settings_categories );
	}

} // end class

endif; // class_exists

return new Settings();