<?php

namespace Devikit\Wfirma\Frontend;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

class Checkout {

	/**
	 * Constructor
	 */
	public function __construct() {
		// Use higher priority (20+) to run after other plugins that might add NIP field
		add_filter( 'woocommerce_checkout_fields', [ $this, 'add_nip_field' ], 20 );
		add_action( 'woocommerce_checkout_update_order_meta', [ $this, 'save_checkout_fields' ], 20 );
		add_action( 'woocommerce_admin_order_data_after_billing_address', [ $this, 'display_nip_in_admin_order' ] );
		// Editable NIP in order admin (same as address fields)
		add_filter( 'woocommerce_admin_billing_fields', [ $this, 'add_editable_nip_to_admin_billing' ], 20 );
		add_action( 'woocommerce_process_shop_order_meta', [ $this, 'save_admin_order_nip' ], 10, 2 );
		// NIP is already shown in formatted billing address, no need to add it to email order meta fields
		add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_scripts' ] );
		add_action( 'wp_head', [ $this, 'add_inline_css' ], 999 );
		
		// NIP validation
		add_action( 'woocommerce_after_checkout_validation', [ $this, 'validate_nip_field' ], 10, 2 );
		
		// Formatted address
		add_filter( 'woocommerce_order_get_formatted_billing_address', [ $this, 'add_nip_to_formatted_address' ], 10, 3 );
		
		// My Account - billing address display
		add_filter( 'woocommerce_my_account_my_address_formatted_address', [ $this, 'my_account_my_address_formatted_address' ], 10, 3 );
		
		// My Account - billing address form (priority 20 to run after other plugins)
		add_filter( 'woocommerce_billing_fields', [ $this, 'add_nip_to_my_account_billing_fields' ], 20, 1 );
		add_action( 'woocommerce_after_save_address_validation', [ $this, 'validate_my_account_billing_nip' ], 10, 2 );
		add_action( 'woocommerce_customer_save_address', [ $this, 'save_my_account_billing_nip' ], 20, 2 );
	}

	/**
	 * Enqueue scripts
	 */
	public function enqueue_scripts() {
		if ( is_checkout() ) {
			wp_enqueue_script( 'devikit-wfirma-checkout', DEVIKIT_WFIRMA_URL . 'assets/js/checkout.js', [ 'jquery' ], DEVIKIT_WFIRMA_VERSION, true );
		}
	}
	
	/**
	 * Add inline CSS to hide NIP field initially if checkbox mode
	 */
	public function add_inline_css() {
		if ( ! is_checkout() ) {
			return;
		}
		
		$settings = get_option( 'devikit_wfirma_settings', [] );
		$nip_display_mode = isset( $settings['nip_display_mode'] ) ? $settings['nip_display_mode'] : 'always';
		
		if ( $nip_display_mode === 'checkbox' ) {
			wp_add_inline_style( 'woocommerce-inline', '.wfirma-nip-hidden-initially { display: none !important; }' );
		}
	}

	/**
	 * Add NIP to formatted address (HTML)
	 * NIP is also added by NipField.php via address_formats, but this ensures it's shown in contexts
	 * where NipField might not be active (e.g., other NIP plugins are active)
	 */
	public function add_nip_to_formatted_address( $address, $raw_address, $order ) {
		$nip = $order->get_meta( '_billing_nip' ) ?: $order->get_meta( 'vat_number' );
		
		// Check if NIP is already in the address to prevent duplication
		if ( ! empty( $nip ) && strpos( $address, 'NIP: ' . $nip ) === false && strpos( $address, 'NIP:' ) === false ) {
			// Try to insert before company
			if ( ! empty( $raw_address['company'] ) ) {
				$address = str_replace( 
					$raw_address['company'], 
					__( 'NIP', 'invoicing-integration-for-wfirma-and-woocommerce' ) . ': ' . esc_html( $nip ) . '<br>' . $raw_address['company'], 
					$address 
				);
			} else {
				// Prepend to beginning of address
				$address = __( 'NIP', 'invoicing-integration-for-wfirma-and-woocommerce' ) . ': ' . esc_html( $nip ) . '<br>' . $address;
			}
		}
		return $address;
	}

