<?php

namespace Devurai\AcceptbluePaymentPro\Surcharge;

use Devurai\AcceptbluePaymentPro\Settings\ACHSettings;
use Devurai\AcceptbluePaymentPro\Settings\CCSettings;
use Devurai\AcceptbluePaymentPro\Settings\GooglePaySettings;
use Devurai\AcceptbluePaymentPro\Settings\SettingsMap;
use Devurai\AcceptbluePaymentPro\Traits\SubscriptionFunctions;

class Surcharge
{
    use SubscriptionFunctions;
    public function __construct()
    {
        add_action('wp_enqueue_scripts', [$this, 'enqueue_scripts']);
        add_filter('pgabfw_cc_request_data', array($this, 'add_surcharge'), 10, 3);
        add_filter('pgabfw_ach_request_data', array($this, 'add_surcharge'), 10, 3);
        add_filter('pgabfw_google_pay_request_data', array($this, 'add_surcharge'), 10, 3);
        add_filter('wc_acceptblue_settings_credit_card', array($this, 'add_surcharge_settings'));
        add_filter('wc_acceptblue_settings_ach', array($this, 'add_surcharge_settings'));
        add_filter('wc_acceptblue_settings_google_pay', array($this, 'add_surcharge_settings'));
        add_action('pgabfw_before_transaction_update', array($this, 'update_surcharge'), 5, 2);
        add_filter('pgabfw_surcharge_amount', array($this, 'calculate_surcharge_amount'), 10, 3);
        add_action('woocommerce_order_status_failed', array($this, 'track_failed_orders'));
    }

    public function enqueue_scripts(): void
    {
        if(is_admin()) return;
        if($this->is_checkout()) {
            wp_enqueue_script('pgabfw_surcharge', pgabfw_pro_assets_url('js/pgabfw_surcharge.js'), array('jquery'), '1.0', array());
            wp_localize_script('pgabfw_surcharge', 'pgabfwSurcharge', self::get_surcharge_notification());
            wp_enqueue_script('pgabfw_surcharge_credit_block', pgabfw_pro_root_url('wc_blocks/credit_surcharge.js'), array('wp-element'), '1.0', array());
            wp_enqueue_script('pgabfw_surcharge_check_block', pgabfw_pro_root_url('wc_blocks/ach_surcharge.js'), array('wp-element'), '1.0', array());
            wp_enqueue_script('pgabfw_surcharge_google_pay_block', pgabfw_pro_root_url('wc_blocks/google_pay_surcharge.js'), array('wp-element'), '1.0', array());
        }
    }

    protected static function get_surcharge_notification(): array
    {
        $data = array(
            'success' => false,
            'card' => '',
            'check' => '',
            'google_pay' => '',
            'tokens' => self::get_credit_card_token_ids()
        );

        $settingsList = [
            'card' => CCSettings::getInstance(),
            'check' => ACHSettings::getInstance(),
            'google_pay' => GooglePaySettings::getInstance()
        ];

        $message = "Please note, a %s surcharge will be added to your order.";

        foreach ($settingsList as $type => $settings) {
            if ($settings->is_surcharge()) {
                $data = self::create_notification($message, $settings, $type, $data);
            }
        }

        return $data;
    }

    public static function create_notification($message, $settings, $type, $data) {
        $surcharge_amount = $settings->get_surcharge_amount();

        if ($surcharge_amount > 0) {
            $symbol = $settings->is_surcharge_currency() ? get_woocommerce_currency_symbol() : '%';
            $data[$type] = sprintf($message, $surcharge_amount . $symbol);
            $data['success'] = true;
            return $data;
        }

        return $data;
    }

    public static function get_credit_card_token_ids(): array
    {
            global $wpdb;

            $tokens = $wpdb->get_results(
                "
                        SELECT token_id, gateway_id FROM {$wpdb->prefix}woocommerce_payment_tokens
                        WHERE gateway_id IN ('acceptblue-cc', 'acceptblue-google-pay')"
                , ARRAY_A);

            $tokens = is_array($tokens) ? $tokens : array();

            $new_arr = array();
            $map = array(
                'acceptblue-cc' => 'card',
                'acceptblue-google-pay' => 'google_pay'
            );
            foreach ($tokens as $token) {
                if (!array_key_exists($token['token_id'], $new_arr)) {
                    $new_arr[$token['token_id']] = '';
                }
                $new_arr[$token['token_id']] = $map[$token['gateway_id']] ?? $token['gateway_id'];
            }
//            return array_map(function ($item){ return $item['token_id']; }, $tokens);
            return $new_arr;
    }

