<?php

namespace ChinaPayments\Optimizations;

use ChinaPayments\CurrencyConverter;
use ChinaPayments\Settings;
class MultiCurrency {
    /**
     * @var MultiCurrency|null
     */
    protected static $_instance = null;

    public static function instance() : MultiCurrency {
        if ( self::$_instance === null ) {
            self::$_instance = new self();
        }
        return self::$_instance;
    }

    public function setup() {
        if ( !$this->_is_enabled() ) {
            return;
        }
        if ( is_admin() ) {
            return;
        }
        add_filter(
            'woocommerce_get_price_html',
            array($this, '_append_cny_to_price'),
            100,
            2
        );
        add_filter(
            'woocommerce_cart_item_price',
            array($this, '_append_cny_to_cart_item_price'),
            100,
            3
        );
        add_filter(
            'woocommerce_cart_item_subtotal',
            array($this, '_append_cny_to_cart_subtotal'),
            100,
            3
        );
        add_filter(
            'woocommerce_cart_subtotal',
            array($this, '_append_cny_to_subtotal'),
            100,
            3
        );
        add_filter( 'woocommerce_cart_totals_order_total_html', array($this, '_append_cny_to_order_total'), 100 );
        add_filter(
            'woocommerce_cart_shipping_method_full_label',
            array($this, '_append_cny_to_shipping'),
            100,
            2
        );
        add_filter(
            'woocommerce_cart_totals_fee_html',
            array($this, '_append_cny_to_fee'),
            100,
            2
        );
        add_filter( 'woocommerce_cart_totals_taxes_total_html', array($this, '_append_cny_to_tax_total'), 100 );
        add_filter(
            'woocommerce_cart_tax_totals',
            array($this, '_append_cny_to_tax_totals'),
            100,
            2
        );
        add_action( 'wp_head', array($this, '_output_styles') );
        // Enqueue frontend JS for WooCommerce Blocks CNY display
        add_action( 'wp_enqueue_scripts', array($this, '_enqueue_frontend_script') );
    }

    protected function _is_enabled() : bool {
        if ( !function_exists( 'china_payments_fs' ) ) {
            return false;
        }
        return false;
        if ( !china_payments_fs()->can_use_premium_code() ) {
            return false;
        }
        return (bool) Settings::instance()->get( 'multi_currency_enabled' );
    }

    protected function _get_store_currency() : string {
        if ( function_exists( 'get_woocommerce_currency' ) ) {
            return strtoupper( get_woocommerce_currency() );
        }
        return 'USD';
    }

    /**
     * Append CNY to product price display.
     */
    public function _append_cny_to_price( $price_html, $product ) {
        if ( strtoupper( $this->_get_store_currency() ) === 'CNY' ) {
            return $price_html;
        }
        // Use the display price so the CNY estimate matches the figure shown,
        // honoring the shop tax-display setting (woocommerce_tax_display_shop).
        $price = ( function_exists( 'wc_get_price_to_display' ) ? (float) wc_get_price_to_display( $product ) : (float) $product->get_price() );
        if ( $price <= 0 ) {
            return $price_html;
        }
        return CurrencyConverter::instance()->get_display_with_cny( $price_html, $price, $this->_get_store_currency() );
    }

    /**
     * Append CNY to cart item price.
     */
    public function _append_cny_to_cart_item_price( $price_html, $cart_item, $cart_item_key ) {
        if ( strtoupper( $this->_get_store_currency() ) === 'CNY' ) {
            return $price_html;
        }
        // Match the unit price WooCommerce displays in the cart, which honors the
        // cart tax-display setting (incl/excl) via WC_Cart::get_product_price().
        $product = $cart_item['data'];
        if ( function_exists( 'wc_get_price_including_tax' ) && function_exists( 'WC' ) && WC()->cart ) {
            $price = ( WC()->cart->display_prices_including_tax() ? (float) wc_get_price_including_tax( $product ) : (float) wc_get_price_excluding_tax( $product ) );
        } else {
            $price = (float) $cart_item['data']->get_price();
        }
        if ( $price <= 0 ) {
            return $price_html;
        }
        return CurrencyConverter::instance()->get_display_with_cny( $price_html, $price, $this->_get_store_currency() );
    }

