<?php

/**
 * This snippet is used to apply the VAT tax according to the Council Directive 2006/112/EC.
 * https://chatgpt.com/c/6813932c-0fb0-800c-9f1b-a5e058831e7c
 *
 * In this file, we provide:
 * - a couple of functions to get the business address country and the VAT rates by country.
 * - hook into core to format the price according to the Council Directive 2006/112/EC.
 * - hook into core to apply the tax to the order total, during checkout.
 * - hook into core to adjust subtotal + taxes on order renewals.
 * - compat with PMPro Vat Tax Addon, just in case.
 *   - hook into the PMPro VAT Tax Addon to apply the same VAT rate to all countries.
 *   - extend customer country fetch to use the session variable.
 *   - never hide the
 */

add_filter( 'pmpro_custom_advanced_settings', function ( $fields ) {
    if ( ! empty( $_REQUEST['pmpro_advancedsettings_nonce'] ) ) {
        $enabletax = isset( $_REQUEST['enable_tax_calculation'] ) && $_REQUEST['enable_tax_calculation'] === '1';
        update_option( 'pop_pmpro_enable_tax_calculation', $enabletax ? '1' : '0' );
    }

    $fields[] = array(
        'name'       => 'enable_tax_calculation',
        'field_name' => 'enable_tax_calculation',
        'field_type' => 'callback',
        'label'      => __( 'Tax Calculation', WC_EL_INV_TEXTDOMAIN ),
        //'description' => __( 'Enable VAT tax calculation according to the Council Directive 2006/112/EC.', WC_EL_INV_TEXTDOMAIN ),
        'callback'   => function () {
            ?>
            <input id="enable_tax_calculation" name="enable_tax_calculation" type="checkbox"
                   value="1" <?php checked( get_option( 'pop_pmpro_enable_tax_calculation', '' ), '1' ); ?> />
            <label for="enable_tax_calculation">
                <?php esc_html_e( 'Enable VAT tax calculation according to the Council Directive 2006/112/EC.', WC_EL_INV_TEXTDOMAIN ) ?>
            </label>
            <?php
        }
    );

    return $fields;
} );

function pop_pmproInit_CouncilDirective_2006_112_EC() {
    $enable_tax_calculation = get_option( 'pop_pmpro_enable_tax_calculation' );
    if( ! $enable_tax_calculation ){
      return;
    }

    // check if current url contains admin-ajax.php?action=stripe_webhook
    // $is_ajax_stripe_webhook = ( defined( 'DOING_AJAX' ) && DOING_AJAX && isset( $_REQUEST['action'] ) && $_REQUEST['action'] === 'stripe_webhook' );
    // $is_ajax_stripe_webhook && error_log( "2006112 during stripe_webhook" );

    // $is_ajax_stripe_webhook && error_log( "2006112 tax calc = $enable_tax_calculation" );
    add_filter( 'pmpro_format_price', 'pop_pmproFormatPrice_CouncilDirective_2006_112_EC' );
    add_filter( 'pmpro_tax', 'pop_pmproApplyCheckoutTax_CouncilDirective_2006_112_EC', 110, 3 );
    add_filter( 'pmpro_vat_by_country', 'pop_pmproSetFixedTaxRate_CouncilDirective_2006_112_EC' );
    
    /**
     * The VAT field must always be shown, even if the customer is from the same country as the business address.
     */
    add_filter( 'pmprovat_hide_vat_if_same_country', '__return_false' );
}

if ( did_action( 'init' ) ) {
    pop_pmproInit_CouncilDirective_2006_112_EC();
} else {
    add_action( 'init', 'pop_pmproInit_CouncilDirective_2006_112_EC' );
}

/**
 * Format the price according to the Council Directive 2006/112/EC, storewide.
 *
 * @param string $formatted
 *
 * @return mixed|string
 */
function pop_pmproGetTaxLabel_CouncilDirective_2006_112_EC() {
    return 'it' === pop_pmproGetCurrentLanguageCode_CouncilDirective_2006_112_EC() ? 'IVA' : 'VAT';
}

/**
 * Resolve the current site language for PMPro VAT labels.
 *
 * Prefer WPML current language when available, otherwise fall back to the current WordPress locale.
 *
 * @return string
 */
function pop_pmproGetCurrentLanguageCode_CouncilDirective_2006_112_EC() {
    return \WcElectronInvoice\Functions\getCurrentLanguage();
}

function pop_pmproFormatPrice_CouncilDirective_2006_112_EC( $formatted ) {
    $action = \WcElectronInvoice\Functions\filterInput($_POST,  'action', FILTER_SANITIZE_SPECIAL_CHARS);
    if ( pmpro_is_checkout() || (defined('DOING_AJAX') && DOING_AJAX && 'pmProViesCheck' === $action)) {
        $formatted .= ' +' . pop_pmproGetTaxLabel_CouncilDirective_2006_112_EC();
    }

    return $formatted;
}

/**
 * Apply the tax to the order total, during checkout.
 *
 * The "eucountry" field and the fields from the session are set by the PMPro VAT Tax Addon, which is not required by POP.
 * So, this function is designed to be compatible with the PMPro VAT Tax Addon.
 *
 * @param float $tax
 * @param array $values
 * @param \MemberOrder $order
 *
 * @return float|mixed
 */