    protected function is_checkout(): bool
    {
        global $post;

        if($post instanceof \WP_Post){
           return is_checkout() || wc_post_content_has_shortcode( 'woocommerce_checkout' ) || has_block('woocommerce/checkout-payment-block', $post);
        }else{
            return false;
        }

    }

    public function add_surcharge($args, $id, $order): array
    {

        if (defined('REST_REQUEST') && REST_REQUEST) {
            $s_id = intval($order->get_meta('_pgabfw_surcharge_id'));
            if ($s_id !== 0) return $args;
        }

        /**
         * @var $order \WC_Order
         * @var $settings CCSettings|ACHSettings|GooglePaySettings|false
         */
        $settings = SettingsMap::get($id);

        if($settings === false) {
            if(function_exists('pgabfw_log')) pgabfw_log('error', $settings->get_gateway_id(), "Settings for id: $id  not found." );
            return $args;
        }

        if(!$settings->is_surcharge()){
            return $args;
        }

        //get surcharge amount for the renewal subscription order start
        $surcharge_settings = null;
        if(wcs_order_contains_renewal($order)){
            if($this->get_subscription_from_order($order->get_id(), $subscription)) {
                $surcharge_settings = $this->get_surcharge_settings_from_order($subscription);
                $surcharge_amount = $this->get_calculated_surcharge_amount($surcharge_settings, $order->get_subtotal());
            }else{
                $surcharge_amount = 0;
            }
        }else {
            $surcharge_amount = $this->get_calculated_surcharge_amount($settings, $order->get_subtotal());
        }
        //get surcharge amount for the renewal subscription order end

        if($surcharge_amount > 0) {
            //save surcharge to the subscription start
            if($this->is_initial_subscription_order($order->get_id())){
                if($this->get_subscription_from_order($order->get_id(), $subscription)) {
                    $surcharge_settings = new SurchargeSettings();
                    $surcharge_settings->set_surcharge_amount(floatval($settings->get_surcharge_amount()));
                    $surcharge_settings->set_surcharge_type($settings->get_surcharge_type());
                    $surcharge_settings->set_surcharge_tax($settings->get_surcharge_tax());
                    $this->save_surcharge_to_order($subscription, $surcharge_settings);
                }
            }
            //save surcharge to the subscription end

            $surcharge_fee = new \WC_Order_Item_Fee();

            $type = $settings->get_title();

            $surcharge_fee->set_name("$type surcharge");
            $surcharge_fee->set_amount($surcharge_fee);
            $surcharge_fee->set_tax_class('');
            if($surcharge_settings !== null){
                //set surcharge tax from the saved in subscription surcharge settings
                $surcharge_fee->set_tax_status($surcharge_settings->get_surcharge_tax());
            }else {
                //set surcharge tax from the general settings
                $surcharge_fee->set_tax_status($settings->get_surcharge_tax());
            }
            $surcharge_fee->set_total($surcharge_amount);

            $order->add_item($surcharge_fee);
            $order->calculate_totals();
            $order->add_meta_data('_pgabfw_surcharge_id', $surcharge_fee->get_id());
            $order->save();

            $surcharge_total_tax = floatval($surcharge_fee->get_total_tax());

            $surcharge_amount = $surcharge_amount + $surcharge_total_tax;

            if(array_key_exists('amount_details', $args)) {
                $args['amount_details']->surcharge = $surcharge_amount;
            }else{
                $args['amount_details'] = (object) array('surcharge' => $surcharge_amount);
            }
            $args['amount'] = floatval($args['amount']) + $surcharge_amount;
//            $args['amount'] = $args['amount'] + $surcharge_amount;
        }

        return $args;
    }