    /**
     * Append CNY to cart item subtotal.
     */
    public function _append_cny_to_cart_subtotal( $subtotal_html, $cart_item, $cart_item_key ) {
        if ( strtoupper( $this->_get_store_currency() ) === 'CNY' ) {
            return $subtotal_html;
        }
        $subtotal = (float) $cart_item['line_subtotal'];
        // In tax-inclusive display the line subtotal is shown with its tax, so
        // add it to keep the CNY estimate aligned with the displayed amount.
        if ( function_exists( 'WC' ) && WC()->cart && WC()->cart->display_prices_including_tax() && isset( $cart_item['line_subtotal_tax'] ) ) {
            $subtotal += (float) $cart_item['line_subtotal_tax'];
        }
        if ( $subtotal <= 0 ) {
            return $subtotal_html;
        }
        return CurrencyConverter::instance()->get_display_with_cny( $subtotal_html, $subtotal, $this->_get_store_currency() );
    }

    /**
     * Append CNY to cart subtotal.
     */
    public function _append_cny_to_subtotal( $subtotal_html, $compound, $cart ) {
        if ( strtoupper( $this->_get_store_currency() ) === 'CNY' ) {
            return $subtotal_html;
        }
        if ( !is_object( $cart ) || !method_exists( $cart, 'get_subtotal' ) ) {
            return $subtotal_html;
        }
        $subtotal = (float) $cart->get_subtotal();
        // In tax-inclusive display the cart subtotal is shown with its tax.
        if ( method_exists( $cart, 'display_prices_including_tax' ) && $cart->display_prices_including_tax() && method_exists( $cart, 'get_subtotal_tax' ) ) {
            $subtotal += (float) $cart->get_subtotal_tax();
        }
        if ( $subtotal <= 0 ) {
            return $subtotal_html;
        }
        return CurrencyConverter::instance()->get_display_with_cny( $subtotal_html, $subtotal, $this->_get_store_currency() );
    }

    /**
     * Append CNY to order total.
     */
    public function _append_cny_to_order_total( $total_html ) {
        if ( strtoupper( $this->_get_store_currency() ) === 'CNY' ) {
            return $total_html;
        }
        if ( !function_exists( 'WC' ) || !WC()->cart ) {
            return $total_html;
        }
        $total = (float) WC()->cart->get_total( 'raw' );
        if ( $total <= 0 ) {
            return $total_html;
        }
        return CurrencyConverter::instance()->get_display_with_cny( $total_html, $total, $this->_get_store_currency() );
    }

    /**
     * Append CNY to a shipping method full label.
     *
     * Fires once per available rate (single-rate and multi-rate/radio
     * displays) on the classic cart and checkout review-order rows. Mirrors
     * WooCommerce's own displayed figure: the shipping tax is added when the
     * store displays shipping prices including tax (wc_cart_totals_shipping_method_label()),
     * so the CNY estimate matches the amount printed on the same row. Free
     * shipping / local pickup at 0 are skipped by the guard.
     */
    public function _append_cny_to_shipping( $label, $method ) {
        if ( strtoupper( $this->_get_store_currency() ) === 'CNY' ) {
            return $label;
        }
        if ( !is_object( $method ) || !method_exists( $method, 'get_cost' ) ) {
            return $label;
        }
        $cost = (float) $method->get_cost();
        if ( function_exists( 'WC' ) && WC()->cart && WC()->cart->display_prices_including_tax() && method_exists( $method, 'get_shipping_tax' ) ) {
            $cost += (float) $method->get_shipping_tax();
        }
        if ( $cost <= 0 ) {
            return $label;
        }
        return CurrencyConverter::instance()->get_display_with_cny( $label, $cost, $this->_get_store_currency() );
    }

