<?php

use Automattic\Jetpack\Constants;
if (!defined('ABSPATH')) {
    exit;
}
class WC_Gateway_COD extends WC_Payment_Gateway
{
    public function __construct()
    {
        $this->setup_properties();
        $this->init_form_fields();
        $this->init_settings();
        $this->title = $this->get_option('title');
        $this->description = $this->get_option('description');
        $this->instructions = $this->get_option('instructions');
        $this->enable_for_methods = $this->get_option('enable_for_methods', array());
        $this->enable_for_virtual = $this->get_option('enable_for_virtual', 'yes') === 'yes';
        add_action('woocommerce_update_options_payment_gateways_' . $this->id, array($this, 'process_admin_options'));
        add_action('woocommerce_thankyou_' . $this->id, array($this, 'thankyou_page'));
        add_filter('woocommerce_payment_complete_order_status', array($this, 'change_payment_complete_order_status'), 10, 3);
        add_action('woocommerce_email_before_order_table', array($this, 'email_instructions'), 10, 3);
    }
    protected function setup_properties()
    {
        $this->id = 'cod';
        $this->icon = apply_filters('woocommerce_cod_icon', '');
        $this->method_title = __('Cash on delivery', 'woocommerce');
        $this->method_description = __('Have your customers pay with cash (or by other means) upon delivery.', 'woocommerce');
        $this->has_fields = false;
    }
    public function init_form_fields()
    {
        $this->form_fields = array('enabled' => array('title' => __('Enable/Disable', 'woocommerce'), 'label' => __('Enable cash on delivery', 'woocommerce'), 'type' => 'checkbox', 'description' => '', 'default' => 'no'), 'title' => array('title' => __('Title', 'woocommerce'), 'type' => 'text', 'description' => __('Payment method description that the customer will see on your checkout.', 'woocommerce'), 'default' => __('Cash on delivery', 'woocommerce'), 'desc_tip' => true), 'description' => array('title' => __('Description', 'woocommerce'), 'type' => 'textarea', 'description' => __('Payment method description that the customer will see on your website.', 'woocommerce'), 'default' => __('Pay with cash upon delivery.', 'woocommerce'), 'desc_tip' => true), 'instructions' => array('title' => __('Instructions', 'woocommerce'), 'type' => 'textarea', 'description' => __('Instructions that will be added to the thank you page.', 'woocommerce'), 'default' => __('Pay with cash upon delivery.', 'woocommerce'), 'desc_tip' => true), 'enable_for_methods' => array('title' => __('Enable for shipping methods', 'woocommerce'), 'type' => 'multiselect', 'class' => 'wc-enhanced-select', 'css' => 'width: 400px;', 'default' => '', 'description' => __('If COD is only available for certain methods, set it up here. Leave blank to enable for all methods.', 'woocommerce'), 'options' => $this->load_shipping_method_options(), 'desc_tip' => true, 'custom_attributes' => array('data-placeholder' => __('Select shipping methods', 'woocommerce'))), 'enable_for_virtual' => array('title' => __('Accept for virtual orders', 'woocommerce'), 'label' => __('Accept COD if the order is virtual', 'woocommerce'), 'type' => 'checkbox', 'default' => 'yes'));
    }
    public function is_available()
    {
        $order = null;
        $needs_shipping = false;
        if (WC()->cart && WC()->cart->needs_shipping()) {
            $needs_shipping = true;
        } elseif (is_page(wc_get_page_id('checkout')) && 0 < get_query_var('order-pay')) {
            $order_id = absint(get_query_var('order-pay'));
            $order = wc_get_order($order_id);
            if ($order && 0 < count($order->get_items())) {
                foreach ($order->get_items() as $item) {
                    $_product = $item->get_product();
                    if ($_product && $_product->needs_shipping()) {
                        $needs_shipping = true;
                        break;
                    }
                }
            }
        }
        $needs_shipping = apply_filters('woocommerce_cart_needs_shipping', $needs_shipping);
        if (!$this->enable_for_virtual && !$needs_shipping) {
            return false;
        }
        if (!empty($this->enable_for_methods) && $needs_shipping) {
            $order_shipping_items = is_object($order) ? $order->get_shipping_methods() : false;
            $chosen_shipping_methods_session = WC()->session->get('chosen_shipping_methods');
            if ($order_shipping_items) {
                $canonical_rate_ids = $this->get_canonical_order_shipping_item_rate_ids($order_shipping_items);
            } else {
                $canonical_rate_ids = $this->get_canonical_package_rate_ids($chosen_shipping_methods_session);
            }
            if (!count($this->get_matching_rates($canonical_rate_ids))) {
                return false;
            }
        }
        return parent::is_available();
    }
    private function is_accessing_settings()
    {
        if (is_admin()) {
            if (!isset($_REQUEST['page']) || 'wc-settings' !== $_REQUEST['page']) {
                return false;
            }
            if (!isset($_REQUEST['tab']) || 'checkout' !== $_REQUEST['tab']) {
                return false;
            }
            if (!isset($_REQUEST['section']) || 'cod' !== $_REQUEST['section']) {
                return false;
            }
            return true;
        }
        if (Constants::is_true('REST_REQUEST')) {
            global $wp;
            if (isset($wp->query_vars['rest_route']) && false !== strpos($wp->query_vars['rest_route'], '/payment_gateways')) {
                return true;
            }
        }
        return false;
    }
    private function load_shipping_method_options()
    {
        if (!$this->is_accessing_settings()) {
            return array();
        }
        $data_store = WC_Data_Store::load('shipping-zone');
        $raw_zones = $data_store->get_zones();
        foreach ($raw_zones as $raw_zone) {
            $zones[] = new WC_Shipping_Zone($raw_zone);
        }
        $zones[] = new WC_Shipping_Zone(0);
        $options = array();
        foreach (WC()->shipping()->load_shipping_methods() as $method) {
            $options[$method->get_method_title()] = array();
            $options[$method->get_method_title()][$method->id] = sprintf(__('Any &quot;%1$s&quot; method', 'woocommerce'), $method->get_method_title());
            foreach ($zones as $zone) {
                $shipping_method_instances = $zone->get_shipping_methods();
                foreach ($shipping_method_instances as $shipping_method_instance_id => $shipping_method_instance) {
                    if ($shipping_method_instance->id !== $method->id) {
                        continue;
                    }
                    $option_id = $shipping_method_instance->get_rate_id();
                    $option_instance_title = sprintf(__('%1$s (#%2$s)', 'woocommerce'), $shipping_method_instance->get_title(), $shipping_method_instance_id);
                    $option_title = sprintf(__('%1$s &ndash; %2$s', 'woocommerce'), $zone->get_id() ? $zone->get_zone_name() : __('Other locations', 'woocommerce'), $option_instance_title);
                    $options[$method->get_method_title()][$option_id] = $option_title;
                }
            }
        }
        return $options;
    }
    private function get_canonical_order_shipping_item_rate_ids($order_shipping_items)
    {
        $canonical_rate_ids = array();
        foreach ($order_shipping_items as $order_shipping_item) {
            $canonical_rate_ids[] = $order_shipping_item->get_method_id() . ':' . $order_shipping_item->get_instance_id();
        }
        return $canonical_rate_ids;
    }
    private function get_canonical_package_rate_ids($chosen_package_rate_ids)
    {
        $shipping_packages = WC()->shipping()->get_packages();
        $canonical_rate_ids = array();
        if (!empty($chosen_package_rate_ids) && is_array($chosen_package_rate_ids)) {
            foreach ($chosen_package_rate_ids as $package_key => $chosen_package_rate_id) {
                if (!empty($shipping_packages[$package_key]['rates'][$chosen_package_rate_id])) {
                    $chosen_rate = $shipping_packages[$package_key]['rates'][$chosen_package_rate_id];
                    $canonical_rate_ids[] = $chosen_rate->get_method_id() . ':' . $chosen_rate->get_instance_id();
                }
            }
        }
        return $canonical_rate_ids;
    }
    private function get_matching_rates($rate_ids)
    {
        return array_unique(array_merge(array_intersect($this->enable_for_methods, $rate_ids), array_intersect($this->enable_for_methods, array_unique(array_map('wc_get_string_before_colon', $rate_ids)))));
    }
    public function process_payment($order_id)
    {
        $order = wc_get_order($order_id);
        if ($order->get_total() > 0) {
            $order->update_status(apply_filters('woocommerce_cod_process_payment_order_status', $order->has_downloadable_item() ? 'on-hold' : 'processing', $order), __('Payment to be made upon delivery.', 'woocommerce'));
        } else {
            $order->payment_complete();
        }
        WC()->cart->empty_cart();
        return array('result' => 'success', 'redirect' => $this->get_return_url($order));
    }
    public function thankyou_page()
    {
        if ($this->instructions) {
            echo wp_kses_post(wpautop(wptexturize($this->instructions)));
        }
    }
    public function change_payment_complete_order_status($status, $order_id = 0, $order = false)
    {
        if ($order && 'cod' === $order->get_payment_method()) {
            $status = 'completed';
        }
        return $status;
    }
    public function email_instructions($order, $sent_to_admin, $plain_text = false)
    {
        if ($this->instructions && !$sent_to_admin && $this->id === $order->get_payment_method()) {
            echo wp_kses_post(wpautop(wptexturize($this->instructions)) . PHP_EOL);
        }
    }
}