<?php

namespace Devikit\Fakturowo;

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

/**
 * NIP Field Handler
 * Adds NIP field to checkout if not provided by another plugin
 */
class NipField {

    /**
     * Constructor
     */
    public function __construct() {
        // Check if NIP field should be added to checkout
        add_action( 'wp', [ $this, 'maybe_add_nip_field' ] );
        
        // Add NIP field to user profile in admin (must be added early, before wp action)
        add_filter( 'woocommerce_customer_meta_fields', [ $this, 'add_nip_to_user_profile' ] );

        // Editable NIP in order admin (same as address fields)
        add_filter( 'woocommerce_admin_billing_fields', [ $this, 'admin_billing_fields' ], 20 );
        add_action( 'woocommerce_process_shop_order_meta', [ $this, 'save_admin_order_nip' ], 10, 2 );
    }

    /**
     * Maybe add NIP field if not exists from other plugin
     */
    public function maybe_add_nip_field() {
        // Check settings
        $settings = get_option( 'devikit_fakturowo_settings', [] );
        $add_nip = isset( $settings['add_nip_field'] ) ? $settings['add_nip_field'] : 'yes';
        
        if ( $add_nip !== 'yes' ) {
            return;
        }

        // Check if another NIP plugin is active
        if ( $this->is_nip_field_available() ) {
            return;
        }

        // Add our NIP field
        add_filter( 'woocommerce_billing_fields', [ $this, 'add_nip_field' ], 20 );
        add_action( 'woocommerce_checkout_update_order_meta', [ $this, 'save_nip_field' ] );
        add_filter( 'woocommerce_order_formatted_billing_address', [ $this, 'display_nip_in_address' ], 10, 2 );
        
        // Only add {nip} placeholder system if NOT using blocks checkout
        // Blocks checkout uses direct HTML modification instead (see CheckoutBlocks.php)
        if ( ! $this->site_uses_block_checkout() ) {
            add_filter( 'woocommerce_formatted_address_replacements', [ $this, 'address_replacements' ], 10, 2 );
            add_filter( 'woocommerce_localisation_address_formats', [ $this, 'address_formats' ] );
        }
    }

    /**
     * Check if NIP field is already available from another plugin
     * 
     * @return bool
     */
    private function is_nip_field_available() {
        // Check for popular NIP plugins
        $nip_plugins = [
            'nip-field-for-woocommerce/nip-field-for-woocommerce.php',
            'nip-field-for-woocommerce-pro/nip-field-for-woocommerce-pro.php',
            'flexible-invoices/flexible-invoices.php',
            'woocommerce-eu-vat-number/woocommerce-eu-vat-number.php',
        ];

        foreach ( $nip_plugins as $plugin ) {
            if ( is_plugin_active( $plugin ) ) {
                return true;
            }
        }

        // Check if billing_nip field is already registered
        // This will be checked at checkout rendering time
        return apply_filters( 'devikit_fakturowo_nip_field_available', false );
    }

    /**
     * Add NIP field to billing fields
     */
    public function add_nip_field( $fields ) {
        // Check if billing_nip already exists
        if ( isset( $fields['billing_nip'] ) ) {
            return $fields;
        }

        // Get settings
        $settings = get_option( 'devikit_fakturowo_settings', [] );
        $nip_required = isset( $settings['nip_required'] ) && $settings['nip_required'] === 'yes';

        $fields['billing_nip'] = [
            'type'        => 'text',
            'label'       => __( 'NIP', 'invoicing-integration-for-fakturowo-and-woocommerce' ),
            'placeholder' => __( 'Enter NIP if you need an invoice', 'invoicing-integration-for-fakturowo-and-woocommerce' ),
            'required'    => $nip_required,
            'class'       => [ 'form-row-wide' ],
            'priority'    => 35, // After company name
            'maxlength'   => 13,
        ];

        return $fields;
    }