    private function get_calculated_surcharge_amount($settings, $amount): float
    {
        /**
         * @var $settings CCSettings|GooglePaySettings|SurchargeSettings
         */
        if($settings->is_surcharge_currency()) {
            $surcharge_amount = $settings->get_surcharge_amount();
        }else{
            $surcharge_amount = $this->calculate_percentage_surcharge($settings->get_surcharge_amount(), $amount);
        }
        return $surcharge_amount;
    }

    private function calculate_percentage_surcharge($percentage, $total_price): float
    {
        $percentage = floatval($percentage);
        $percentage = $percentage / 100;

        return floatval($total_price * $percentage);
    }

    public function add_surcharge_settings($settings)
    {
        $settings['enable_surcharge'] = array(
            'title' => __('Enabled/Disabled', 'payment-gateway-accept-blue-for-woocommerce'),
            'label'       => __( 'Surcharge', 'payment-gateway-accept-blue-for-woocommerce' ),
            'type'        => 'checkbox',
            'description' => '',
            'default'     => 'no',
        );

        $settings['surcharge_amount'] = array(
            'title'       => __( 'Surcharge amount', 'payment-gateway-accept-blue-for-woocommerce' ),
            'type'        => 'text',
            'description' => __( '' ),
            'default'     => '',
            'desc_tip'    => true,
        );

        $settings['surcharge_type'] = array(
            'title'       => __('Surcharge type', 'payment-gateway-accept-blue-for-woocommerce' ),
            'type'        => 'select',
            'description' => '',
            'default'     => 'currency',
            'options'     => array(
                'currency' => 'Currency',
                'percentage' => 'Percentage'
            )

        );

        $settings['surcharge_tax'] = array(
            'title'       => __('Surcharge tax', 'payment-gateway-accept-blue-for-woocommerce' ),
            'type'        => 'select',
            'description' => '',
            'default'     => 'none',
            'options'     => array(
                'none' => 'None',
                'taxable' => 'Taxable'
            )

        );


        return $settings;
    }

    public function update_surcharge($order): void
    {

        /**
         * @var $order \WC_Order
         */

        if (!is_admin()) return;

        try {
            $payment_method_id = $order->get_payment_method();
            if ($payment_method_id !== 'acceptblue-cc') {
                return;
            }

            $settings = CCSettings::getInstance();
            if (!$settings->is_surcharge_percentage()) {
                return;
            }

            $surcharge_id = intval($order->get_meta('_pgabfw_surcharge_id'));
            if ($surcharge_id === 0) {
                return;
            }

            /**
             * @var $surcharge_fee \WC_Order_Item_Fee
             */
            $surcharge_fee = $order->get_item($surcharge_id);
            if (!$surcharge_fee) {
                return;
            }

            $subtotal = $order->get_subtotal();
            $new_surcharge_amount = self::get_calculated_surcharge_amount($settings, $subtotal);
            $current_surcharge = $surcharge_fee->get_total();

            if ($current_surcharge === (string)$new_surcharge_amount) {
                return;
            }

            $surcharge_fee->set_amount($new_surcharge_amount);
            $surcharge_fee->set_total($new_surcharge_amount);
            $surcharge_fee->set_tax_class('');
            $surcharge_fee->set_tax_status($settings->get_surcharge_tax());

            $surcharge_fee->save();

            $order->add_item($surcharge_fee);
            $order->calculate_totals();

            $order->save();

        } catch (\Exception $e) {
            error_log('Error in update_surcharge: ' . $e->getMessage());
        }

    }

    public function calculate_surcharge_amount($surcharge_amount, $total_price, $settings): float
    {
        /**
         * @var $settings CCSettings|ACHSettings|GooglePaySettings
         */
        if($settings->is_surcharge()) {
            return $this->get_calculated_surcharge_amount($settings, $total_price);
        }else{
            return $surcharge_amount;
        }
    }

    public function track_failed_orders($order_id)
    {
        $order = wc_get_order($order_id);

        if(!$order instanceof \WC_Order) return;

        if (defined('REST_REQUEST') && REST_REQUEST && !is_admin()) {
            $s_id = intval($order->get_meta('_pgabfw_surcharge_id'));
            if ($s_id === 0) return;

            $order->remove_item($s_id);
            $order->calculate_totals();
            $order->delete_meta_data('_pgabfw_surcharge_id');
            $order->save();

        }
    }
}