	/**
	 * Add NIP field if not exists
	 */
	public function add_nip_field( $fields ) {
		$settings = get_option( 'devikit_wfirma_settings', [] );
		$nip_display_mode = isset( $settings['nip_display_mode'] ) ? $settings['nip_display_mode'] : 'always';
		$checkbox_label = isset( $settings['invoice_checkbox_label'] ) && ! empty( $settings['invoice_checkbox_label'] ) 
			? $settings['invoice_checkbox_label'] 
			: __( 'I want an invoice', 'invoicing-integration-for-wfirma-and-woocommerce' );

		// Add checkbox if mode is 'checkbox'
		if ( $nip_display_mode === 'checkbox' ) {
			$checkbox_field = [
				'type'    => 'checkbox',
				'label'   => $checkbox_label,
				'class'   => [ 'form-row-wide', 'create-invoice-checkbox' ],
				'priority' => 24, // Before NIP (25)
			];

			if ( isset( $fields['billing']['billing_company'] ) ) {
				$new_billing_fields = [];
				foreach ( $fields['billing'] as $key => $field ) {
					if ( $key === 'billing_company' ) {
						$new_billing_fields['billing_want_invoice'] = $checkbox_field;
					}
					$new_billing_fields[ $key ] = $field;
				}
				$fields['billing'] = $new_billing_fields;
			} else {
				$fields['billing']['billing_want_invoice'] = $checkbox_field;
			}
		}

		// Check if NIP field is already added by another plugin
		$common_keys = [ 'billing_company_nip', 'billing_nip', 'billing_tax_number', 'billing_vat', 'vat_number' ];
		
		$nip_exists = false;
		foreach ( $common_keys as $key ) {
			if ( isset( $fields['billing'][ $key ] ) ) {
				$nip_exists = $key;
				break;
			}
		}

		// If NIP field already exists, don't add our own
		if ( $nip_exists ) {
			return $fields;
		}

		// Check if NIP is required
		$nip_required = isset( $settings['nip_required'] ) && $settings['nip_required'] === 'yes';
		
		$nip_field_config = [
			'type'        => 'text',
			'label'       => __( 'NIP', 'invoicing-integration-for-wfirma-and-woocommerce' ),
			'placeholder' => __( 'Enter NIP', 'invoicing-integration-for-wfirma-and-woocommerce' ),
			'required'    => $nip_required,
			'class'       => [ 'form-row-wide', 'wfirma-nip-field' ],
			'clear'       => true,
			'priority'    => 25,
		];
		
		// Add class to hide NIP field initially if checkbox mode is enabled
		if ( $nip_display_mode === 'checkbox' ) {
			$nip_field_config['class'][] = 'wfirma-nip-hidden-initially';
		}

		// Insert before Company Name if exists
		if ( isset( $fields['billing']['billing_company'] ) ) {
			$new_billing_fields = [];
			foreach ( $fields['billing'] as $key => $field ) {
				if ( $key === 'billing_company' ) {
					$new_billing_fields['billing_nip'] = $nip_field_config;
				}
				$new_billing_fields[ $key ] = $field;
			}
			$fields['billing'] = $new_billing_fields;
		} else {
			$fields['billing']['billing_nip'] = $nip_field_config;
		}

		return $fields;
	}

	/**
	 * Validate NIP field during checkout
	 */
	public function validate_nip_field( $data, $errors ) {
		// If another NIP plugin is active, let it handle validation
		if ( $this->is_other_nip_plugin_active() ) {
			return;
		}
		
		$settings = get_option( 'devikit_wfirma_settings', [] );
		
		$nip_required = isset( $settings['nip_required'] ) && $settings['nip_required'] === 'yes';
		$validate_format = isset( $settings['validate_nip_format'] ) && $settings['validate_nip_format'] === 'yes';
		
		// phpcs:ignore WordPress.Security.NonceVerification.Missing -- Called by WooCommerce checkout validation hook which handles nonce
		$nip = isset( $_POST['billing_nip'] ) ? sanitize_text_field( wp_unslash( $_POST['billing_nip'] ) ) : '';
		
		if ( $nip_required && empty( $nip ) ) {
			$errors->add( 'billing_nip_required', __( 'Pole NIP jest wymagane.', 'invoicing-integration-for-wfirma-and-woocommerce' ) );
			return;
		}
		
		if ( $validate_format && ! empty( $nip ) ) {
			$nip_clean = preg_replace( '/[\s\-]/', '', $nip );
			
			if ( ! preg_match( '/^[0-9]{10}$/', $nip_clean ) ) {
				$errors->add( 'billing_nip_invalid', __( 'NIP must contain exactly 10 digits.', 'invoicing-integration-for-wfirma-and-woocommerce' ) );
			}
		}
	}
	