    /**
     * Append CNY to a cart fee line.
     *
     * Mirrors WooCommerce's displayed figure: the fee tax is added when the
     * store displays cart prices including tax (wc_cart_totals_fee_html()).
     * Negative fees (discounts) are skipped by the <= 0 guard.
     */
    public function _append_cny_to_fee( $fee_html, $fee ) {
        if ( strtoupper( $this->_get_store_currency() ) === 'CNY' ) {
            return $fee_html;
        }
        $amount = ( is_object( $fee ) && isset( $fee->total ) ? (float) $fee->total : 0 );
        if ( is_object( $fee ) && isset( $fee->tax ) && function_exists( 'WC' ) && WC()->cart && WC()->cart->display_prices_including_tax() ) {
            $amount += (float) $fee->tax;
        }
        if ( $amount <= 0 ) {
            return $fee_html;
        }
        return CurrencyConverter::instance()->get_display_with_cny( $fee_html, $amount, $this->_get_store_currency() );
    }

    /**
     * Append CNY to the combined tax-total line.
     *
     * Covers the "single total" tax display mode (woocommerce_tax_total_display
     * = 'single'), where the row is rendered via wc_cart_totals_taxes_total_html().
     * The default 'itemized' mode is handled by _append_cny_to_tax_totals().
     */
    public function _append_cny_to_tax_total( $tax_html ) {
        if ( strtoupper( $this->_get_store_currency() ) === 'CNY' ) {
            return $tax_html;
        }
        if ( !function_exists( 'WC' ) || !WC()->cart ) {
            return $tax_html;
        }
        $tax = (float) WC()->cart->get_taxes_total();
        if ( $tax <= 0 ) {
            return $tax_html;
        }
        return CurrencyConverter::instance()->get_display_with_cny( $tax_html, $tax, $this->_get_store_currency() );
    }

    /**
     * Append CNY to itemized tax-total rows.
     *
     * Covers the default 'itemized' tax display, where each tax rate is
     * rendered from WC_Cart::get_tax_totals() (no per-row HTML filter exists,
     * so we annotate the formatted_amount on each total object here). Each
     * object's ->amount is the raw tax figure; rows are display-only and the
     * array is rebuilt on every call, so annotating once per object is safe.
     */
    public function _append_cny_to_tax_totals( $tax_totals, $cart ) {
        if ( strtoupper( $this->_get_store_currency() ) === 'CNY' ) {
            return $tax_totals;
        }
        if ( !is_array( $tax_totals ) ) {
            return $tax_totals;
        }
        foreach ( $tax_totals as $tax ) {
            if ( !is_object( $tax ) || !isset( $tax->formatted_amount ) ) {
                continue;
            }
            $amount = ( isset( $tax->amount ) ? (float) $tax->amount : 0 );
            if ( $amount <= 0 ) {
                continue;
            }
            $tax->formatted_amount = CurrencyConverter::instance()->get_display_with_cny( $tax->formatted_amount, $amount, $this->_get_store_currency() );
        }
        return $tax_totals;
    }

    /**
     * Output minimal CSS for CNY display.
     */
    public function _output_styles() {
        echo '<style>.china-payments-cny-equivalent{color:#888;font-size:0.85em;white-space:nowrap;}</style>';
    }

    /**
     * Enqueue frontend JS for WooCommerce Blocks CNY display.
     *
     * Block-based cart/checkout render prices via React/JS,
     * bypassing PHP price filters. This script appends CNY
     * equivalents to block-rendered price elements.
     */
    public function _enqueue_frontend_script() {
        if ( is_admin() ) {
            return;
        }
        $store_currency = $this->_get_store_currency();
        if ( strtoupper( $store_currency ) === 'CNY' ) {
            return;
        }
        $rate = CurrencyConverter::instance()->get_rate( $store_currency, 'CNY' );
        if ( $rate === false ) {
            return;
        }
        $script_url = plugins_url( 'interface/js/multi-currency-frontend.js', CHINA_PAYMENTS_BASE_FILE_PATH );
        wp_enqueue_script(
            'china-payments-multi-currency-frontend',
            $script_url,
            array(),
            CHINA_PAYMENTS_VERSION,
            true
        );
        wp_localize_script( 'china-payments-multi-currency-frontend', 'chinaPaymentsMultiCurrency', array(
            'rate'          => (string) $rate,
            'storeCurrency' => $store_currency,
        ) );
    }

}
