<?php
/**
 * CWAFC_Admin_Action Class
 *
 * Handles the admin functionality.
 *
 * @package Custom Woo Addon For Ceretax
 */

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
	header( 'Status: 403 Forbidden' );
	header( 'HTTP/1.1 403 Forbidden' );
	exit;
}

if ( ! class_exists( 'CWAFC_Admin_Action' ) ) {

	/**
	 *  The CWAFC_Admin_Action Class
	 */
	class CWAFC_Admin_Action {

		/**
		 * Construct.
		 */
		public function __construct() {

			add_action( 'admin_enqueue_scripts', array( $this, 'action__cwafc_admin_init' ) );
			// Add settings fields to the new tab.
			add_action( 'woocommerce_settings_tabs_cwafc_ceretax', array( $this, 'action__cwafc_settings_tab' ) );
			// Save settings.
			add_action( 'woocommerce_update_options_cwafc_ceretax', array( $this, 'action__cwafc_update_settings' ) );
			// Display custom fields in the "General" tab of the product edit page.
			add_action( 'woocommerce_product_options_general_product_data', array( $this, 'action__cwafc_add_custom_product_fields' ) );
			// Save custom fields when the product is saved.
			add_action( 'woocommerce_process_product_meta', array( $this, 'action__cwafc_save_custom_product_fields' ) );
			// Add custom field to product category.
			add_action( 'product_cat_add_form_fields', array( $this, 'action__cwafc_add_custom_field_to_product_category' ), 10, 2 );
			add_action( 'product_cat_edit_form_fields', array( $this, 'action__cwafc_edit_custom_field_in_product_category' ), 10, 2 );
			// Save custom field to product category.
			add_action( 'created_product_cat', array( $this, 'action__cwafc_save_custom_field_in_product_category' ), 10, 2 );
			add_action( 'edited_product_cat', array( $this, 'action__cwafc_save_custom_field_in_product_category' ), 10, 2 );
			// Add admin order line item column.
			add_action( 'woocommerce_admin_order_item_headers', array( $this, 'action__cwafc_woocommerce_admin_order_item_headers' ), 20 );
			// Populate the new column with custom data.
			add_action( 'woocommerce_admin_order_item_values', array( $this, 'action__cwafc_woocommerce_admin_order_item_values' ), 10, 3 );
			// Add admin order style and script.
			add_action( 'admin_footer', array( $this, 'action__cwafc_admin_footer_function' ), 20 );
			// Add add store address validate button WC general setting tab.
			add_filter( 'woocommerce_general_settings', array( $this, 'filter__cwafc_add_store_address_validate_button' ) );
			// Add render store address validate button.
			add_action( 'woocommerce_admin_field_validate_store_address_button', array( $this, 'action__cwafc_render_store_address_validate_button' ) );
			// Validate_store_address.
			add_action( 'woocommerce_update_options_general', array( $this, 'action__cwafc_validate_store_address' ) );
			// Add custom style after total.
			add_action( 'woocommerce_admin_order_totals_after_total', array( $this, 'action__cwafc_add_after_total_style' ) );
		}

		/**
		 * Register admin min js and admin min css.
		 *
		 * @param string $hook get the settings page name.
		 * @return void
		 */
		public function action__cwafc_admin_init( $hook ) {
			if ( 'woocommerce_page_wc-settings' !== $hook ) {
				return;
			}
			wp_enqueue_script( CWAFC_PREFIX . '_admin_js', CWAFC_URL . 'assets/js/admin.js', array( 'jquery-core' ), CWAFC_VERSION, true );
			wp_enqueue_style( CWAFC_PREFIX . '_admin_css', CWAFC_URL . 'assets/css/admin.css', array(), CWAFC_VERSION );
		}

		/**
		 * Woocommerce setting tabs callback
		 *
		 * @return void
		 */
		public function action__cwafc_settings_tab() {
			woocommerce_admin_fields( $this->cwafc_get_settings() );
		}

		/**
		 * Woocommerce setting tabs save fields
		 *
		 * @return mix
		 */
		public function action__cwafc_update_settings() {

			// phpcs:disable WordPress.Security.NonceVerification.Missing -- Nonce verification already handled in WC_Admin_Settings::save()
			$cere_tax_api_key = ( null !== CWAFC_PREFIX && isset( $_POST[ CWAFC_PREFIX . '_cere_tax_api_key' ] ) ) ? sanitize_text_field( wp_unslash( $_POST[ CWAFC_PREFIX . '_cere_tax_api_key' ] ) ) : '';
			$cere_tax_tax_env = ( null !== CWAFC_PREFIX && isset( $_POST[ CWAFC_PREFIX . '_cere_tax_environment' ] ) ) ? sanitize_text_field( wp_unslash( $_POST[ CWAFC_PREFIX . '_cere_tax_environment' ] ) ) : '';
			// phpcs:enable
			$valid_api_key = $this->cwafc_is_valid_cere_tax_api_key( $cere_tax_api_key, $cere_tax_tax_env );

			if ( ! $valid_api_key ) {
				WC_Admin_Settings::add_error( __( 'API key is not valid. Please add valid API key.', 'ceretax' ) );
				return false;
			} else {
				woocommerce_update_options( $this->cwafc_get_settings() );
				WC_Admin_Settings::add_message( __( 'API key validated successfully.', 'ceretax' ) );
			}
		}

		/**
		 * Define the settings fields
		 *
		 * @return $settings
		 */
		public function cwafc_get_settings() {
			$settings = array(
				array(
					'name' => __( 'Connect to CereTax', 'ceretax' ),
					'type' => 'title',
				),

				array(
					'name'     => __( 'API Key', 'ceretax' ),
					'type'     => 'text',
					'desc'     => __( 'Enter your API key for CereTax', 'ceretax' ),
					'id'       => CWAFC_PREFIX . '_cere_tax_api_key',
					'desc_tip' => true,
					'autoload' => false,
				),

				array(
					'name'     => __( 'Environment', 'ceretax' ),
					'type'     => 'select',
					'desc'     => __( 'Select the environment', 'ceretax' ),
					'id'       => CWAFC_PREFIX . '_cere_tax_environment',
					'desc_tip' => true,
					'autoload' => false,
					'options'  => array(
						'cert'       => __( 'Cert', 'ceretax' ),
						'production' => __( 'Production', 'ceretax' ),
					),
				),

				array(
					'name'     => __( 'Profile', 'ceretax' ),
					'type'     => 'text',
					'desc'     => __( 'Enter your profile for CereTax', 'ceretax' ),
					'id'       => CWAFC_PREFIX . '_cere_tax_profile',
					'desc_tip' => true,
					'autoload' => false,
				),

				array(
					'type' => 'sectionend',
					'id'   => 'cere_tax_section_end',
				),

				array(
					'name' => __( 'General Settings', 'ceretax' ),
					'type' => 'title',
				),

				array(
					'name'    => __( 'Enable CereTax', 'ceretax' ),
					'type'    => 'checkbox',
					'id'      => CWAFC_PREFIX . '_cere_tax_enable',
					'class'   => 'cere_tax_checkbox',
					'default' => 'no',
				),

				array(
					'name'    => __( 'Disable CereTax For Refund Orders', 'ceretax' ),
					'type'    => 'checkbox',
					'id'      => CWAFC_PREFIX . '_cere_tax_refund_disable',
					'class'   => 'cere_tax_checkbox',
					'default' => 'no',
				),

				array(
					'name'    => __( 'Post finalized transactions to CereTax', 'ceretax' ),
					'type'    => 'checkbox',
					'id'      => CWAFC_PREFIX . '_cere_tax_post_transactions',
					'class'   => 'cere_tax_checkbox',
					'default' => 'no',
				),

				array(
					'name'    => __( 'Enable Logging', 'ceretax' ),
					'type'    => 'checkbox',
					'id'      => CWAFC_PREFIX . '_cere_tax_enable_logging',
					'class'   => 'cere_tax_checkbox',
					'default' => 'no',
				),

				array(
					'type' => 'sectionend',
					'id'   => 'cere_tax_section_end',
				),

				array(
					'name' => __( 'Address Validation Settings', 'ceretax' ),
					'type' => 'title',
				),

				array(
					'name'    => __( 'Validate customer and vendor addresses', 'ceretax' ),
					'type'    => 'checkbox',
					'id'      => CWAFC_PREFIX . '_cere_tax_validate_customer_addresses',
					'class'   => 'cere_tax_checkbox',
					'default' => 'no',
				),

				array(
					'name'    => __( 'Validate addresses on every transaction', 'ceretax' ),
					'type'    => 'checkbox',
					'id'      => CWAFC_PREFIX . '_cere_tax_validate_on_transaction',
					'class'   => 'cere_tax_checkbox',
					'default' => 'no',
				),

				array(
					'type' => 'sectionend',
					'id'   => 'cere_tax_section_end',
				),

				array(
					'name' => __( 'Default Settings', 'ceretax' ),
					'type' => 'title',
				),

				array(
					'name'     => __( 'Business Type', 'ceretax' ),
					'type'     => 'text',
					'desc'     => __( 'Enter your business type', 'ceretax' ),
					'id'       => CWAFC_PREFIX . '_cere_tax_business_type',
					'desc_tip' => true,
					'autoload' => false,
				),

				array(
					'name'     => __( 'Customer Type', 'ceretax' ),
					'type'     => 'text',
					'desc'     => __( 'Enter your customer type', 'ceretax' ),
					'id'       => CWAFC_PREFIX . '_cere_tax_customer_type',
					'desc_tip' => true,
					'autoload' => false,
				),

				array(
					'name'     => __( 'PS Code', 'ceretax' ),
					'type'     => 'text',
					'desc'     => __( 'Enter your PS code', 'ceretax' ),
					'id'       => CWAFC_PREFIX . '_cere_tax_ps_code',
					'desc_tip' => true,
					'autoload' => false,
				),

				array(
					'name'     => __( 'Tax Name', 'ceretax' ),
					'type'     => 'text',
					'desc'     => __( 'Enter the Tax Name. If you are using a multilingual plugin do not make any changes here.', 'ceretax' ),
					'id'       => CWAFC_PREFIX . '_cere_tax_name',
					'desc_tip' => true,
					'autoload' => false,
					'default'  => 'Tax',
				),

				array(
					'name'     => __( 'Line Item Tax Column Name', 'ceretax' ),
					'type'     => 'text',
					'desc'     => __( 'Enter the admin order line item tax column name. If you are using a multilingual plugin do not make any changes here.', 'ceretax' ),
					'id'       => CWAFC_PREFIX . '_cere_tax_line_item_column_name',
					'desc_tip' => true,
					'autoload' => false,
					'default'  => 'Tax Total',
				),

				array(
					'name'    => __( 'Tax Included', 'ceretax' ),
					'type'    => 'checkbox',
					'id'      => CWAFC_PREFIX . '_cere_tax_tax_included',
					'class'   => 'cere_tax_checkbox',
					'default' => 'no',
				),

				array(
					'type' => 'sectionend',
					'id'   => 'cere_tax_section_end',
				),
			);

			return $settings;
		}

		/**
		 * Check API key entered is valid or not
		 *
		 * @param string $api_key ceratax api key.
		 * @param string $tax_env ceratax api env.
		 * @return boolean
		 */
		public function cwafc_is_valid_cere_tax_api_key( $api_key, $tax_env ) {

			if ( 'production' === $tax_env ) {
				$api_url = 'https://calc.prod.ceretax.net/test';
			} else {
				$api_url = 'https://calc.cert.ceretax.net/test';
			}

			$response = wp_remote_post(
				$api_url,
				array(
					'method'  => 'POST',
					'headers' => array(
						'x-api-key'    => $api_key,
						'Content-Type' => 'application/json',
					),
					'timeout' => 60,
				)
			);

			if ( is_wp_error( $response ) ) {
				return false;
			} else {
				$response_code = wp_remote_retrieve_response_code( $response );
			}
			if ( 200 === $response_code ) {
				return true;
			}
			return false;
		}

		/**
		 * Add custom fields to products
		 *
		 * @return void
		 */
		public function action__cwafc_add_custom_product_fields() {

			woocommerce_wp_text_input(
				array(
					'id'          => CWAFC_PREFIX . '_cere_tax_product_ps_code',
					'label'       => __( 'CereTax PS Code', 'ceretax' ),
					'placeholder' => __( 'Enter PS Code', 'ceretax' ),
					'desc_tip'    => 'true',
					'description' => __( 'PS Codes help identify the appropriate taxes, taxability, and rates that are applicable to a transaction.', 'ceretax' ),
				)
			);
		}

		/**
		 * Save custom fields to products
		 *
		 * @param string $product_id Product ID.
		 * @return void
		 */
		public function action__cwafc_save_custom_product_fields( $product_id ) {

			$product_ps_code_key = CWAFC_PREFIX . '_cere_tax_product_ps_code';
			$product             = wc_get_product( $product_id );
			// phpcs:disable WordPress.Security.NonceVerification.Missing
			$product_ps_code = isset( $_POST[ $product_ps_code_key ] ) ? sanitize_text_field( wp_unslash( $_POST[ $product_ps_code_key ] ) ) : '';
			// phpcs:enable WordPress.Security.NonceVerification.Missing
			$product->update_meta_data( $product_ps_code_key, sanitize_text_field( $product_ps_code ) );
			$product->save();
		}

		/**
		 * Add custom fields to products category
		 *
		 * @return void
		 */
		public function action__cwafc_add_custom_field_to_product_category() {
			?>
				<div class="form-field">
					<label for="custom_field"><?php esc_html_e( 'CereTax PS Code', 'ceretax' ); ?></label>
					<input type="text" name="<?php echo esc_attr( CWAFC_PREFIX . '_cere_tax_product_cat_ps_code' ); ?>" id="cere_tax_product_cat_ps_code" value="">
					<p class="description"><?php esc_html_e( 'Enter product category PS code.', 'ceretax' ); ?></p>
				</div>
			<?php
		}

		/**
		 * Add custom fields in products edit category
		 *
		 * @param string $term ceratax term object.
		 *
		 * @return void
		 */
		public function action__cwafc_edit_custom_field_in_product_category( $term ) {
			$cere_tax_product_cat_ps_code = get_term_meta( $term->term_id, CWAFC_PREFIX . '_cere_tax_product_cat_ps_code', true );
			?>
			<tr class="form-field">
				<th scope="row" valign="top">
					<label for="cere_tax_product_cat_ps_code"><?php esc_html_e( 'CereTax PS Code', 'ceretax' ); ?></label>
				</th>
				<td>
					<input type="text" name="<?php echo esc_attr( CWAFC_PREFIX . '_cere_tax_product_cat_ps_code' ); ?>" id="cere_tax_product_cat_ps_code" value="<?php echo esc_attr( $cere_tax_product_cat_ps_code ) ? esc_attr( $cere_tax_product_cat_ps_code ) : ''; ?>">
					<p class="description"><?php esc_html_e( 'Enter product category PS code.', 'ceretax' ); ?></p>
				</td>
			</tr>
			<?php
		}

		/**
		 * Add custom fields in products edit category
		 *
		 * @param string $term_id ceratax term ID.
		 *
		 * @return void
		 */
		public function action__cwafc_save_custom_field_in_product_category( $term_id ) {
			$term_field_meta_key = CWAFC_PREFIX . '_cere_tax_product_cat_ps_code';
			// phpcs:disable WordPress.Security.NonceVerification.Missing
			if ( isset( $_POST[ $term_field_meta_key ] ) ) {
				update_term_meta( $term_id, $term_field_meta_key, sanitize_text_field( wp_unslash( $_POST[ $term_field_meta_key ] ) ) );
			}
			// phpcs:enable WordPress.Security.NonceVerification.Missing
		}

		/**
		 * Admin footer script & style
		 *
		 * @return void
		 */
		public function action__cwafc_admin_footer_function() {
			$order_id = null;
			// phpcs:disable WordPress.Security.NonceVerification.Recommended
			if ( ( isset( $_GET['post'] ) && ! empty( $_GET['post'] ) ) || ( isset( $_GET['id'] ) && ! empty( $_GET['id'] ) ) ) {
				if ( isset( $_GET['post'] ) && ! empty( $_GET['post'] ) ) {
					$order_id = sanitize_text_field( wp_unslash( $_GET['post'] ) );
				} elseif ( isset( $_GET['id'] ) && ! empty( $_GET['id'] ) ) {
					$order_id = sanitize_text_field( wp_unslash( $_GET['id'] ) );
				} else {
					$order_id = '';
				}
			}
			// phpcs:enable WordPress.Security.NonceVerification.Recommended

			$cere_tax_name = get_option( CWAFC_PREFIX . '_cere_tax_name', 'Tax' );
			$ceretax_data  = get_post_meta( $order_id, 'ceretax_data', true );
			$order         = wc_get_order( $order_id );
			if ( ! empty( $order ) ) {
				foreach ( $order->get_fees() as $fee_id => $fee ) {
					if ( $fee->get_name() === $cere_tax_name ) {
						$fee_amount = $fee->get_amount();
						break;
					}
				}
			}
			if ( ! empty( $order_id ) && ! empty( $ceretax_data ) ) { ?>
				<style>
					/* Hide Tax column for ceretax order item list */
					.woocommerce_order_items tr th.line_tax,
					.woocommerce_order_items tr td.line_tax { 
						display: none !important; 
					}

				</style>
			<?php } ?>
			<style>
				/* Ceretax table stysle */
				#cwafc_ceretax_metabox .inside {
					margin: 0px;
					padding: 0px;
					overflow: auto !important;
				}
				table.ceratax-tax-table {
					width: 100% !important;
					font-size: 14px !important;
				}
				.ceratax-tax-table thead {
					background:#ededed !important;
				}
				.ceratax-tax-table tr th {
					padding: 8px 10px !important;
				}
				.ceratax-tax-table tr td {
					padding: 8px 10px !important;
					border-bottom: 1px solid #ededed !important;
				}
			</style>
			<?php if ( ! empty( $order_id ) && ! empty( $ceretax_data ) ) { // Refund order script. ?>
			<script>
				jQuery(function($) {
					jQuery( '#woocommerce-order-items' ).on( 'change', 'input.refund_order_item_qty', function() {
						var $row               = jQuery( this ).closest( 'tr.item' );
						var qty                = $row.find( 'input.quantity' ).val();
						var refund_qty         = jQuery( this ).val();
						var ceretax_line_total = jQuery( 'input.ceretax_line_total', $row );
						var line_total         = jQuery( 'input.line_total', $row );
						var refund_line_total  = jQuery( 'input.refund_line_total', $row );

						var unit_line_ceretax_total = accounting.unformat( ceretax_line_total.attr( 'data-line-tax' ), woocommerce_admin.mon_decimal_point ) / qty;
						ceretax_line_total.val(
							parseFloat( accounting.formatNumber( unit_line_ceretax_total * refund_qty, 2, '' ) )
							.toString()
							.replace( '.', woocommerce_admin.mon_decimal_point )
						).trigger( 'change' );

						// Totals
						var unit_total = accounting.unformat( line_total.attr( 'data-total' ), woocommerce_admin.mon_decimal_point ) / qty;

						refund_line_total.val(
							parseFloat( accounting.formatNumber( unit_total * refund_qty, woocommerce_admin_meta_boxes.rounding_precision, '' ) )
								.toString()
								.replace( '.', woocommerce_admin.mon_decimal_point )
						).trigger( 'change' );

						jQuery( this ).trigger( 'refund_quantity_changed' );

					});
					jQuery( '#woocommerce-order-items' ).on( 'change', '.refund input.ceretax_line_total', function() {

						var refund_amount     = 0;
						var $items            = jQuery( '.woocommerce_order_items' ).find( 'tr.item, tr.fee, tr.shipping' );
						var round_at_subtotal = 'yes' === woocommerce_admin_meta_boxes.round_at_subtotal;

						// Restrict value based on data-line-tax
						var maxValue   = parseFloat( jQuery( this ).data('line-tax') ) || 0;
						var inputValue = parseFloat( jQuery( this ).val() ) || 0;

						if ( inputValue > maxValue ) {
							alert( 'You cannot refund the line item tax exceeding the allowed limit of ' + maxValue + '.' );
							jQuery( this ).val( maxValue );
						}

						$items.each(function() {
							var $row               = jQuery( this );
							var refund_cost_fields = $row.find( '.refund input:not(.refund_order_item_qty)' );

							refund_cost_fields.each(function( index, el ) {
								var field_amount = accounting.unformat( jQuery( el ).val() || 0, woocommerce_admin.mon_decimal_point );
								refund_amount += parseFloat( round_at_subtotal ?
									field_amount :
									accounting.formatNumber( field_amount, woocommerce_admin_meta_boxes.currency_format_num_decimals, '' ) );
							});
						});

						jQuery( '#refund_amount' ).val( 
							accounting.formatNumber(
								refund_amount,
								woocommerce_admin_meta_boxes.currency_format_num_decimals,
								'',
								woocommerce_admin.mon_decimal_point
						) ).trigger( 'change' );

					});
					jQuery( '#woocommerce-order-items' ).on( 'change', '.refund input.ceretax_shipping_line_total', function() {

						// Restrict value based on data-line-tax
						var maxValue   = parseFloat( jQuery( this ).data('shipping-tax') ) || 0;
						var inputValue = parseFloat( jQuery( this ).val() ) || 0;

						if ( inputValue > maxValue ) {
							alert( 'You cannot refund the line item tax exceeding the allowed limit of ' + maxValue + '.' );
							jQuery( this ).val( maxValue );
						}

					});

					// Hide the Tax( Custom fee ) refund text input.
					jQuery( '.woocommerce_order_items #order_fee_line_items tr' ).each( function() {
						var feeName = jQuery( this ).find('.name .view').text().trim();
						var taxName = '<?php echo esc_js( get_option( CWAFC_PREFIX . '_cere_tax_name', 'Tax' ) ); ?>';
						if ( feeName === taxName ) {
							jQuery( this ).find( '.refund input' ).hide();
						}
					});
				});
			</script>
			<?php }
		}

		/**
		 * Add admin order line item column header.
		 *
		 * @param object $order Order object.
		 * @return void
		 */
		public function action__cwafc_woocommerce_admin_order_item_headers( $order ) {
			$ceretax_data_lineitem = get_post_meta( $order->get_id(), 'ceretax_data_lineitem', true );
			$ceretax_data          = get_post_meta( $order->get_id(), 'ceretax_data', true );
			if ( ! empty( $ceretax_data_lineitem ) && ! empty( $ceretax_data ) && ! empty( $order ) ) {
				$cere_tax_line_item_column_name = get_option( CWAFC_PREFIX . '_cere_tax_line_item_column_name', 'Tax Total' );
				echo '<th class="ceretax_line_heading" width="7%">' . esc_html( $cere_tax_line_item_column_name ) . '</th>';
			}
		}

		/**
		 * Add admin order line item column header.
		 *
		 * @param object $product Product object.
		 * @param object $item Product item object.
		 * @param string $item_id Order object.
		 * @return void
		 */
		public function action__cwafc_woocommerce_admin_order_item_values( $product, $item, $item_id ) {

			// phpcs:disable WordPress.Security.NonceVerification
			$order_id = null;
			if ( isset( $_GET['post'] ) && ! empty( $_GET['post'] ) ) {
				$order_id = sanitize_text_field( wp_unslash( $_GET['post'] ) );
			} elseif ( isset( $_GET['id'] ) && ! empty( $_GET['id'] ) ) {
				$order_id = sanitize_text_field( wp_unslash( $_GET['id'] ) );
			} else {
				$order_id = null;
			}
			if ( empty( $order_id ) && isset( $_POST['order_id'] ) ) {
				$order_id = sanitize_text_field( wp_unslash( $_POST['order_id'] ) );
			}
			// phpcs:enable WordPress.Security.NonceVerification

			$cere_tax_name         = get_option( CWAFC_PREFIX . '_cere_tax_name', 'Tax' );
			$order                 = wc_get_order( $order_id );
			$ceretax_data_lineitem = json_decode( get_post_meta( $order_id, 'ceretax_data_lineitem', true ) );
			$ceretax_data          = json_decode( get_post_meta( $order_id, 'ceretax_data', true ) );

			if ( ! empty( $ceretax_data_lineitem ) && ! empty( $ceretax_data ) && ! empty( $order ) ) {

				if ( ! empty( $product ) ) {
					echo '<td class="ceretax_line_value" width="7%">';
					if ( is_object( $ceretax_data_lineitem ) && is_object( $ceretax_data ) ) {
						$ceretax_items_data = $ceretax_data_lineitem->invoice->lineItems;
						$ceretax_data       = $ceretax_data->invoice->lineItems;
						if ( ! empty( $ceretax_items_data ) && ! empty( $ceretax_data ) ) {

							if ( $product->is_type( 'variation' ) ) {
								$product_id = $product->get_parent_id();
							} else {
								$product_id = $product->get_id();
							}

							$line_item_total_tax_amount = 0;
							$line_item_calc_base_amount = 0;
							$line_item_revenue_amount   = 0;
							$line_item_total_tax        = 0;

							$filtered = array_filter(
								$ceretax_items_data,
								function ( $filtered_item ) use ( $product_id, $item_id ) {
									return isset( $filtered_item->itemNumber ) && $filtered_item->itemNumber == $product_id && isset( $filtered_item->lineId ) && $filtered_item->lineId == $item_id; // phpcs:ignore WordPress.NamingConventions.ValidVariableName
								}
							);

							$refunded_filtered = array_filter(
								$ceretax_data,
								function ( $refunded_item ) use ( $product_id ) {
									return isset( $refunded_item->itemNumber ) && $refunded_item->itemNumber == $product_id && isset( $refunded_item->lineId ) && $refunded_item->lineId == $item_id; // phpcs:ignore WordPress.NamingConventions.ValidVariableName
								}
							);

							$line_item_revenue_amount = ! empty( $filtered ) ? round( reset( $filtered )->revenue, 2 ) : 0;
							$line_item_taxe_breaks    = ! empty( $filtered ) ? reset( $filtered )->taxes : array();

							if ( ! empty( $line_item_taxe_breaks ) && is_array( $line_item_taxe_breaks ) ) {
								foreach ( $line_item_taxe_breaks as $key => $val ) {
									if ( ! empty( $val->calculationBaseAmt ) && ( $val->calculationBaseAmt >= $line_item_revenue_amount ) ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName
										$line_item_calc_base_amount  = $val->calculationBaseAmt; // phpcs:ignore WordPress.NamingConventions.ValidVariableName
										$line_item_total_tax_amount += $val->totalTax; // phpcs:ignore WordPress.NamingConventions.ValidVariableName
									}
								}
							}
							if ( ! empty( $line_item_calc_base_amount ) ) {
								$line_item_total_tax = ( $line_item_revenue_amount / $line_item_calc_base_amount ) * $line_item_total_tax_amount;
							}

							$total_line_tax                 = ! empty( $filtered ) ? reset( $filtered )->totalTaxLine : null;
							$total_line_refunded_tax        = ! empty( $refunded_filtered ) ? reset( $refunded_filtered )->totalTaxLine : null;
							$ceretax_refunded_line_item_tax = $item->get_meta( '_ceretax_refunded_line_item_tax' );
							echo '<div class="view">';
							echo wp_kses_post( wc_price( $line_item_total_tax, array( 'currency' => $order->get_currency() ) ) );
							if ( is_array( $order->get_refunds() ) && count( $order->get_refunds() ) > 0 && ! empty( $ceretax_refunded_line_item_tax ) ) {
								echo '<small class="refunded">' . wp_kses_post( wc_price( -1 * $ceretax_refunded_line_item_tax, array( 'currency' => $order->get_currency() ) ) ) . '</small>';
							}
							echo '</div>';

							echo '<div class="refund" style="display: none;">
								<input type="text" name="ceretax_line_total[' . absint( $item_id ) . ']" placeholder="' . esc_attr( wc_format_localized_price( 0 ) ) . '" class="refund_line_tax ceretax_line_total wc_input_price" size="4" data-line-tax="' . esc_attr( wc_format_localized_price( round( $line_item_total_tax, 2 ) ) ) . '" />
							</div>';
						}
					}
					echo '</td>';
				} elseif ( $item instanceof WC_Order_Item_Fee && $item->get_name() === $cere_tax_name ) {
					echo '<td class="ceretax_line_value" width="7%"></td>';
				} elseif ( $item instanceof WC_Order_Item_Shipping ) {

					echo '<td class="ceretax_line_value" width="7%">';

					$shipping_tax_amount            = 0;
					$shipping_line_total            = $item['total'];
					$ceretax_refunded_line_item_tax = $item->get_meta( '_ceretax_refunded_line_item_tax' );
					if ( ! empty( $item['total'] ) && is_object( $ceretax_data_lineitem ) ) {
						$ceretax_items_data = $ceretax_data_lineitem->invoice->lineItems;
						if ( ! empty( $ceretax_items_data ) ) {
							$ceretax_items_count = 0;
							foreach ( $ceretax_items_data as $item_data ) {
								$line_item_tax_breaks         = $item_data->taxes;
								$transaction_charges_tax      = 0;
								$tras_charge_calc_base_amount = 0;
								if ( ! empty( $line_item_tax_breaks ) ) {
									foreach ( $line_item_tax_breaks as $key => $val ) {
										if ( ! empty( $val->transactionChargesCalculationBaseAmt ) ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName
											$tras_charge_calc_base_amount = $val->transactionChargesCalculationBaseAmt; // phpcs:ignore WordPress.NamingConventions.ValidVariableName
											$transaction_charges_tax      = $transaction_charges_tax + $val->transactionChargesTax; // phpcs:ignore WordPress.NamingConventions.ValidVariableName
										}
									}
								}
								if ( ! empty( $tras_charge_calc_base_amount ) ) {
									$ceretax_items_count++; // phpcs:ignore WordPress.PHP.PreIncrement.PreIncrement
									$shipping_tax_amount = $shipping_tax_amount + ( $transaction_charges_tax ) * ( $shipping_line_total / $tras_charge_calc_base_amount );
								}
							}
						}
					}
					if ( ! empty( $ceretax_items_count ) ) {
						$shipping_tax_amount = ( $shipping_tax_amount / $ceretax_items_count );
					}
					echo '<div class="view">';
					echo wp_kses_post( wc_price( $shipping_tax_amount, array( 'currency' => $order->get_currency() ) ) );
					if ( is_array( $order->get_refunds() ) && count( $order->get_refunds() ) > 0 && ! empty( $ceretax_refunded_line_item_tax ) ) {
						echo '<small class="refunded">' . wp_kses_post( wc_price( -1 * $ceretax_refunded_line_item_tax, array( 'currency' => $order->get_currency() ) ) ) . '</small>';
					}
					echo '</div>';

					echo '<div class="refund" style="display: none;">
						<input type="text" name="ceretax_shipping_line_total[' . absint( $item_id ) . ']" placeholder="' . esc_attr( wc_format_localized_price( 0 ) ) . '" class="refund_line_tax ceretax_shipping_line_total wc_input_price" size="4" data-shipping-tax="' . esc_attr( wc_format_localized_price( round( $shipping_tax_amount, 2 ) ) ) . '" />
					</div>';
					echo '</td>';
				} else {
					echo '<td class="ceretax_line_value" width="7%">';
					echo '</td>';
				}
			}
		}

		/**
		 * Add store address validate button.
		 *
		 * @param array $settings Setting fields.
		 * @return $settings
		 */
		public function filter__cwafc_add_store_address_validate_button( $settings ) {
			$new_settings = array();
			foreach ( $settings as $setting ) {
				$new_settings[] = $setting;
				// Insert custom button after the postcode field.
				if ( isset( $setting['id'] ) && 'store_address' === $setting['id'] && 'sectionend' === $setting['type'] ) {
					$new_settings[] = array(
						'type'  => 'validate_store_address_button', // Custom type, we'll render it below.
						'id'    => 'validate_store_address',
						'title' => '', // No label.
					);
				}
			}
			return $new_settings;
		}

		/**
		 * Render store address validate button.
		 *
		 * @return void
		 */
		public function action__cwafc_render_store_address_validate_button() {
			?>
			<p class="submit">
				<button name="save" class="button-primary woocommerce-save-button" type="submit" value="Validate Address"><?php esc_html_e( 'Validate Address', 'woocommerce' ); ?></button>
			</p>
			<?php
		}

		/**
		 * Validate store address.
		 *
		 * @return mix
		 */
		public function action__cwafc_validate_store_address() {

			// phpcs:disable WordPress.Security.NonceVerification
			$address_1       = isset( $_POST['woocommerce_store_address'] ) ? sanitize_text_field( wp_unslash( $_POST['woocommerce_store_address'] ) ) : '';
			$address_2       = isset( $_POST['woocommerce_store_address_2'] ) ? sanitize_text_field( wp_unslash( $_POST['woocommerce_store_address_2'] ) ) : '';
			$city            = isset( $_POST['woocommerce_store_city'] ) ? sanitize_text_field( wp_unslash( $_POST['woocommerce_store_city'] ) ) : '';
			$postcode        = isset( $_POST['woocommerce_store_postcode'] ) ? strtoupper( sanitize_text_field( wp_unslash( $_POST['woocommerce_store_postcode'] ) ) ) : '';
			$default_country = isset( $_POST['woocommerce_default_country'] ) ? strtoupper( sanitize_text_field( wp_unslash( $_POST['woocommerce_default_country'] ) ) ) : '';
			// phpcs:enable WordPress.Security.NonceVerification

			// Get country and state separately.
			list( $country, $state ) = array_pad( explode( ':', $default_country ), 2, '' );

			// Get ceretax env and api key.
			$cere_tax_tax_env = get_option( CWAFC_PREFIX . '_cere_tax_environment' );
			$cere_tax_api_key = get_option( CWAFC_PREFIX . '_cere_tax_api_key' );

			if ( 'production' === $cere_tax_tax_env ) {
				$api_url = 'https://av.prod.ceretax.net/validate';
			} else {
				$api_url = 'https://av.cert.ceretax.net/validate';
			}

			$request_body = array(
				array(
					'addressLine1' => $address_1,
					'city'         => $city,
					'state'        => $state,
					'postalCode'   => $postcode,
					'country'      => $country,
				),
			);

			$body = wp_json_encode( $request_body );

			// add api request data in wc logs if log option enabled.
			$this->cwafc_wc_add_custom_logs( $request_body, 'ceretax-store-address-validation-request' );

			$response = wp_remote_post(
				$api_url,
				array(
					'method'      => 'POST',
					'data_format' => 'body',
					'body'        => $body,
					'headers'     => array(
						'Accept'       => 'application/json',
						'x-api-key'    => $cere_tax_api_key,
						'Content-Type' => 'application/json',
					),
					'timeout'     => 60,
				)
			);

			// add api response data in wc logs if log option enabled.
			$this->cwafc_wc_add_custom_logs( $response, 'ceretax-store-address-validation-response' );

			if ( is_wp_error( $response ) ) {
				$notice_msg  = __( 'Request failed: ', 'ceretax' );
				$notice_msg .= $response->get_error_message();
				WC_Admin_Settings::add_error( $notice_msg );
				return false;
			} else {
				$data = wp_remote_retrieve_body( $response );
				$data = json_decode( $data, true );
			}

			if ( isset( $data['results'][0]['errorMessages'] ) ) {
				$notice_msg  = __( 'Address not validate: ', 'ceretax' );
				$notice_msg .= $data['results'][0]['errorMessages'][0]['message'];
				WC_Admin_Settings::add_error( $notice_msg );
				return false;
			} else {
				$validated_address_details = $data['results'][0]['validatedAddressDetails'];
				if ( ! empty( $validated_address_details ) ) {

					// Get validated address.
					$validated_address_line_1 = sanitize_text_field( wp_unslash( $data['results'][0]['validatedAddressDetails']['addressLine1'] ) );
					$validated_address_line_2 = sanitize_text_field( wp_unslash( $data['results'][0]['validatedAddressDetails']['addressLine2'] ) );
					$validated_city           = sanitize_text_field( wp_unslash( $data['results'][0]['validatedAddressDetails']['city'] ) );
					$validated_postal_code    = sanitize_text_field( wp_unslash( strtoupper( $data['results'][0]['submittedAddressDetails']['postalCode'] ) ) );

					// Update validated address.
					update_option( 'woocommerce_store_address', $validated_address_line_1 );
					update_option( 'woocommerce_store_address_2', $validated_address_line_2 );
					update_option( 'woocommerce_store_city', $validated_city );
					update_option( 'woocommerce_store_postcode', $validated_postal_code );

					$notice_msg = __( 'Address validate successfully !', 'ceretax' );
					WC_Admin_Settings::add_message( $notice_msg );

				} else {
					$notice_msg = $data['results'][0]['errorMessages'][0]['message'];
					WC_Admin_Settings::add_error( $notice_msg );
					return false;
				}
			}
		}

		/**
		 * Add WooCommerce logs for custom API call.
		 *
		 * @param object $log_data   pass the log data.
		 * @param string $log_source pass the source of the log.
		 * @return void
		 */
		public function cwafc_wc_add_custom_logs( $log_data, $log_source ) {
			$enable_logging = get_option( CWAFC_PREFIX . '_cere_tax_enable_logging' );
			if ( 'yes' === $enable_logging ) {
				$logger = wc_get_logger();
				$logger->info( wp_json_encode( $log_data, JSON_PRETTY_PRINT ), array( 'source' => $log_source ) );
			}
		}

		/**
		 * Add custom style after total.
		 *
		 * @param int $order_id Order id.
		 * @return void
		 */
		public function action__cwafc_add_after_total_style( $order_id ) {
			$order = is_a( $order_id, 'WC_Order' ) ? $order_id : wc_get_order( $order_id );

			if ( ! $order instanceof WC_Order ) {
				return;
			}

			$ceretax_data_raw = get_post_meta( $order->get_id(), 'ceretax_data', true );
			if ( empty( $ceretax_data_raw ) ) {
				return;
			}

			$ceretax_data = json_decode( $ceretax_data_raw );
			if ( isset( $ceretax_data->invoice->totalTaxInvoice ) && empty( $ceretax_data->invoice->totalTaxInvoice ) ) {
				return;
			}

			$order_total_fees = $order->get_total_fees();
			if ( $order_total_fees < 0 ) {
				return;
			}

			$cere_tax_name      = get_option( CWAFC_PREFIX . '_cere_tax_name', 'Tax' );
			$cere_tax_fee_exist = false;
			foreach ( $order->get_fees() as $fee_id => $fee ) {
				if ( $fee->get_name() === $cere_tax_name ) {
					$cere_tax_fee_exist = true;
					break;
				}
			}

			if ( ! $cere_tax_fee_exist ) {
				return;
			}

			if ( 0 < count( $order->get_coupon_codes() ) && 0 < $order->get_total_discount() ) {
				echo '<style>
					.wc-order-data-row .wc-order-totals:first-of-type tr:nth-of-type(3) {
						display: none !important;
					}
				</style>';
			} else {
				echo '<style>
					.wc-order-data-row .wc-order-totals:first-of-type tr:nth-of-type(2) {
						display: none !important;
					}
				</style>';
			}
		}
	}

	add_action(
		'plugins_loaded',
		function () {
			cwafc()->admin->action = new CWAFC_Admin_Action();
		}
	);
}