	/**
	 * Check if another NIP plugin is active
	 */
	private function is_other_nip_plugin_active() {
		if ( ! function_exists( 'is_plugin_active' ) ) {
			require_once ABSPATH . 'wp-admin/includes/plugin.php';
		}
		
		$nip_plugins = [
			'woocommerce-nip-field/woocommerce-nip-field.php',
			'nip-field-woocommerce/nip-field-woocommerce.php',
			'nip-field-for-woocommerce/nip-field-for-woocommerce.php',
			'flexible-invoices-woocommerce/flexible-invoices-woocommerce.php',
			'woocommerce-ifirma/woocommerce-ifirma.php',
			'woocommerce-fakturownia/woocommerce-fakturownia.php',
			'woocommerce-infakt/woocommerce-infakt.php',
		];
		
		foreach ( $nip_plugins as $plugin ) {
			if ( is_plugin_active( $plugin ) ) {
				return true;
			}
		}
		
		return false;
	}

	/**
	 * Save checkout fields to order meta
	 */
	public function save_checkout_fields( $order_id ) {
		$existing_nip = get_post_meta( $order_id, '_billing_nip', true );
		
		// phpcs:ignore WordPress.Security.NonceVerification.Missing -- Called by WooCommerce checkout hook which handles nonce
		if ( empty( $existing_nip ) && ! empty( $_POST['billing_nip'] ) ) {
			// phpcs:ignore WordPress.Security.NonceVerification.Missing -- Called by WooCommerce checkout hook which handles nonce
			$nip = sanitize_text_field( wp_unslash( $_POST['billing_nip'] ) );
			update_post_meta( $order_id, '_billing_nip', $nip );
		}
		
		// phpcs:ignore WordPress.Security.NonceVerification.Missing -- Called by WooCommerce checkout hook which handles nonce
		if ( isset( $_POST['billing_want_invoice'] ) ) {
			update_post_meta( $order_id, '_billing_want_invoice', '1' );
		} else {
			update_post_meta( $order_id, '_billing_want_invoice', '0' );
		}
	}

	/**
	 * Display admin order extras (e.g. "I want an invoice").
	 * NIP is shown only in the editable billing form via woocommerce_admin_billing_fields.
	 */
	public function display_nip_in_admin_order( $order ) {
		$want_invoice = $order->get_meta( '_billing_want_invoice' );
		if ( $want_invoice !== '' ) {
			$status = ( $want_invoice === '1' ) ? __( 'Yes', 'invoicing-integration-for-wfirma-and-woocommerce' ) : __( 'No', 'invoicing-integration-for-wfirma-and-woocommerce' );
			echo '<p><strong>' . esc_html__( 'I want an invoice', 'invoicing-integration-for-wfirma-and-woocommerce' ) . ':</strong> ' . esc_html( $status ) . '</p>';
		}
	}

	/**
	 * Add editable NIP field to admin order billing section (same as address fields)
	 */
	public function add_editable_nip_to_admin_billing( $fields ) {
		if ( isset( $fields['nip'] ) ) {
			return $fields;
		}
		$fields['nip'] = [
			'label' => __( 'NIP', 'invoicing-integration-for-wfirma-and-woocommerce' ),
			'show'  => true,
		];
		return $fields;
	}

	/**
	 * Save NIP when order is updated in admin
	 *
	 * @param int       $order_id Order ID.
	 * @param \WC_Order $order    Order object (optional, for HPOS compatibility).
	 */
	public function save_admin_order_nip( $order_id, $order = null ) {
		// Hook may pass WP_Post in some WooCommerce versions - always use WC_Order
		if ( ! $order instanceof \WC_Order ) {
			$order = wc_get_order( $order_id );
		}
		if ( ! $order ) {
			return;
		}
		// phpcs:ignore WordPress.Security.NonceVerification.Missing -- Called by WooCommerce save hook which verifies nonce
		if ( isset( $_POST['_billing_nip'] ) ) {
			// phpcs:ignore WordPress.Security.NonceVerification.Missing -- Called by WooCommerce save hook which verifies nonce
			$nip = sanitize_text_field( wp_unslash( $_POST['_billing_nip'] ) );
			$order->update_meta_data( '_billing_nip', $nip );
			$order->save();
		}
	}