    /**
     * Save NIP field to order meta
     */
    public function save_nip_field( $order_id ) {
        // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce is verified by WooCommerce checkout process
        if ( ! empty( $_POST['billing_nip'] ) ) {
            // phpcs:ignore WordPress.Security.NonceVerification.Missing
            $nip = sanitize_text_field( wp_unslash( $_POST['billing_nip'] ) );
            // Remove only dashes and spaces, preserve country code and digits
            $nip = preg_replace( '/[\s\-]/', '', $nip );
            
            $order = wc_get_order( $order_id );
            $order->update_meta_data( '_billing_nip', $nip );
            $order->save();
        }
    }

    /**
     * Display NIP in formatted address
     */
    public function display_nip_in_address( $address, $order ) {
        // Don't add NIP in admin order edit - it's shown in the editable billing field
        $screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;
        if ( is_admin() && $screen && $screen->id === 'shop_order' ) {
            return $address;
        }

        $nip = $order->get_meta( '_billing_nip' );
        if ( $nip ) {
            $address['nip'] = $nip;
        }
        return $address;
    }

    /**
     * Address replacements
     */
    public function address_replacements( $replacements, $args ) {
        $replacements['{nip}'] = isset( $args['nip'] ) ? __( 'NIP: ', 'invoicing-integration-for-fakturowo-and-woocommerce' ) . $args['nip'] : '';
        return $replacements;
    }

    /**
     * Address formats
     */
    public function address_formats( $formats ) {
        foreach ( $formats as $country => $format ) {
            $formats[ $country ] = $format . "\n{nip}";
        }
        return $formats;
    }

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

    /**
     * Save NIP when order is updated in admin
     *
     * @param int            $order_id Order ID.
     * @param \WC_Order|null $order    Order object (optional). Hook may pass WP_Post in some WooCommerce versions.
     */
    public function save_admin_order_nip( $order_id, $order = null ) {
        // Hook may pass WP_Post in older WooCommerce - 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
            $nip = sanitize_text_field( wp_unslash( $_POST['_billing_nip'] ) );
            $order->update_meta_data( '_billing_nip', $nip );
            $order->save();
        }
    }

    /**
     * Add NIP field to user profile in admin
     *
     * @param array $fields Customer meta fields
     * @return array Modified fields
     */
    public function add_nip_to_user_profile( $fields ) {
        // Check if another NIP plugin already added the field
        if ( isset( $fields['billing']['fields']['billing_nip'] ) ) {
            return $fields;
        }
        
        // Check settings
        $settings = get_option( 'devikit_fakturowo_settings', [] );
        $add_nip = isset( $settings['add_nip_field'] ) ? $settings['add_nip_field'] : 'yes';
        
        if ( $add_nip !== 'yes' ) {
            return $fields;
        }
        
        // Add NIP field to billing address section
        if ( isset( $fields['billing']['fields'] ) ) {
            if ( isset( $fields['billing']['fields']['billing_company'] ) ) {
                // Insert NIP field after Company Name field
                $new_fields = [];
                
                foreach ( $fields['billing']['fields'] as $key => $field ) {
                    $new_fields[ $key ] = $field;
                    
                    if ( $key === 'billing_company' ) {
                        // Add NIP field after Company Name field
                        $new_fields['billing_nip'] = [
                            'label'       => __( 'NIP', 'invoicing-integration-for-fakturowo-and-woocommerce' ),
                            'description' => '',
                        ];
                    }
                }
                
                $fields['billing']['fields'] = $new_fields;
            } else {
                // If Company Name field doesn't exist, add NIP field at the beginning
                $fields['billing']['fields'] = array_merge(
                    [
                        'billing_nip' => [
                            'label'       => __( 'NIP', 'invoicing-integration-for-fakturowo-and-woocommerce' ),
                            'description' => '',
                        ],
                    ],
                    $fields['billing']['fields']
                );
            }
        }
        
        return $fields;
    }

    /**
     * Check if site uses block checkout
     */
    private function site_uses_block_checkout() {
        $checkout_page_id = wc_get_page_id( 'checkout' );
        if ( ! $checkout_page_id ) {
            return false;
        }
        
        // Check if checkout page has blocks
        return has_block( 'woocommerce/checkout', $checkout_page_id );
    }
}