function pop_pmproApplyCheckoutTax_CouncilDirective_2006_112_EC( $tax, $values, $order ) {
    // PMPro 3.2+ is needed, which introduced the pmpro business address setting.
    $business_country = pop_pmproGetBusinessAddressCountry();
    if ( empty( $business_country ) ) {
        return $tax;
    }

    if ( ! empty( $_REQUEST['billing_vat_number'] ) ) {
        $vat_number = sanitize_text_field( $_REQUEST['billing_vat_number'] );
    } elseif ( ! empty( $_SESSION['billing_vat_number'] ) ) {
        $vat_number = sanitize_text_field( $_SESSION['billing_vat_number'] );
    } else {
        $vat_number = "";
    }

    //Check the billing country first. If an EU country was selected, we would have made sure it matched the billing country.
    if ( ! empty( $values['billing_country'] ) ) {
        $customer_country = $values['billing_country'];
    } elseif ( ! empty( $_REQUEST['eucountry'] ) ) {
        $customer_country = sanitize_text_field( $_REQUEST['eucountry'] );
    }        //but you might have an eucountry set with no billing country
    elseif ( ! empty( $_SESSION['eucountry'] ) ) {
        $customer_country = sanitize_text_field( $_SESSION['eucountry'] );
    }        //ditto if you store in a session to go offsite
    else {
        $customer_country = "";
    }

    // calculate the tax rate
    $tax_rate = pop_getTaxRateForCustomer( $business_country, $customer_country, $vat_number );

    // add vat to total taxes
    if ( ! empty( $tax_rate ) ) {
        $tax = $tax + round( (float) $values['price'] * $tax_rate, 2 );
    }

    return $tax;
}

/**
 * Apply the same VAT rate to all countries (Council Directive 2006/112/EC).
 * This hook is from the PMPro VAT Tax Addon, which is not required by POP though.
 */
function pop_pmproSetFixedTaxRate_CouncilDirective_2006_112_EC( $vat_by_country ) {
    $business_country = pop_pmproGetBusinessAddressCountry();
    if ( empty( $business_country ) || ! isset( $vat_by_country[ $business_country ] ) ) {
        return $vat_by_country;
    }

    foreach ( $vat_by_country as $country => $vat ) {
        $vat_by_country[ $country ] = $vat_by_country[ $business_country ];
    }

    return $vat_by_country;
}

/**
 * Calculate the tax rate for the customer.
 *
 * @param string $business_country
 * @param string $customer_country
 * @param string $vat_number
 *
 * @return float|int
 */
function pop_getTaxRateForCustomer( $business_country, $customer_country, $vat_number ) {
    $business_country = strtoupper( sanitize_text_field( (string) $business_country ) );
    $customer_country = strtoupper( sanitize_text_field( (string) $customer_country ) );

    // default to business country rate
    $tax_rate = pop_getTaxRateByCountry( $business_country );

    // if the customer is from a different country than the business address, check the vies
    if ( ! empty( $vat_number ) && ! empty( $customer_country ) && $business_country !== $customer_country ) {
        // convert ISO country designation to EU Vat country designation
        if ( $customer_country == 'GR' ) {
            $customer_country = 'EL';
        }

        $vat_number_normalized = \WcElectronInvoice\Functions\normalizeVatForVies( $vat_number, $customer_country );

        if ( WcElectronInvoice\WooCommerce\Fields\InvoiceFields::viesCheck( $vat_number_normalized, $customer_country ) ) {
            $tax_rate = 0;
        }
    }

    return $tax_rate;
}

/**
 * Get the business address country from PMPro settings.
 * PMPro 3.2+ is needed, which introduced the pmpro business address setting.
 *
 * @return string
 */
function pop_pmproGetBusinessAddressCountry() {
    $pmpro_business_address = get_option( 'pmpro_business_address' );
    $business_country       = $pmpro_business_address['country'] ?? '';

    return $business_country;
}

/**
 * @param string $country
 *
 * @return array|int|mixed
 */
function pop_getTaxRates() {
    $vat_by_country = array(
        "BE" => 0.21,
        "BG" => 0.20,
        "CZ" => 0.21,
        "DK" => 0.25,
        "DE" => 0.19,
        "EE" => 0.24,
        "GR" => 0.24,        //EL
        "ES" => 0.21,
        "FR" => 0.20,
        "HR" => 0.25,
        "IE" => 0.23,
        "IT" => 0.22,
        "CY" => 0.19,
        "LV" => 0.21,
        "LT" => 0.21,
        "LU" => 0.17,
        "HU" => 0.27,
        "MT" => 0.18,
        "NL" => 0.21,
        "AT" => 0.20,
        "PL" => 0.23,
        "PT" => 0.23,
        "RO" => 0.21,
        "SI" => 0.22,
        "SK" => 0.23,
        "FI" => 0.255,
        "SE" => 0.25,
        "GB" => 0.20,        //UK
        "CA" => array( "BC" => 0.05 )
    );

    return $vat_by_country;
}

function pop_getTaxRateByCountry( $country = '' ) {
    $vat_by_country = pop_getTaxRates();

    return $vat_by_country[ $country ] ?? 0;
}