	/**
	 * Display NIP field in billing address (My Account)
	 */
	public function my_account_my_address_formatted_address( $address, $customer_id, $name ) {
		if ( $name === 'billing' ) {
			$nip = get_user_meta( $customer_id, 'billing_nip', true );
			
			if ( ! empty( $nip ) ) {
				$address['nip'] = $nip;
			}
		}
		
		return $address;
	}

	/**
	 * Add NIP field to billing address form in My Account
	 */
	public function add_nip_to_my_account_billing_fields( $fields ) {
		if ( isset( $fields['billing_nip'] ) ) {
			return $fields;
		}

		if ( ! apply_filters( 'devikit_wfirma_add_nip_field_my_account', true ) ) {
			return $fields;
		}

		$settings = get_option( 'devikit_wfirma_settings', [] );
		$nip_required = isset( $settings['nip_required'] ) && $settings['nip_required'] === 'yes';

		if ( isset( $fields['billing_company'] ) ) {
			$company_field = $fields['billing_company'];
			$company_priority = isset( $company_field['priority'] ) ? $company_field['priority'] : 30;
			
			$fields['billing_nip'] = [
				'type'        => 'text',
				'label'       => __( 'NIP', 'invoicing-integration-for-wfirma-and-woocommerce' ),
				'placeholder' => __( 'Enter NIP', 'invoicing-integration-for-wfirma-and-woocommerce' ),
				'required'    => $nip_required,
				'class'       => [ 'form-row-wide' ],
				'clear'       => true,
				'priority'    => $company_priority - 1,
			];
		}
		
		return $fields;
	}

	/**
	 * Validate NIP field in My Account address form
	 */
	public function validate_my_account_billing_nip( $user_id, $load_address ) {
		if ( $load_address !== 'billing' ) {
			return;
		}
		
		if ( ! isset( $_POST['woocommerce-edit-address-nonce'] ) || 
			 ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['woocommerce-edit-address-nonce'] ) ), 'woocommerce-edit_address' ) ) {
			return;
		}
		
		if ( $this->is_other_nip_plugin_active() ) {
			return;
		}
		
		$settings = get_option( 'devikit_wfirma_settings', [] );
		$nip_required = isset( $settings['nip_required'] ) && $settings['nip_required'] === 'yes';
		$validate_format = isset( $settings['validate_nip_format'] ) && $settings['validate_nip_format'] === 'yes';
		
		$nip = isset( $_POST['billing_nip'] ) ? sanitize_text_field( wp_unslash( $_POST['billing_nip'] ) ) : '';
		
		if ( $nip_required && empty( $nip ) ) {
			wc_add_notice( __( 'Pole NIP jest wymagane.', 'invoicing-integration-for-wfirma-and-woocommerce' ), 'error' );
			return;
		}
		
		if ( $validate_format && ! empty( $nip ) ) {
			$nip_clean = preg_replace( '/[\s\-]/', '', $nip );
			
			if ( ! preg_match( '/^[0-9]{10}$/', $nip_clean ) ) {
				wc_add_notice( __( 'NIP must contain exactly 10 digits.', 'invoicing-integration-for-wfirma-and-woocommerce' ), 'error' );
			}
		}
	}

	/**
	 * Save NIP field in My Account address form
	 */
	public function save_my_account_billing_nip( $user_id, $load_address ) {
		if ( $load_address !== 'billing' ) {
			return;
		}

		if ( ! isset( $_POST['woocommerce-edit-address-nonce'] ) || 
			 ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['woocommerce-edit-address-nonce'] ) ), 'woocommerce-edit_address' ) ) {
			return;
		}

		$existing_nip = get_user_meta( $user_id, 'billing_nip', true );
		
		if ( isset( $_POST['billing_nip'] ) ) {
			$new_nip = sanitize_text_field( wp_unslash( $_POST['billing_nip'] ) );
			
			if ( empty( $existing_nip ) || $existing_nip !== $new_nip ) {
				update_user_meta( $user_id, 'billing_nip', $new_nip );
			}
		}
	}
}
