<?php
/**
 * filtersFront.php
 *
 * @author     alfiopiccione <alfio.piccione@gmail.com>
 * @license    http://opensource.org/licenses/gpl-2.0.php GPL v2
 *
 * Copyright (C) 2025 POP
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

use POPxPMPro\Functions\Utils;
use WcElectronInvoice\WooCommerce\Fields\GeneralFields;

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

//
//  array(
//      'filter'        => '',
//      'callback'      => '',
//      'priority'      => '',
//      'accepted_args' => '',
//  )
//
$orderProvider    = new \POPxPMPro\Providers\OrdersProvider();
$productsProvider = new \POPxPMPro\Providers\ProductsProvider();
$taxesProvider    = new \POPxPMPro\Providers\TaxesProvider();

$filters = array(
	'front' => array(
		'action' => array(

			// registering orders provider for PMS
			// registering here for xml and pdf preview and export
			array(
				'filter'        => 'wc_el_inv-enqueue_orders_provider',
				'callback'      => array( $orderProvider, 'enqueue' ),
				'priority'      => 11,
				'accepted_args' => 1,
			),

			// todo: save discount total and tax rate in payment meta
			/*
			array(
				'filter'        => 'pms_payment_insert',
				'callback'      => array($orderProvider, 'on_payment_insert'),
				'priority'      => 100,
				'accepted_args' => 2,
			),
			*/

			// registering the products provider for PMS
			// registering in the front filters for XML and PDF preview and export
			array(
				'filter'        => 'wc_el_inv-enqueue_products_provider',
				'callback'      => array( $productsProvider, 'enqueue' ),
				'priority'      => 10,
				'accepted_args' => 1,
			),

			// registering the taxes provider for PMS
			// registering in the front filters for XML and PDF preview and export
			array(
				'filter'        => 'wc_el_inv-enqueue_taxes_provider',
				'callback'      => array( $taxesProvider, 'enqueue' ),
				'priority'      => 10,
				'accepted_args' => 1,
			),

			// todo: validate vat number
			/*
			array(
				'filter'        => array(
					'pms_payment_insert',
					'pms_member_subscription_update',
				),
				'callback'      => function ($payID, $data) {
					$country              = \WcElectronInvoice\Functions\filterInput($_POST, 'billing_country') ?: false;
					$vatNumber            = \WcElectronInvoice\Functions\filterInput($_POST, 'billing_vat_number') ?: false;
					$customerInvoiceType  = \WcElectronInvoice\Functions\filterInput($_POST, 'billing_invoice_type') ?: false;

					if (! $country && ! $vatNumber) {
						return false;
					}

					// Set prefix type used for retrieved nature or ref normative value
					$prefix = null;
					if (in_array($country, WcElectronInvoice\WooCommerce\Fields\GeneralFields::getEuCountries(),
						true)) {
						$prefix = 'ue_';
					} elseif (! in_array($country, WcElectronInvoice\WooCommerce\Fields\GeneralFields::getEuCountries(),
						true)) {
						$prefix = 'extra_ue_';
					}

					// Set type
					switch ($customerInvoiceType) {
						case 'company':
						case 'freelance':
							$type = 'company';
							break;
						default:
							$type = 'private';
							break;
					}

					$vatNumber = str_replace( $country, '', $vatNumber );

					$vies = false;
					if ( ! empty( $vatNumber ) && in_array( $customerInvoiceType, [ 'company', 'freelance' ] ) ) {
						$vies = InvoiceFields::viesCheck( $vatNumber, $country );
					}

					if ($vies) {
						if ($prefix) {
							$nature            = WcElectronInvoice\WooCommerce\Fields\TaxFields::getReverseChargeNature("{$prefix}{$type}");
							$refNormative      = WcElectronInvoice\WooCommerce\Fields\TaxFields::getReverseChargeRefNormative("{$prefix}{$type}");
							$refNormativeValue = esc_html($refNormative);

							$nature = apply_filters('wc_el_inv-before_nature_rc_pmpro_save', $nature, $payID, $data);
							if ('' !== $nature) {
								update_pmpro_membership_order_meta($payID, 'nature_rc', $nature);
							}
							if ('' !== $refNormativeValue) {
								$refNormativeValue = apply_filters('wc_el_inv-before_ref_norm_rc_pmpro_save', $refNormativeValue, $payID, $data);
								update_pmpro_membership_order_meta($payID, 'ref_norm_rc', $refNormativeValue);
							}
						}
						update_pmpro_membership_order_meta($payID, 'order_vies_check', true);
					} else {
						update_pmpro_membership_order_meta($payID, 'order_vies_check', false);
					}

					$order         = \WcElectronInvoice\Providers\OrderQuery::instance()->getProviderOrder($payID, 'pmpro');
					$numberInvoice = $order->get_meta('order_number_invoice') ?: null;
					if ($order instanceof POPxPMPro\Providers\Order && ! $numberInvoice) {
						$numerationType = $order->get_billing_choice_type() ?: 'invoice';
						$number         = \WcElectronInvoice\Functions\getNextInvoiceNumber("number_next_{$numerationType}");
						if ($number) {
							// Set invoice number for order.
							$order->update_meta('order_number_invoice', $number);
							// Set formatted number
							\WcElectronInvoice\Functions\setFormattedInvoiceNumber($order, $numerationType);
							// Save
							$order->save();
						}
					}
				},
				'priority'      => 99,
				'accepted_args' => 2,
			),
			*/

			// Bollo
			array(
				'filter'   => 'pmpro_checkout_after_level_cost',
				'callback' => function ( $level ) {
					Utils::pmProShowStampDutyNotice( $level );
				},
				'priority' => 10,
			),
			array(
				'filter'   => 'pmpro_invoice_bullets_bottom',
				'callback' => function ( $invoice ) {
					Utils::pmProShowInOrderStampDutyNotice( $invoice );
				},
				'priority' => 10,
			),

			// Rivalsa INPS
			array(
				'filter'   => 'pmpro_checkout_after_level_cost',
				'callback' => function ( $level ) {
					Utils::pmProShowRivalsaNotice( $level );
				},
				'priority' => 10,
			),
			array(
				'filter'   => 'pmpro_invoice_bullets_bottom',
				'callback' => function ( $invoice ) {
					Utils::pmProShowInOrderRivalsaNotice( $invoice );
				},
				'priority' => 10,
			),

			/**
			 * After checkout
			 */
				array(
					'filter'        => 'pmpro_after_checkout',
					'callback'      => function ( $user_id, \MemberOrder $order ) {
						if ( empty( $_POST ) || ! $order->id ) {
							return;
						}

						$isPeppolContext = \WcElectronInvoice\Integrations::isPeppolContext();

					// Checkout fields update order metas + user metas
					$meta_keys = [ 'billing_choice_type', 'billing_invoice_type', 'billing_sdi_type', 'billing_vat_number', 'billing_company', 'billing_tax_code' ];
						foreach ( $meta_keys as $meta_key ) {
							if ( ! empty( $_POST[ $meta_key ] ) ) {
								$meta_value = \WcElectronInvoice\Functions\filterInput( $_POST, $meta_key ) ?: false;
								update_pmpro_membership_order_meta( $order->id, $meta_key, $meta_value );

							if ( $order->user_id ) {
								update_user_meta( $order->user_id, $meta_key, $meta_value );
							}
						}

					}

					// Checkout fields update order metas + user metas (PMPro field names -> billing_* metas)
					$billing_map = [
						'billing_firstname' => 'bfirstname',
						'billing_lastname'  => 'blastname',
						'billing_address1'  => 'baddress1',
						'billing_address2'  => 'baddress2',
						'billing_city'      => 'bcity',
						'billing_state'     => 'bstate',
						'billing_postcode'  => 'bzipcode',
						'billing_country'   => 'bcountry',
						'billing_phone'     => 'bphone',
					];
					// Map billing_* to PMPro default b* meta for user sync
					$pmpro_meta_map = [
						'billing_firstname' => 'pmpro_bfirstname',
						'billing_lastname'  => 'pmpro_blastname',
						'billing_address1'  => 'pmpro_baddress1',
						'billing_address2'  => 'pmpro_baddress2',
						'billing_city'      => 'pmpro_bcity',
						'billing_state'     => 'pmpro_bstate',
						'billing_postcode'  => 'pmpro_bzipcode',
						'billing_country'   => 'pmpro_bcountry',
						'billing_phone'     => 'pmpro_bphone',
					];

						foreach ( $billing_map as $meta_key => $request_key ) {
							$raw_value = \WcElectronInvoice\Functions\filterInput( $_POST, $request_key ) ?: \WcElectronInvoice\Functions\filterInput( $_POST, $meta_key );
							if ( ! empty( $raw_value ) ) {
							$meta_value = stripslashes( sanitize_text_field( $raw_value ) );
							update_pmpro_membership_order_meta( $order->id, $meta_key, $meta_value );

							if ( $order->user_id ) {
								update_user_meta( $order->user_id, $meta_key, $meta_value );

								// keep PMPro default b* metas in sync
								if ( isset( $pmpro_meta_map[ $meta_key ] ) ) {
									update_user_meta( $order->user_id, $pmpro_meta_map[ $meta_key ], $meta_value );
								}
							}
						}

						$customerInvoiceTypeForReset = \WcElectronInvoice\Functions\filterInput( $_POST, 'billing_invoice_type' );
						if ( $isPeppolContext && 'private' === $customerInvoiceTypeForReset ) {
							update_pmpro_membership_order_meta( $order->id, 'billing_company', '' );
							if ( $order->user_id ) {
								update_user_meta( $order->user_id, 'billing_company', '' );
							}
						}
					}

					// Maybe calculate fees
					$enable_tax_calculation = get_option( 'pop_pmpro_enable_tax_calculation' );
					if ( !$enable_tax_calculation && GeneralFields::isItalianShop() ) {
						Utils::pmProSaveFeesCheckout( $order );
					}

					// Calculate natura / rif normativa
					$countryRequest      = \WcElectronInvoice\Functions\filterInput( $_POST, 'bcountry' ) ?: \WcElectronInvoice\Functions\filterInput( $_POST, 'billing_country' );
					$vatNumber           = \WcElectronInvoice\Functions\filterInput( $_POST, 'billing_vat_number' ) ?: false;
					$customerInvoiceType = \WcElectronInvoice\Functions\filterInput( $_POST, 'billing_invoice_type' ) ?: false;

					// 1. request/order
					$countryOrder = $countryRequest ?: get_pmpro_membership_order_meta( $order->id, 'billing_country', true );
					if ( empty( $countryOrder ) && isset( $order->billing->country ) ) {
						$countryOrder = $order->billing->country;
					}

					// 2. member PMPro
					$countryMember = $order->user_id ? get_user_meta( $order->user_id, 'pmpro_bcountry', true ) : '';

					// 3. user (only if consistent)
					$countryUser = $order->user_id ? get_user_meta( $order->user_id, 'billing_country', true ) : '';

					$country = $countryOrder;
					if ( empty( $country ) && $countryMember ) {
						$country = $countryMember;
					}
					if ( empty( $country ) && $countryUser && ( empty( $countryMember ) || $countryUser === $countryMember ) ) {
						$country = $countryUser;
					}

					$country = $country ?: false;

					Utils::pmProSaveOrderNaturaRifNorm( $order, $country, $vatNumber, $customerInvoiceType );
				},
				'priority'      => 99,
				'accepted_args' => 2,
			),
		),
		'filter' => array(

            // Force pmpro billing fields
            array(
                'filter'   => 'pmpro_include_billing_address_fields',
                'callback' => function ( $include ) {
                    $gateway = pmpro_getGateway();
                    if($gateway == "check") {
                        return true;
                    }

                    return $include;
                },
                'priority' => 100,
            ),

			// Rivalsa INPS
			array(
				'filter'   => 'pmpro_checkout_level',
				'callback' => function ( $level ) {
					return Utils::pmProAddRivalsaFee( $level );
				},
				'priority' => 10,
			),

            // Bollo (si aggiunge dopo la rivalsa per non entrare nel calcolo)
            array(
                'filter'   => 'pmpro_checkout_level',
                'callback' => function ( $level ) {
                    return Utils::pmProAddStampDutyFee( $level );
                },
                'priority' => 20,
            ),

			/*
			array(
				'filter'        => 'pms_get_tax_extra_fields',
				'callback'      => array($orderProvider, 'tax_extra_fields'),
				'priority'      => 99,
				'accepted_args' => 1,
			),
			*/

				array(
					'filter'        => 'wc_el_inv-scripts_list',
					'callback'      => function ( $scripts ) {
						$dev = 'dev' === WC_EL_INV_ENV;
						$isSdiContext = \WcElectronInvoice\Integrations::isSdiContext();
						$activeJsCfCheck = \WcElectronInvoice\Admin\Settings\OptionPage::init()->getOptions('invoice_active_js_cf_check');
						$loadCfScript = $isSdiContext && 'on' === $activeJsCfCheck;
						$script_path = \POPxPMPro\Plugin::getPluginDirPath( 'assets/js/pmpro-invoiceFields.js' );
						$script_file = \POPxPMPro\Plugin::getPluginDirUrl( 'assets/js/pmpro-invoiceFields.js' );
						if ( file_exists( \POPxPMPro\Plugin::getPluginDirPath( 'assets/js/pmpro-invoiceFields.min.js' ) ) ) {
							$script_path = \POPxPMPro\Plugin::getPluginDirPath( 'assets/js/pmpro-invoiceFields.min.js' );
							$script_file = \POPxPMPro\Plugin::getPluginDirUrl( 'assets/js/pmpro-invoiceFields.min.js' );
						}
						$script_ver = $dev ? time() : ( file_exists( $script_path ) ? filemtime( $script_path ) : WC_EL_INV_VERSION );

						return array_merge( $scripts, array(
							array(
								'handle'    => 'wc_el_inv_cf',
								'file'      => \WcElectronInvoice\Plugin::getPluginDirUrl( 'assets/js/cf/codice-fiscale.js' ),
								'deps'      => array(),
								'ver'       => $dev ? time() : WC_EL_INV_VERSION,
								'in_footer' => true,
								'enqueue'   => $loadCfScript && pmpro_is_checkout(),
							),
							array(
								'handle'    => 'wc_el_inv_invoice',
								'file'      => $script_file,
								'deps'      => array(),
								'ver'       => $script_ver,
								'in_footer' => true,
								'enqueue'   => pmpro_is_checkout(),
							),
						) );
					},
				'priority'      => 99,
				'accepted_args' => 1,
			),

			// todo: move this to an object for all providers, not provider-specific.
			array(
				'filter'        => 'wc_el_inv-scripts_localize_list',
				'callback'      => function ( $scripts ) {
					$scripts['wc_el_inv_invoice'] = array_merge( $scripts['wc_el_inv_invoice'], array(
						'pop_invalid_tax_code'   => __( 'Please enter a valid Tax Code.', WC_EL_INV_TEXTDOMAIN ),
						'pop_invalid_vat_number' => __( 'Please enter a valid VAT number.', WC_EL_INV_TEXTDOMAIN ),
						'pop_invalid_sdi_pec'    => __( 'Enter a valid SDI code or PEC address.', WC_EL_INV_TEXTDOMAIN ),
					) );

					return $scripts;
				},
				'priority'      => 99,
				'accepted_args' => 1,
			),
		),
	),
);

add_filter( 'wc_el_inv-filters_front', function ( $filtersFront ) use ( $filters ) {
	$filtersFront['front']['action'] = array_merge( $filtersFront['front']['action'], $filters['front']['action'] );
	$filtersFront['front']['filter'] = array_merge( $filtersFront['front']['filter'], $filters['front']['filter'] );

	return $filtersFront;
}, 10, 1 );

return $filters;
