<?php

defined( 'ABSPATH' ) or exit;

if ( ! class_exists( 'PW_Gift_Cards_Admin' ) ) :

final class PW_Gift_Cards_Admin {

    public $settings;

    function __construct() {
        global $pw_gift_cards;

        $this->settings = array(
            array(
                'title' => __( 'PW Gift Cards', 'pw-woocommerce-gift-cards' ),
                'type'  => 'title',
                'desc'  => '',
                'id'    => 'pw_gift_cards_options',
            ),
            array(
                'title'   => __( 'Allow Scheduled Delivery', 'pw-woocommerce-gift-cards' ),
                'desc'    => __( 'Provides a "Delivery Date" for the purchasing customer to specify that the gift card should be delivered on a certain date. Otherwise gift cards are delivered as soon as the order is marked Complete. Default: Checked.', 'pw-woocommerce-gift-cards' ),
                'id'      => 'pwgc_allow_scheduled_delivery',
                'default' => 'yes',
                'type'    => 'checkbox',
            ),
            array(
                'title'   => __( 'Calendar Format', 'pw-woocommerce-gift-cards' ),
                'desc'    => __( 'If Scheduled Delivery is allowed, this is the date format that will appear for the Delivery Date calendar. Default: YYYY-MM-DD', 'pw-woocommerce-gift-cards' ),
                'id'      => 'pwgc_pikaday_format',
                'default' => 'YYYY-MM-DD',
                'type'    => 'text',
            ),
            array(
                'title'   => __( 'Calendar First Day of the Week', 'pw-woocommerce-gift-cards' ),
                'desc'    => __( 'If Scheduled Delivery is allowed, this indicates the first day of the week for the Delivery Date calendar. 0 = Sunday, 1 = Monday. Default: 0 (Sunday)', 'pw-woocommerce-gift-cards' ),
                'id'      => 'pwgc_pikaday_first_day',
                'default' => '0',
                'type'    => 'text',
            ),
            array(
                'title'   => __( 'Auto Complete Orders', 'pw-woocommerce-gift-cards' ),
                'desc'    => __( 'When an order only contains gift cards, automatically mark the order as Complete to send the gift cards immediately.', 'pw-woocommerce-gift-cards' ),
                'id'      => 'pwgc_autocomplete_gift_card_orders',
                'default' => 'yes',
                'type'    => 'checkbox',
            ),
            array(
                'title'   => __( 'Send When Payment Received', 'pw-woocommerce-gift-cards' ),
                'desc'    => __( 'By default we wait until the order status is Complete before generating and emailing the gift card. Check this box to send the gift card immediately once the payment has been received. Scheduled gift cards will still be sent on the scheduled date. Default: Unchecked', 'pw-woocommerce-gift-cards' ),
                'id'      => 'pwgc_send_when_processing',
                'default' => 'no',
                'type'    => 'checkbox',
            ),
            array(
                'title'   => __( 'Disable Expiration Date', 'pw-woocommerce-gift-cards' ),
                'desc'    => __( 'If the law in your area prohibits an expiration date for gift cards, you can disable Expiration Dates system wide. This will hide all buttons, options, and mention of an expiration date. Default: Unchecked.', 'pw-woocommerce-gift-cards' ),
                'id'      => 'pwgc_no_expiration_date',
                'default' => 'no',
                'type'    => 'checkbox',
            ),
            array(
                'title'   => __( 'Buy Gift Cards with Gift Cards', 'pw-woocommerce-gift-cards' ),
                'desc'    => __( 'Allow customers to purchase gift cards using another gift card. Disable this to prevent customers from extending the date on expiring gift cards. Default: Unchecked.', 'pw-woocommerce-gift-cards' ),
                'id'      => 'pwgc_allow_gift_card_purchasing',
                'default' => 'no',
                'type'    => 'checkbox',
            ),
            array(
                'title'   => __( 'Check Balance on My Account', 'pw-woocommerce-gift-cards' ),
                'desc'    => __( 'When enabled, a link to the Check Balance page will be added to the My Account page. Default: checked', 'pw-woocommerce-gift-cards' ),
                'id'      => 'pwgc_check_balance_show_on_my_account',
                'default' => 'yes',
                'type'    => 'checkbox',
            ),
            array(
                'title'   => __( 'Allow Reloading', 'pw-woocommerce-gift-cards' ),
                'desc'    => __( 'When enabled, customers can add funds to an existing gift card from the Check Balance page.', 'pw-woocommerce-gift-cards' ),
                'id'      => 'pwgc_allow_reloading',
                'default' => 'yes',
                'type'    => 'checkbox',
            ),
            array(
                'title'   => __( 'Allow Manual Debit', 'pw-woocommerce-gift-cards' ),
                'desc'    => __( 'When enabled, customers or store employees can debit funds from an existing gift card from the Check Balance page. Useful for physical stores where customers will redeem the card for in store purchases.', 'pw-woocommerce-gift-cards' ),
                'id'      => 'pwgc_check_balance_allow_manual_debit',
                'default' => 'no',
                'type'    => 'checkbox',
            ),
            array(
                'title'   => __( 'Show Activity on Check Balance Page', 'pw-woocommerce-gift-cards' ),
                'desc'    => __( 'When enabled, detailed transaction history will be shown on the Check Balance page.', 'pw-woocommerce-gift-cards' ),
                'id'      => 'pwgc_check_balance_show_transactions',
                'default' => 'no',
                'type'    => 'checkbox',
            ),
            array(
                'title'   => __( 'Use the WooCommerce Transactional Email System', 'pw-woocommerce-gift-cards' ),
                'desc'    => __( 'Enabled by default. If you are not receiving your gift card emails, try disabling this setting.', 'pw-woocommerce-gift-cards' ),
                'id'      => 'pwgc_use_wc_transactional_emails',
                'default' => 'yes',
                'type'    => 'checkbox',
            ),
            array(
                'title'   => __( 'Allow Background Images', 'pw-woocommerce-gift-cards' ),
                'desc'    => __( 'Disabled by default. Check this box to allow a background image to be set in the Email Designer. Outlook does not display background images.', 'pw-woocommerce-gift-cards' ),
                'id'      => 'pwgc_allow_background_images',
                'default' => 'no',
                'type'    => 'checkbox',
            ),
            array(
                'title'   => __( 'Apply Fix For Missing Fields', 'pw-woocommerce-gift-cards' ),
                'desc'    => __( 'If you do not see the To / From / Message fields on your gift card product page, try checking this box and reloading. Some themes have out of date WooCommerce template files and need to be patched to work with the Gift Card product.', 'pw-woocommerce-gift-cards' ),
                'id'      => 'pwgc_before_add_to_cart_quantity_theme_fix',
                'default' => 'no',
                'type'    => 'checkbox',
            ),
            array(
                'title'   => __( 'Format Prices', 'pw-woocommerce-gift-cards' ),
                'desc'    => __( 'For fixed gift card amounts, format the price with the system currency symbol. This is enabled by default. If you are having trouble with currency switchers, disable this setting. Note: You must remove and re-add your fixed gift card amounts if you change this setting.', 'pw-woocommerce-gift-cards' ),
                'id'      => 'pwgc_format_prices',
                'default' => 'yes',
                'type'    => 'checkbox',
            ),
            array(
                'title'     => __( 'Pre-populate the "From" Field', 'pw-woocommerce-gift-cards' ),
                'desc'      => __( 'If the customer is logged in, populate the From field with the Display Name value for their account. Default: Checked.', 'pw-woocommerce-gift-cards' ),
                'id'        => 'pwgc_current_user_populates_from_field',
                'default'   => 'yes',
                'type'      => 'checkbox',
            ),
            array(
                'title'     => __( 'Allow Multiple Recipients', 'pw-woocommerce-gift-cards' ),
                'desc'      => __( 'Similar to how Amazon works, allow multiple recipient email addresses when purchasing a gift card. Default: Checked.', 'pw-woocommerce-gift-cards' ),
                'id'        => 'pwgc_allow_multiple_recipients',
                'default'   => 'yes',
                'type'      => 'checkbox',
            ),
            array(
                'title'     => __( 'Carbon Copy', 'pw-woocommerce-gift-cards' ),
                'desc'      => __( 'When a gift card is emailed, carbon copy these addresses. Separate multiple emails with a comma.', 'pw-woocommerce-gift-cards' ),
                'id'        => 'pwgc_cc_email',
                'default'   => '',
                'type'      => 'text',
            ),
            array(
                'title'     => __( 'Blind Carbon Copy', 'pw-woocommerce-gift-cards' ),
                'desc'      => __( 'When a gift card is emailed, blind carbon copy these addresses. Separate multiple emails with a comma.', 'pw-woocommerce-gift-cards' ),
                'id'        => 'pwgc_bcc_email',
                'default'   => '',
                'type'      => 'text',
            ),
            array(
                'title'     => __( 'Send to the Buyer', 'pw-woocommerce-gift-cards' ),
                'desc'      => __( 'When a gift card is emailed, blind carbon copy the gift card to the purchasing customer.', 'pw-woocommerce-gift-cards' ),
                'id'        => 'pwgc_bcc_buyer',
                'default'   => 'no',
                'type'      => 'checkbox',
            ),
            array(
                'title'    => __( 'Redeem Location - Cart', 'pw-woocommerce-gift-cards' ),
                'desc'     => __( 'Specifies where the "Apply Gift Card" box appears on the Cart page.', 'pw-woocommerce-gift-cards' ),
                'id'       => 'pwgc_redeem_cart_location',
                'default'  => 'proceed_to_checkout',
                'type'     => 'select',
                'class'    => 'wc-enhanced-select',
                'css'      => 'min-width: 350px;',
                'desc_tip' => false,
                'options'  => array(
                    'proceed_to_checkout' => __( 'Above the "Proceed to Checkout" button.', 'pw-woocommerce-gift-cards' ),
                    'after_cart_contents' => __( 'Below the "Apply Coupon" area.', 'pw-woocommerce-gift-cards' ),
                    'none' => __( 'Do not display gift card field.', 'pw-woocommerce-gift-cards' ),
                ),
            ),
            array(
                'title'    => __( 'Redeem Location - Checkout', 'pw-woocommerce-gift-cards' ),
                'desc'     => __( 'Specifies where the "Apply Gift Card" box appears on the Checkout page.', 'pw-woocommerce-gift-cards' ),
                'id'       => 'pwgc_redeem_checkout_location',
                'default'  => 'review_order_before_submit',
                'type'     => 'select',
                'class'    => 'wc-enhanced-select',
                'css'      => 'min-width: 350px;',
                'desc_tip' => false,
                'options'  => array(
                    'review_order_before_submit' => __( 'Below the "Payment Methods" area.', 'pw-woocommerce-gift-cards' ),
                    'before_checkout_form' => __( 'Below the "Apply Coupon" area.', 'pw-woocommerce-gift-cards' ),
                    'none' => __( 'Do not display gift card field.', 'pw-woocommerce-gift-cards' ),
                ),
            ),
            array(
                'title'   => __( 'Coupon Code Field Input', 'pw-woocommerce-gift-cards' ),
                'desc'    => __( 'Allow gift card numbers to be entered into the Coupon Code field to be redeemed. Default: checked.', 'pw-woocommerce-gift-cards' ),
                'id'      => 'pwgc_redeem_coupon_code',
                'default' => 'yes',
                'type'    => 'checkbox',
            ),
            array(
                'title'   => __( 'Strict Input', 'pw-woocommerce-gift-cards' ),
                'desc'    => __( 'For added security, a redeemed gift card number must be entered exactly, including any dashes or special characters. Default: checked.', 'pw-woocommerce-gift-cards' ),
                'id'      => 'pwgc_strict_input',
                'default' => 'yes',
                'type'    => 'checkbox',
            ),
            array(
                'title'   => __( 'Remove card after checkout', 'pw-woocommerce-gift-cards' ),
                'desc'    => __( 'After an order is placed the gift card will remain in the session for use with future purchases. Check this box to automatically remove the card from the session instead. Default: Unchecked', 'pw-woocommerce-gift-cards' ),
                'id'      => 'pwgc_remove_card_from_cart_after_checkout',
                'default' => 'no',
                'type'    => 'checkbox',
            ),
            array(
                'title'   => __( 'Use Font Awesome Icon', 'pw-woocommerce-gift-cards' ),
                // translators: %s is a link to the Font Awesome website.
                'desc'    => sprintf( __( 'On the customer facing "Check Balance" page, show a gift card icon from the %s library.', 'pw-woocommerce-gift-cards' ), '<a href="https://fontawesome.com/" target="_blank">Font Awesome</a>' ),
                'id'      => 'pwgc_use_fontawesome',
                'default' => 'yes',
                'type'    => 'checkbox',
            ),
            array(
                'title'       => __( 'Default Redeem URL', 'pw-woocommerce-gift-cards' ),
                'desc'        => __( 'The link for the Redeem button on the gift card email. Include the https prefix, the Gift Card Number is automatically appended in the URL. Can be different per Design.', 'pw-woocommerce-gift-cards' ),
                'id'          => 'pwgc_default_redeem_url',
                'placeholder' => pwgc_shop_url(),
                'default'     => '',
                'type'        => 'text',
            ),
            array(
                'title'   => __( 'Show Balances by Date', 'pw-woocommerce-gift-cards' ),
                'desc'    => __( 'On the Balances page in the admin area, optionally show a date picker to show the balances as of a certain date.', 'pw-woocommerce-gift-cards' ),
                'id'      => 'pwgc_show_balances_by_date',
                'default' => 'no',
                'type'    => 'checkbox',
            ),
            array(
                'title'   => __( 'Show Balances by Product', 'pw-woocommerce-gift-cards' ),
                'desc'    => __( 'On the Balances page in the admin area, optionally filter by the gift card product that was purchased.', 'pw-woocommerce-gift-cards' ),
                'id'      => 'pwgc_show_balances_by_product',
                'default' => 'no',
                'type'    => 'checkbox',
            ),
            array(
                'title'    => __( 'Hide Pimwick Plugins Menu', 'pw-woocommerce-gift-cards' ),
                // translators: %s is PW Gift Cards.
                'desc'     => sprintf( __( 'Do not show the Pimwick Plugins menu on the left. You can still access the dashboard via WooCommerce > %s', 'pw-woocommerce-gift-cards' ), __( 'PW Gift Cards', 'pw-woocommerce-gift-cards' ) ),
                'id'       => 'hide_pimwick_menu',
                'default'  => 'no',
                'type'     => 'checkbox',
                'desc_tip' => false,
            ),
            array(
                'type'  => 'sectionend',
                'id'    => 'pw_gift_cards_options',
            ),
        );

        add_action( 'admin_menu', array( $this, 'admin_menu' ) );
        add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
        add_filter( 'woocommerce_product_data_tabs', array( $this, 'woocommerce_product_data_tabs' ), 1 );
        add_action( 'woocommerce_product_data_panels', array( $this, 'woocommerce_product_data_panels' ) );
        add_action( 'woocommerce_variation_options', array( $this, 'woocommerce_variation_options' ), 10, 3 );
        add_action( 'woocommerce_variation_options_pricing', array( $this, 'woocommerce_variation_options_redemption_restrictions' ), 10, 3 );
        add_action( 'admin_footer', array( $this, 'admin_footer' ) );
        add_action( 'woocommerce_after_product_attribute_settings', array( $this, 'woocommerce_after_product_attribute_settings' ), 10, 2 );
        add_filter( 'woocommerce_product_filters', array( $this, 'woocommerce_product_filters' ) );
        add_action( 'woocommerce_process_product_meta_' . PWGC_PRODUCT_TYPE_SLUG, array( $this, 'process_pw_gift_card_product_meta_data' ) );
        add_action( 'woocommerce_admin_process_variation_object', array( $this, 'woocommerce_admin_process_variation_object' ), 10, 2 );
        add_action( 'woocommerce_admin_order_totals_after_tax', array( $this, 'woocommerce_admin_order_totals_after_tax' ) );
        add_filter( 'woocommerce_get_sections_products', array( $this, 'woocommerce_get_sections_products' ) );
        add_filter( 'woocommerce_get_settings_products', array( $this, 'woocommerce_get_settings_products' ), 10, 2 );
        add_filter( 'pwbe_variable_product_types', array( $this, 'pwbe_variable_product_types' ), 10, 2 );

        add_action( 'wp_ajax_pw-gift-cards-activation', array( $this, 'ajax_activation' ) );
        add_action( 'wp_ajax_pw-gift-cards-check-license', array( $this, 'ajax_check_license' ) );
        add_action( 'wp_ajax_pw-gift-cards-hide_renew_notice', array( $this, 'ajax_hide_renew_notice' ) );
        add_action( 'wp_ajax_pw-gift-cards-add_gift_card_amount', array( $this, 'ajax_add_gift_card_amount' ) );
        add_action( 'wp_ajax_pw-gift-cards-remove_gift_card_amount', array( $this, 'ajax_remove_gift_card_amount' ) );
        add_action( 'wp_ajax_pw-gift-cards-add_bonus_amount', array( $this, 'ajax_add_bonus_amount' ) );
        add_action( 'wp_ajax_pw-gift-cards-remove_bonus_amount', array( $this, 'ajax_remove_bonus_amount' ) );
        add_action( 'wp_ajax_pw-gift-cards-hide_partner_message', array( $this, 'ajax_hide_partner_message' ) );
        add_action( 'wp_ajax_pw-gift-cards-search', array( $this, 'ajax_search' ) );
        add_action( 'wp_ajax_pw-gift-cards-search_load_more', array( $this, 'ajax_search_load_more' ) );
        add_action( 'wp_ajax_pw-gift-cards-balance_summary', array( $this, 'ajax_balance_summary' ) );
        add_action( 'wp_ajax_pw-gift-cards-view_activity', array( $this, 'ajax_view_activity' ) );
        add_action( 'wp_ajax_pw-gift-cards-create_gift_card', array( $this, 'ajax_create_gift_card' ) );
        add_action( 'wp_ajax_pw-gift-cards-import_gift_cards', array( $this, 'ajax_import_gift_cards' ) );
        add_action( 'wp_ajax_pw-gift-cards-save_settings', array( $this, 'ajax_save_settings' ) );
        add_action( 'wp_ajax_pw-gift-cards-create_product', array( $this, 'ajax_create_product' ) );
        add_action( 'wp_ajax_pw-gift-cards-create_balance_page', array( $this, 'ajax_create_balance_page' ) );
        add_action( 'wp_ajax_pw-gift-cards-adjustment', array( $this, 'ajax_adjustment' ) );
        add_action( 'wp_ajax_pw-gift-cards-set_expiration_date', array( $this, 'ajax_set_expiration_date' ) );
        add_action( 'wp_ajax_pw-gift-cards-get_email_form', array( $this, 'ajax_get_email_form' ) );
        add_action( 'wp_ajax_pw-gift-cards-email_gift_card', array( $this, 'ajax_email_gift_card' ) );
        add_action( 'wp_ajax_pw-gift-cards-delete', array( $this, 'ajax_delete' ) );
        add_action( 'wp_ajax_pw-gift-cards-restore', array( $this, 'ajax_restore' ) );
        add_action( 'wp_ajax_pw-gift-cards-select_design', array( $this, 'ajax_select_design' ) );
        add_action( 'wp_ajax_pw-gift-cards-create_design', array( $this, 'ajax_create_design' ) );
        add_action( 'wp_ajax_pw-gift-cards-save_design', array( $this, 'ajax_save_design' ) );
        add_action( 'wp_ajax_pw-gift-cards-delete_design', array( $this, 'ajax_delete_design' ) );
        add_action( 'wp_ajax_pw-gift-cards-preview_email', array( $this, 'ajax_preview_email' ) );

        // Show an alert on the backend if we don't have the minimum required version.
        add_action( 'wp_ajax_pw-gift-cards-hide_paypal_ipn_pdt_bug_notice', array( $this, 'ajax_hide_paypal_ipn_pdt_bug_notice' ) );
        if ( ! get_option( 'pwgc_hide_paypal_ipn_pdt_bug_notice', false ) && pwgc_paypal_ipn_pdt_bug_exists() ) {
            add_action( 'admin_notices', array( $this, 'paypal_ipn_pdt_bug_exists' ) );
            return;
        }
    }

    function paypal_ipn_pdt_bug_exists() {
        ?>
        <div id="pwgc-paypal-ipn-pdt-bug-notice" class="error notice" style="padding: 14px;">
            <strong><?php _e( 'Configuration error detected by', 'pw-woocommerce-gift-cards' ); ?> <?php echo PWGC_PRODUCT_NAME; ?></strong>
            <p><?php _e( 'Your PayPal payment gateway is incorrectly configured. You should not have both IPN and PDT enabled. The "IPN Email Notifications" setting is enabled and there is also a "PayPal Identity Token" (PDT) value set. PayPal is reaching back to your site twice to confirm the payment. This causes things to happen twice including email notifications, stock reduction, and gift card generation. Go to WooCommerce -> Settings -> Payments -> PayPal and either clear the value from the "PayPal Identity Token" field or disable the "IPN Email Notifications" setting.', 'pw-woocommerce-gift-cards' ); ?></p>
            <button id="pwgc-paypal-ipn-pdt-bug-notice-dismiss" class="button"><?php _e( 'Dismiss this notice', 'pw-woocommerce-gift-cards' ); ?></button>
        </div>
        <script>
            jQuery('#pwgc-paypal-ipn-pdt-bug-notice-dismiss').on('click', function(e) {
                jQuery(this).attr( 'disabled', true);
                jQuery.post(ajaxurl, {'action': 'pw-gift-cards-hide_paypal_ipn_pdt_bug_notice'}, function( result ) {
                    jQuery('#pwgc-paypal-ipn-pdt-bug-notice').hide();
                });

                e.preventDefault();
                return false;
            });
        </script>
        <?php
    }

    function ajax_hide_paypal_ipn_pdt_bug_notice() {
        update_option( 'pwgc_hide_paypal_ipn_pdt_bug_notice', true );
        wp_send_json_success();
    }

    function admin_menu() {
        global $pw_gift_cards;

        if ( get_option( 'hide_pimwick_menu', 'no' ) === 'no' ) {
            if ( empty ( $GLOBALS['admin_page_hooks']['pimwick'] ) ) {
                add_menu_page(
                    __( 'PW Gift Cards', 'pw-woocommerce-gift-cards' ),
                    __( 'Pimwick Plugins', 'pw-woocommerce-gift-cards' ),
                    PWGC_REQUIRES_PRIVILEGE,
                    'pimwick',
                    array( $this, 'index' ),
                    $pw_gift_cards->relative_url( '/admin/assets/images/pimwick-icon-120x120.png' ),
                    6
                );

                add_submenu_page(
                    'pimwick',
                    __( 'PW Gift Cards', 'pw-woocommerce-gift-cards' ),
                    __( 'Pimwick Plugins', 'pw-woocommerce-gift-cards' ),
                    PWGC_REQUIRES_PRIVILEGE,
                    'pimwick',
                    array( $this, 'index' )
                );

                remove_submenu_page( 'pimwick', 'pimwick' );
            }

            add_submenu_page(
                'pimwick',
                __( 'PW Gift Cards', 'pw-woocommerce-gift-cards' ),
                __( 'PW Gift Cards', 'pw-woocommerce-gift-cards' ),
                PWGC_REQUIRES_PRIVILEGE,
                'pw-gift-cards',
                array( $this, 'index' )
            );

            remove_submenu_page( 'pimwick', 'pimwick-plugins' );
            add_submenu_page(
                'pimwick',
                __( 'Pimwick Plugins', 'pw-woocommerce-gift-cards' ),
                __( 'Our Plugins', 'pw-woocommerce-gift-cards' ),
                PWGC_REQUIRES_PRIVILEGE,
                'pimwick-plugins',
                array( $this, 'other_plugins_page' )
            );
        }

        add_submenu_page(
            'woocommerce',
            __( 'PW Gift Cards', 'pw-woocommerce-gift-cards' ),
            __( 'PW Gift Cards', 'pw-woocommerce-gift-cards' ),
            PWGC_REQUIRES_PRIVILEGE,
            'wc-pw-gift-cards',
            array( $this, 'index' )
        );
    }

    function other_plugins_page() {
        global $pimwick_more_handled;

        if ( !$pimwick_more_handled ) {
            $pimwick_more_handled = true;
            require( 'ui/more.php' );
        }
    }

    function index() {
        global $pw_gift_cards;

        if ( isset( $_POST['activate-license'] ) ) {
            $pw_gift_cards->license->activate_license( wc_clean( $_POST['license-key'] ) );
        }

        require( 'ui/index.php' );
    }

    function admin_enqueue_scripts( $hook ) {
        global $wp_scripts;
        global $pw_gift_cards;

        wp_register_style( 'pw-gift-cards-icon', $pw_gift_cards->relative_url( '/admin/assets/css/icon-style.css' ), array( 'admin-menu' ), PWGC_VERSION );
        wp_enqueue_style( 'pw-gift-cards-icon' );

        if ( !empty( $hook ) && substr( $hook, -strlen( 'pw-gift-cards' ) ) === 'pw-gift-cards' ) {
            wp_enqueue_media();

            wp_enqueue_style( 'pw-gift-cards-admin', $pw_gift_cards->relative_url( '/admin/assets/css/pw-gift-cards-admin.css' ), array(), PWGC_VERSION );
            wp_enqueue_style( 'pw-gift-cards-spectrum', $pw_gift_cards->relative_url( '/admin/assets/css/nano.min.css' ), array(), PWGC_VERSION );
            wp_enqueue_script( 'pw-gift-cards-spectrum', $pw_gift_cards->relative_url( '/admin/assets/js/pickr.min.js' ), array( 'jquery' ), PWGC_VERSION );

            wp_enqueue_style( 'jquery-ui-style', $pw_gift_cards->relative_url( '/admin/assets/css/jquery-ui-style.min.css' ), array(), PWGC_VERSION );
            wp_enqueue_script( 'jquery-ui-datepicker' );
            wp_enqueue_script( 'wc-admin-meta-boxes' );
            wp_enqueue_style( 'woocommerce_admin_styles' );

            wp_enqueue_script( 'pw-gift-cards-admin', $pw_gift_cards->relative_url( '/admin/assets/js/pw-gift-cards-admin.js' ), array( 'jquery' ), PWGC_VERSION );
            wp_localize_script( 'pw-gift-cards-admin', 'pwgc', array(
                'admin_email' => get_option( 'admin_email' ),
                'i18n' => array(
                    'adjustment_amount_prompt' => __( 'Adjustment amount? Can be positive or negative.', 'pw-woocommerce-gift-cards' ),
                    'adjustment_note_prompt' => __( 'Note', 'pw-woocommerce-gift-cards' ),
                    'select_image' => __( 'Select Image', 'pw-woocommerce-gift-cards' ),
                    'use_selected_image' => __( 'Use selected image', 'pw-woocommerce-gift-cards' ),
                    'prompt_for_expiration_date' => __( 'Expiration Date (YYYY-MM-DD)', 'pw-woocommerce-gift-cards' ),
                    'prompt_for_email_address' => __( 'Recipient Email Address', 'pw-woocommerce-gift-cards' ),
                    'prompt_for_sender' => __( 'From', 'pw-woocommerce-gift-cards' ),
                    'prompt_for_note' => __( 'Note (optional)', 'pw-woocommerce-gift-cards' ),
                    'email_sent' => __( 'Email has been sent.', 'pw-woocommerce-gift-cards' ),
                    'delete_design_prompt' => __( 'Are you sure you want to delete this design?', 'pw-woocommerce-gift-cards' ),
                    'preview_email_notice' => __( 'Note: Be sure to save changes before sending a preview email.', 'pw-woocommerce-gift-cards' ),
                    'preview_email_prompt' => __( 'Recipient email address?', 'pw-woocommerce-gift-cards' ),
                ),
                'nonces' => array(
                    'balance_summary' => wp_create_nonce( 'pw-gift-cards-balance-summary' ),
                    'search' => wp_create_nonce( 'pw-gift-cards-search' ),
                    'view_activity' => wp_create_nonce( 'pw-gift-cards-view-activity' ),
                    'create_gift_card' => wp_create_nonce( 'pw-gift-cards-create-gift-card' ),
                    'save_settings' => wp_create_nonce( 'pw-gift-cards-save-settings' ),
                    'create_product' => wp_create_nonce( 'pw-gift-cards-create-product' ),
                    'create_balance_page' => wp_create_nonce( 'pw-gift-cards-create-balance-page' ),
                    'adjustment' => wp_create_nonce( 'pw-gift-cards-adjustment' ),
                    'expiration_date' => wp_create_nonce( 'pw-gift-cards-expiration-date' ),
                    'delete' => wp_create_nonce( 'pw-gift-cards-delete' ),
                    'restore' => wp_create_nonce( 'pw-gift-cards-restore' ),
                    'select_design' => wp_create_nonce( 'pw-gift-cards-select-design' ),
                    'create_design' => wp_create_nonce( 'pw-gift-cards-create-design' ),
                    'save_design' => wp_create_nonce( 'pw-gift-cards-save-design' ),
                    'delete_design' => wp_create_nonce( 'pw-gift-cards-delete-design' ),
                    'preview_email' => wp_create_nonce( 'pw-gift-cards-preview-email' ),
                    'get_email_form' => wp_create_nonce( 'pw-gift-cards-get-email-form' ),
                    'send_email' => wp_create_nonce( 'pw-gift-cards-send-email' ),
                )
            ) );

            wp_enqueue_script( 'fontawesome-all', $pw_gift_cards->relative_url( '/assets/js/fontawesome-all.min.js' ), array(), PWGC_FONT_AWESOME_VERSION );

            if ( class_exists( 'Better_Font_Awesome_Library' ) ) {
                $bfa = Better_Font_Awesome_Library::get_instance();
                if ( !empty( $bfa ) ) {
                    remove_action( 'admin_enqueue_scripts', array( $bfa, 'register_font_awesome_css' ), 15 );
                }
            }
        }

        if ( function_exists( 'get_current_screen' ) && $screen = get_current_screen() ) {
            if ( $screen->id == 'product' ) {
                wp_enqueue_style( 'pw-gift-cards-product-data-panels', $pw_gift_cards->relative_url( '/admin/assets/css/product-data-panels.css' ), array(), PWGC_VERSION );

                wp_enqueue_script( 'pw-gift-cards-product-data-panels', $pw_gift_cards->relative_url( '/admin/assets/js/product-data-panels.js' ), array(), PWGC_VERSION );

                wp_localize_script( 'pw-gift-cards-product-data-panels', 'pwgc', array(
                    'product_type_slug' => PWGC_PRODUCT_TYPE_SLUG,
                    'i18n' => array(
                        'wait'                      => __( 'Wait', 'pw-woocommerce-gift-cards' ),
                        'add'                       => __( 'Add', 'pw-woocommerce-gift-cards' ),
                        'remove'                    => __( 'Remove', 'pw-woocommerce-gift-cards' ),
                        'error_greater_than_zero'   => __( 'Amount must be greater than zero.', 'pw-woocommerce-gift-cards' ),
                        'error_greater_than_min'    => __( 'Amount must be greater than minimum amount.', 'pw-woocommerce-gift-cards' ),
                        'error_less_than_max'       => __( 'Amount must be less than maximum amount.', 'pw-woocommerce-gift-cards' ),
                        'error'                     => __( 'Error', 'pw-woocommerce-gift-cards' ),
                        'add_bonus_amount'          => __( 'Add a bonus amount', 'pw-woocommerce-gift-cards' ),
                        'bonus_spend_prompt'        => __( 'Gift card amount that triggers the bonus?', 'pw-woocommerce-gift-cards' ),
                        'bonus_get_prompt'          => __( 'Bonus gift card amount?', 'pw-woocommerce-gift-cards' ),
                    ),
                    'nonces' => array(
                        'add_gift_card_amount'      => wp_create_nonce( 'pw-gift-cards-add-gift-card-amount' ),
                        'remove_gift_card_amount'   => wp_create_nonce( 'pw-gift-cards-remove-gift-card-amount' ),
                        'add_bonus_amount'          => wp_create_nonce( 'pw-gift-cards-add-bonus-amount' ),
                        'remove_bonus_amount'       => wp_create_nonce( 'pw-gift-cards-remove-bonus-amount' ),
                        'view_activity'             => wp_create_nonce( 'pw-gift-cards-view-activity' ),
                    )
                ) );
            }
        }
    }

    function woocommerce_product_data_tabs( $tabs ) {
        global $post;

        $is_physical_card = false;
        if ( is_a( $post, 'WP_Post' ) && !empty( $post->ID ) ) {
            $product = wc_get_product( $post->ID );
            if ( is_a( $product, 'WC_Product_PW_Gift_Card' ) ) {
                $is_physical_card = $product->get_pwgc_is_physical_card( 'edit' );
            }
        }

        if ( !$is_physical_card ) {
            $tabs['shipping']['class'][] = 'hide_if_' . PWGC_PRODUCT_TYPE_SLUG;
        }

        $tabs['inventory']['class'][] = 'show_if_' . PWGC_PRODUCT_TYPE_SLUG;
        $tabs['variations']['class'][] = 'show_if_' . PWGC_PRODUCT_TYPE_SLUG;

        $tabs[ PWGC_PRODUCT_TYPE_SLUG . '_cards' ] = array(
            'label'     => __( 'Gift Card', 'pw-woocommerce-gift-cards' ),
            'target'    => PWGC_PRODUCT_TYPE_SLUG . '_cards',
            'class'     => array( 'show_if_' . PWGC_PRODUCT_TYPE_SLUG ),
            'priority'  => 5
        );

        return $tabs;
    }

    function woocommerce_product_data_panels() {
        require( 'ui/product-data-panel-cards.php' );
    }

    function woocommerce_variation_options( $loop, $variation_data, $variation_post ) {
        $variation = wc_get_product( $variation_post->ID );
        if ( !is_a( $variation, 'WC_Product_Variation' ) ) {
            return;
        }

        $product_ids = $variation->get_meta( '_pwgc_product_ids' );
        $exclude_product_ids = $variation->get_meta( '_pwgc_exclude_product_ids' );
        $product_categories = $variation->get_meta( '_pwgc_product_categories' );
        $exclude_product_categories = $variation->get_meta( '_pwgc_exclude_product_categories' );
        $exclude_tax = $variation->get_meta( '_pwgc_exclude_tax' );
        $exclude_shipping = $variation->get_meta( '_pwgc_exclude_shipping' );

        $redemption_restrictions = ( !empty( $product_ids ) || !empty( $exclude_product_ids ) || !empty( $product_categories ) || !empty( $exclude_product_categories ) || $exclude_tax || $exclude_shipping );

        $redemption_restrictions = apply_filters( 'pwgc_variation_has_redemption_restrictions', $redemption_restrictions, $variation );

        ?>
        <label class="tips show_if_<?php echo PWGC_PRODUCT_TYPE_SLUG; ?>" data-tip="<?php esc_attr_e( 'Specify which products can be purchased using this gift card.', 'pw-woocommerce-gift-cards' ); ?>">
            <?php esc_html_e( 'Redemption restrictions?', 'pw-woocommerce-gift-cards' ); ?>
            <input type="checkbox" class="checkbox variable_pwgc_redemption_restrictions" name="variable_pwgc_redemption_restrictions[<?php echo esc_attr( $loop ); ?>]" <?php checked( $redemption_restrictions, true ); // Use view context so 'parent' is considered. ?> />
        </label>
        <?php
    }

    function woocommerce_variation_options_redemption_restrictions( $loop, $variation_data, $variation_post ) {
        $variation = wc_get_product( $variation_post->ID );
        if ( !is_a( $variation, 'WC_Product_Variation' ) ) {
            return;
        }

        $product_ids = $variation->get_meta( '_pwgc_product_ids' );
        $exclude_product_ids = $variation->get_meta( '_pwgc_exclude_product_ids' );
        $product_categories = $variation->get_meta( '_pwgc_product_categories' );
        $exclude_product_categories = $variation->get_meta( '_pwgc_exclude_product_categories' );
        $exclude_tax = $variation->get_meta( '_pwgc_exclude_tax' );
        $exclude_shipping = $variation->get_meta( '_pwgc_exclude_shipping' );

        $redemption_restrictions = ( !empty( $product_ids ) || !empty( $exclude_product_ids ) || !empty( $product_categories ) || !empty( $exclude_product_categories ) || $exclude_tax || $exclude_shipping );

        $redemption_restrictions = apply_filters( 'pwgc_variation_has_redemption_restrictions', $redemption_restrictions, $variation );

        $product_object = wc_get_product( $variation->get_parent_id() );
        $categories = get_terms( 'product_cat', 'orderby=name&hide_empty=0' );

        ?>
        <div class="pwgc_variation_redemption_restrictions <?php if ( !$redemption_restrictions ) { echo 'pwgc-hidden'; } ?>">
            <p class="form-field form-row form-row-first">
                <label for="variable_pwgc_product_ids"><?php esc_html_e( 'Products', 'woocommerce' ); ?></label>
                <?php echo wc_help_tip( __( 'Products that can be purchased using this gift card. Leave blank to allow all products except excluded products and categories.', 'pw-woocommerce-gift-cards' ) ); // WPCS: XSS ok. ?>
                <select id="variable_pwgc_product_ids" name="variable_pwgc_product_ids[<?php esc_attr_e( $loop ); ?>][]" style="width: 100%;" class="wc-product-search" multiple="multiple" data-placeholder="<?php esc_attr_e( 'Search for a product&hellip;', 'woocommerce' ); ?>" data-action="woocommerce_json_search_products_and_variations" data-exclude="<?php echo intval( $product_object->get_id() ); ?>">
                    <?php
                        if ( is_array( $product_ids ) ) {
                            foreach ( $product_ids as $product_id ) {
                                $product = wc_get_product( $product_id );
                                if ( is_object( $product ) ) {
                                    echo '<option value="' . esc_attr( $product_id ) . '"' . selected( true, true, false ) . '>' . esc_html( wp_strip_all_tags( $product->get_formatted_name() ) ) . '</option>';
                                }
                            }
                        }
                    ?>
                </select>
            </p>
            <p class="form-field form-row form-row-last">
                <label for="variable_pwgc_exclude_product_ids"><?php esc_html_e( 'Exclude products', 'woocommerce' ); ?></label>
                <?php echo wc_help_tip( __( 'Products that cannot be purchased using this gift card.', 'pw-woocommerce-gift-cards' ) ); // WPCS: XSS ok. ?>
                <select id="variable_pwgc_exclude_product_ids" name="variable_pwgc_exclude_product_ids[<?php esc_attr_e( $loop ); ?>][]" style="width: 100%;" class="wc-product-search" multiple="multiple" data-placeholder="<?php esc_attr_e( 'Search for a product&hellip;', 'woocommerce' ); ?>" data-action="woocommerce_json_search_products_and_variations" data-exclude="<?php echo intval( $product_object->get_id() ); ?>">
                    <?php
                        if ( is_array( $exclude_product_ids ) ) {
                            foreach ( $exclude_product_ids as $product_id ) {
                                $product = wc_get_product( $product_id );
                                if ( is_object( $product ) ) {
                                    echo '<option value="' . esc_attr( $product_id ) . '"' . selected( true, true, false ) . '>' . esc_html( wp_strip_all_tags( $product->get_formatted_name() ) ) . '</option>';
                                }
                            }
                        }
                    ?>
                </select>
            </p>
            <p class="form-field form-row form-row-first">
                <label for="variable_pwgc_product_categories"><?php _e( 'Product categories', 'woocommerce' ); ?></label>
                <?php echo wc_help_tip( __( 'Product categories that can be purchased using this gift card. Leave blank to allow all categories except excluded products and categories.', 'pw-woocommerce-gift-cards' ) ); ?>
                <select id="variable_pwgc_product_categories" name="variable_pwgc_product_categories[<?php esc_attr_e( $loop ); ?>][]" style="width: 100%;" class="wc-enhanced-select" multiple="multiple" data-placeholder="<?php esc_attr_e( 'Any category', 'woocommerce' ); ?>">
                    <?php
                        if ( is_array( $categories ) ) {
                            foreach ( $categories as $cat ) {
                                echo '<option value="' . esc_attr( $cat->term_id ) . '"' . wc_selected( $cat->term_id, $product_categories ) . '>' . esc_html( $cat->name ) . '</option>';
                            }
                        }
                    ?>
                </select>
            </p>
            <p class="form-field form-row form-row-last">
                <label for="variable_pwgc_exclude_product_categories"><?php _e( 'Exclude categories', 'woocommerce' ); ?></label>
                <?php echo wc_help_tip( __( 'Product categories that cannot be purchased using this gift card.', 'pw-woocommerce-gift-cards' ) ); ?>
                <select id="variable_pwgc_exclude_product_categories" name="variable_pwgc_exclude_product_categories[<?php esc_attr_e( $loop ); ?>][]" style="width: 100%;" class="wc-enhanced-select" multiple="multiple" data-placeholder="<?php esc_attr_e( 'No categories', 'woocommerce' ); ?>">
                    <?php
                        if ( is_array( $categories ) ) {
                            foreach ( $categories as $cat ) {
                                echo '<option value="' . esc_attr( $cat->term_id ) . '"' . wc_selected( $cat->term_id, $exclude_product_categories ) . '>' . esc_html( $cat->name ) . '</option>';
                            }
                        }
                    ?>
                </select>
            </p>
            <?php

                do_action( 'pwgc_data_panel_variation_redemption_restrictions', $variation, $loop );

                woocommerce_wp_checkbox( array(
                    'id'                => 'variable_pwgc_exclude_tax[' . $loop . ']',
                    'value'             => $exclude_tax ? 'yes' : 'no',
                    'cbvalue'           => 'yes',
                    'label'             => '&nbsp;' . __( 'Exclude tax', 'pw-woocommerce-gift-cards' ),
                    'desc_tip'          => 'true',
                    'description'       => __( 'Check this box and tax will not be paid by this gift card when redeemed.', 'pw-woocommerce-gift-cards' ) . ' ' . __( 'Default: Unchecked', 'pw-woocommerce-gift-cards' ),
                ) );

                woocommerce_wp_checkbox( array(
                    'id'                => 'variable_pwgc_exclude_shipping[' . $loop . ']',
                    'value'             => $exclude_shipping ? 'yes' : 'no',
                    'cbvalue'           => 'yes',
                    'label'             => '&nbsp;' . __( 'Exclude Shipping', 'pw-woocommerce-gift-cards' ),
                    'desc_tip'          => 'true',
                    'description'       => __( 'Check this box and shipping will not be paid by this gift card when redeemed.', 'pw-woocommerce-gift-cards' ) . ' ' . __( 'Default: Unchecked', 'pw-woocommerce-gift-cards' ),
                ) );
            ?>
        </div>
        <?php
    }

    function admin_footer() {
        if ( 'product' != get_post_type() ) {
            return;
        }

        ?>
        <script type='text/javascript'>
            jQuery('.inventory_options').addClass('show_if_<?php echo PWGC_PRODUCT_TYPE_SLUG; ?>');
            jQuery('#inventory_product_data ._sold_individually_field').parent().addClass('show_if_<?php echo PWGC_PRODUCT_TYPE_SLUG; ?>');
            jQuery('#inventory_product_data ._sold_individually_field').addClass('show_if_<?php echo PWGC_PRODUCT_TYPE_SLUG; ?>');
            jQuery('#general_product_data ._tax_status_field').closest('.options_group').addClass('show_if_<?php echo PWGC_PRODUCT_TYPE_SLUG; ?>');
        </script>
        <?php
    }

    function woocommerce_after_product_attribute_settings( $attribute, $i ) {
        ?>
        <script type='text/javascript'>
            jQuery( function() {
                jQuery('.enable_variation').addClass('show_if_<?php echo PWGC_PRODUCT_TYPE_SLUG; ?>');
                var product_type = jQuery( 'select#product-type' ).val();
                if (product_type == '<?php echo PWGC_PRODUCT_TYPE_SLUG; ?>') {
                    jQuery('.enable_variation').show();
                }
            });
        </script>
        <?php
    }

    function woocommerce_product_filters( $output ) {
        return str_replace( 'Pw-gift-card</option>', PWGC_PRODUCT_TYPE_NAME . '</option>', $output );
    }

    function process_pw_gift_card_product_meta_data( $post_id ) {
        global $pw_gift_cards;

        $product = new WC_Product_PW_Gift_Card( $post_id );

        $new_amount = wc_clean( $_POST['pwgc_new_amount'] );
        if ( !empty( $new_amount ) ) {
            $result = $product->add_amount( $new_amount );
            if ( !is_numeric( $result ) ) {
                wp_die( $result );
            }
        }

        $errors = $product->set_props( array(
            'pwgc_hide_variations_select'       => isset( $_POST['_pwgc_hide_variations_select'] ) ? 1 : 0,
            'pwgc_show_recipient_name'          => isset( $_POST['_pwgc_show_recipient_name'] ) ? 1 : 0,
            'pwgc_show_email_preview'           => isset( $_POST['_pwgc_show_email_preview'] ) ? 1 : 0,
            'pwgc_custom_amount_allowed'        => isset( $_POST['_pwgc_custom_amount_allowed'] ) ? 1 : 0,
            'pwgc_custom_amount_min'            => $pw_gift_cards->numeric_price( wc_clean( $_POST['_pwgc_custom_amount_min'] ) ),
            'pwgc_custom_amount_max'            => $pw_gift_cards->numeric_price( wc_clean( $_POST['_pwgc_custom_amount_max'] ) ),
            'pwgc_is_physical_card'             => isset( $_POST['_pwgc_is_physical_card'] ) ? 1 : 0,
            'pwgc_no_coupons_allowed'           => isset( $_POST['_pwgc_no_coupons_allowed'] ) ? 1 : 0,
            'pwgc_physical_email'               => wc_clean( $_POST['_pwgc_physical_email'] ),
            'pwgc_expire_days'                  => absint( $_POST['_pwgc_expire_days'] ),
            'pwgc_product_ids'                  => isset( $_POST['_pwgc_redemption_restrictions'] ) && isset( $_POST['_pwgc_product_ids'] ) ? array_map( 'intval', (array) wp_unslash( $_POST['_pwgc_product_ids'] ) ) : array(),
            'pwgc_exclude_product_ids'          => isset( $_POST['_pwgc_redemption_restrictions'] ) && isset( $_POST['_pwgc_exclude_product_ids'] ) ? array_map( 'intval', (array) wp_unslash( $_POST['_pwgc_exclude_product_ids'] ) ) : array(),
            'pwgc_product_categories'           => isset( $_POST['_pwgc_redemption_restrictions'] ) && isset( $_POST['_pwgc_product_categories'] ) ? array_map( 'intval', (array) wp_unslash( $_POST['_pwgc_product_categories'] ) ) : array(),
            'pwgc_exclude_product_categories'   => isset( $_POST['_pwgc_redemption_restrictions'] ) && isset( $_POST['_pwgc_exclude_product_categories'] ) ? array_map( 'intval', (array) wp_unslash( $_POST['_pwgc_exclude_product_categories'] ) ) : array(),
            'pwgc_exclude_tax'                  => isset( $_POST['_pwgc_redemption_restrictions'] ) && isset( $_POST['_pwgc_exclude_tax'] ) ? 1 : 0,
            'pwgc_exclude_shipping'             => isset( $_POST['_pwgc_redemption_restrictions'] ) && isset( $_POST['_pwgc_exclude_shipping'] ) ? 1 : 0,
            'pwgc_email_design_ids'             => wc_clean( $_POST['_pwgc_email_design_ids'] ),
            'pwgc_enable_bonus'                 => isset( $_POST['_pwgc_enable_bonus'] ) ? 1 : 0,
            'pwgc_cumulative_bonus'             => isset( $_POST['_pwgc_cumulative_bonus'] ) ? 1 : 0,
            'pwgc_bonus_recipient'              => wc_clean( $_POST['_pwgc_bonus_recipient'] ),
        ) );

        if ( is_wp_error( $errors ) ) {
            WC_Admin_Meta_Boxes::add_error( $errors->get_error_message() );
        }

        $product->set_default_attributes( array( PWGC_DENOMINATION_ATTRIBUTE_SLUG => wc_clean( $_POST['_pwgc_default_amount'] ) ) );

        do_action( 'pwgc_process_pw_gift_card_product_meta_data', $product );

        $product->save();
    }

    function woocommerce_admin_process_variation_object( $variation, $i ) {
        $product_ids                    = isset( $_POST['variable_pwgc_redemption_restrictions'][ $i ] ) && isset( $_POST['variable_pwgc_product_ids'][ $i ] ) ? array_map( 'intval', (array) wp_unslash( $_POST['variable_pwgc_product_ids'][ $i ] ) ) : null;
        $exclude_product_ids            = isset( $_POST['variable_pwgc_redemption_restrictions'][ $i ] ) && isset( $_POST['variable_pwgc_exclude_product_ids'][ $i ] ) ? array_map( 'intval', (array) wp_unslash( $_POST['variable_pwgc_exclude_product_ids'][ $i ] ) ) : null;
        $product_categories             = isset( $_POST['variable_pwgc_redemption_restrictions'][ $i ] ) && isset( $_POST['variable_pwgc_product_categories'][ $i ] ) ? array_map( 'intval', (array) wp_unslash( $_POST['variable_pwgc_product_categories'][ $i ] ) ) : null;
        $exclude_product_categories     = isset( $_POST['variable_pwgc_redemption_restrictions'][ $i ] ) && isset( $_POST['variable_pwgc_exclude_product_categories'][ $i ] ) ? array_map( 'intval', (array) wp_unslash( $_POST['variable_pwgc_exclude_product_categories'][ $i ] ) ) : null;
        $exclude_tax                    = isset( $_POST['variable_pwgc_redemption_restrictions'][ $i ] ) && isset( $_POST['variable_pwgc_exclude_tax'][ $i ] ) ? 1 : 0;
        $exclude_shipping               = isset( $_POST['variable_pwgc_redemption_restrictions'][ $i ] ) && isset( $_POST['variable_pwgc_exclude_shipping'][ $i ] ) ? 1 : 0;

        $variation->update_meta_data( '_pwgc_product_ids', $product_ids );
        $variation->update_meta_data( '_pwgc_exclude_product_ids', $exclude_product_ids );
        $variation->update_meta_data( '_pwgc_product_categories', $product_categories );
        $variation->update_meta_data( '_pwgc_exclude_product_categories', $exclude_product_categories );
        $variation->update_meta_data( '_pwgc_exclude_tax', $exclude_tax );
        $variation->update_meta_data( '_pwgc_exclude_shipping', $exclude_shipping );

        do_action( 'pwgc_process_pw_gift_card_variation_meta_data', $variation, $i );
    }

    function woocommerce_admin_order_totals_after_tax( $order_id ) {
        $order = wc_get_order( $order_id );
        require( 'ui/order-gift-card-total.php' );
    }

    function woocommerce_get_sections_products( $sections ) {
        $sections['pw_gift_cards'] = __( 'PW Gift Cards', 'pw-woocommerce-gift-cards' );

        return $sections;
    }

    function woocommerce_get_settings_products( $settings, $current_section ) {
        if ( 'pw_gift_cards' === $current_section ) {
            $settings = $this->settings;
        }

        return $settings;
    }

    function pwbe_variable_product_types( $types, $sql_builder ) {
        if ( ! in_array( PWGC_PRODUCT_TYPE_SLUG, $types ) ) {
            $types[] = PWGC_PRODUCT_TYPE_SLUG;
        }

        return $types;
    }

    function ajax_activation() {
        global $pw_gift_cards;

        $license_key = sanitize_title( $_POST['license-key'] );
        $pw_gift_cards->license->activate_license( $license_key );

        // FAILING?
        $registration['active'] = $pw_gift_cards->license->is_premium();
        $registration['error'] = $pw_gift_cards->license->error;

        wp_send_json( $registration );
    }

    function ajax_check_license() {
        global $pw_gift_cards;

        $registration['active'] = $pw_gift_cards->license->is_premium();
        $registration['error'] = $pw_gift_cards->license->error;

        wp_send_json( $registration );
    }

    function ajax_hide_renew_notice() {
        update_option( 'pw-gift-cards-hide-renew-notice', true );
        wp_send_json_success();
    }

    function ajax_add_gift_card_amount() {
        global $pw_gift_cards;

        check_ajax_referer( 'pw-gift-cards-add-gift-card-amount', 'security' );

        $pw_gift_cards->set_current_currency_to_default();

        if ( ! current_user_can( 'edit_products' ) ) {
            wp_die( -1 );
        }

        $product_id = absint( $_POST['product_id'] );
        $new_amount = wc_clean( $_POST['amount'] );
        $new_amount = $pw_gift_cards->sanitize_amount( $new_amount );

        if ( $product = new WC_Product_PW_Gift_Card( $product_id ) ) {
            $result = $product->add_amount( $new_amount );

            if ( is_numeric( $result ) ) {
                wp_send_json_success( array( 'amount' => $pw_gift_cards->pretty_price( $new_amount ), 'variation_id' => $result ) );
            } else {
                wp_send_json_error( array( 'message' => $result ) );
            }
        } else {
            // translators: %s is the product id.
            wp_send_json_error( array( 'message' => sprintf( __( 'Could not locate product id %s', 'pw-woocommerce-gift-cards' ), $product_id ) ) );
        }
    }

    function ajax_remove_gift_card_amount() {
        check_ajax_referer( 'pw-gift-cards-remove-gift-card-amount', 'security' );

        if ( ! current_user_can( 'edit_products' ) ) {
            wp_die( -1 );
        }

        $product_id = absint( $_POST['product_id'] );
        $variation_id = absint( $_POST['variation_id'] );

        if ( $product = new WC_Product_PW_Gift_Card( $product_id ) ) {

            $result = $product->delete_amount( $variation_id );
            if ( $result === true ) {
                wp_send_json_success();
            } else {
                wp_send_json_error( array( 'message' => $result ) );
            }

        } else {
            wp_send_json_error( array( 'message' => __( 'Could not locate product using product_id ', 'pw-woocommerce-gift-cards' ) . $product_id ) );
        }
    }

    function ajax_add_bonus_amount() {
        global $pw_gift_cards;

        check_ajax_referer( 'pw-gift-cards-add-bonus-amount', 'security' );

        $pw_gift_cards->set_current_currency_to_default();

        if ( ! current_user_can( 'edit_products' ) ) {
            wp_die( -1 );
        }

        $product_id = absint( $_POST['product_id'] );
        $spend = $pw_gift_cards->numeric_price( wc_clean( $_POST['spend'] ) );
        $get = $pw_gift_cards->numeric_price( wc_clean( $_POST['get'] ) );

        if ( $spend <= 0 || $get <= 0 ) {
            wp_send_json_error( array( 'message' => __( 'Gift Card Amount and Bonus amount are both required.', 'pw-woocommerce-gift-cards' ) ) );
        }

        if ( $product = new WC_Product_PW_Gift_Card( $product_id ) ) {
            $bonus_structure = $product->get_pwgc_bonus_structure();

            if ( empty( $bonus_structure ) ) { $bonus_structure = array(); }

            $bonus_structure[ $spend ] = $get;

            $product->set_pwgc_bonus_structure( $bonus_structure );
            $product->save();

            // translators: %1$s is the Spend amount, %2$s is the bonus card amount.
            wp_send_json_success( array( 'message' => sprintf( __( 'Buy a %1$s gift card, get a %2$s bonus card', 'pw-woocommerce-gift-cards' ), $pw_gift_cards->pretty_price( $spend ), $pw_gift_cards->pretty_price( $get ) ) ) );
        } else {
            wp_send_json_error( array( 'message' => sprintf( __( 'Could not locate product id %s', 'pw-woocommerce-gift-cards' ), $product_id ) ) );
        }
    }

    function ajax_remove_bonus_amount() {
        check_ajax_referer( 'pw-gift-cards-remove-bonus-amount', 'security' );

        if ( ! current_user_can( 'edit_products' ) ) {
            wp_die( -1 );
        }

        $product_id = absint( $_POST['product_id'] );
        $key = absint( $_POST['key'] );

        if ( $product = new WC_Product_PW_Gift_Card( $product_id ) ) {
            $bonus_structure = $product->get_pwgc_bonus_structure();
            $new_bonus_structure = array();

            if ( !empty( $bonus_structure ) ) {
                foreach ( $bonus_structure as $spend => $get ) {
                    if ( $key != $spend ) {
                        $new_bonus_structure[ $spend ] = $get;
                    }
                }
            }

            $product->set_pwgc_bonus_structure( $new_bonus_structure );
            $product->save();

            wp_send_json_success();

        } else {
            wp_send_json_error( array( 'message' => __( 'Could not locate product using product_id ', 'pw-woocommerce-gift-cards' ) . $product_id ) );
        }
    }

    function ajax_hide_partner_message() {
        update_option( 'pwgc_hide_partner_message', true );
        wp_send_json_success();
    }

    function ajax_search() {
        global $pw_gift_cards;

        check_ajax_referer( 'pw-gift-cards-search', 'security' );

        $search_terms = isset( $_POST['search_terms'] ) ? $_POST['search_terms'] : '';

        $gift_cards = $this->search_gift_cards( $search_terms, 0 );

        $pw_gift_cards->set_current_currency_to_default();

        ob_start();
        require( 'ui/sections/search-results.php' );
        $html = ob_get_clean();

        wp_send_json( array( 'html' => $html ) );
    }

    function ajax_search_load_more() {
        global $pw_gift_cards;

        $gift_cards = $this->search_gift_cards( $_POST['search_terms'], $_POST['offset'] );

        $pw_gift_cards->set_current_currency_to_default();

        ob_start();
        require( 'ui/sections/search-results-rows.php' );
        $html = ob_get_clean();

        wp_send_json( array( 'html' => $html ) );
    }

    function search_gift_cards( $search_terms, $offset ) {
        global $wpdb;

        $gift_cards = array();
        $where_sql = '';

        if ( !empty( $search_terms ) ) {
            $search_terms = '%' . wc_clean( $search_terms ) . '%';
            $where_sql .= $wpdb->prepare( 'AND (gift_card.number LIKE %s OR gift_card.recipient_email LIKE %s)', $search_terms, $search_terms );
        } else {
            $where_sql .= 'AND gift_card.active = true';
        }


        $date_sql_activity = '';
        if ( isset( $_REQUEST['date'] ) && !empty( $_REQUEST['date'] ) ) {
            $date_sql_activity = $wpdb->prepare( "AND a.activity_date <= %s", $_REQUEST['date'] . ' 23:59:59' );
            $where_sql .= $wpdb->prepare( "AND gift_card.create_date <= %s", $_REQUEST['date'] . ' 23:59:59' );
        }

        if ( isset( $_REQUEST['variation_ids'] ) && !empty( $_REQUEST['variation_ids'] ) ) {
            $variation_ids = array();
            if ( is_array( $_REQUEST['variation_ids'] ) ) {
                $variation_ids = $_REQUEST['variation_ids'];
                array_walk( $variation_ids, 'absint' );
            } else if ( !empty( absint( $_REQUEST['variation_ids'] ) ) ) {
                $variation_ids = array( absint( $_REQUEST['variation_ids'] ) );
            }

            $variation_ids = array_filter( $variation_ids );
            if ( !empty( $variation_ids ) ) {
                $sql = ' AND gift_card.variation_id IN (' . implode( ', ', array_fill( 0, count( $variation_ids ), '%s' ) ) . ')';
                $where_sql .= call_user_func_array( array( $wpdb, 'prepare' ), array_merge( array( $sql ), $variation_ids ) );
            }
        }

        $sql = "
            SELECT
                gift_card.*,
                (SELECT SUM(amount) FROM {$wpdb->pimwick_gift_card_activity} AS a WHERE a.pimwick_gift_card_id = gift_card.pimwick_gift_card_id $date_sql_activity) AS balance
            FROM
                `{$wpdb->pimwick_gift_card}` AS gift_card
            WHERE
                1 = 1
                $where_sql
            ORDER BY
                gift_card.create_date DESC,
                gift_card.pimwick_gift_card_id DESC
            LIMIT
                " . absint( $offset ) . ", " . absint( PWGC_ADMIN_MAX_ROWS ) . "
        ";

        $results = $wpdb->get_results( $sql );
        if ( $results !== null ) {
            foreach ( $results as $row ) {
                $gift_cards[] = new PW_Gift_Card( $row );
            }
        }

        return $gift_cards;
    }

    function ajax_balance_summary() {
        global $pw_gift_cards;

        check_ajax_referer( 'pw-gift-cards-balance-summary', 'security' );

        $pw_gift_cards->set_current_currency_to_default();

        require_once( 'ui/sections/balance-summary.php' );

        wp_die();
    }

    function ajax_view_activity() {
        global $pw_gift_cards;

        check_ajax_referer( 'pw-gift-cards-view-activity', 'security' );

        $pw_gift_cards->set_current_currency_to_default();

        $card_number = wc_clean( $_POST['card_number'] );

        $gift_card = new PW_Gift_Card( $card_number );
        if ( $gift_card->get_id() ) {
            ob_start();
            require( 'ui/sections/activity-records.php' );
            $html = ob_get_clean();

            $balance = wc_price( $gift_card->get_balance() );

            wp_send_json( array( 'balance' => $balance, 'html' => $html ) );
        }

        wp_send_json( array( 'balance' => '', 'html' => '<div class="pwgc-balance-error">' . $gift_card->get_error_message() . '</div>' ) );
    }

    function ajax_create_gift_card() {
        global $pw_gift_cards;

        check_ajax_referer( 'pw-gift-cards-create-gift-card', 'security' );

        $variation_id = isset( $_POST['variation_id'] ) ? absint( $_POST['variation_id'] ) : false;
        $amount = wc_clean( $_POST['amount'] );
        $expiration_date = wc_clean( $_POST['expiration_date'] );
        $recipient_email = stripslashes( wc_clean( $_POST['recipient_email'] ) );
        $recipient_name = stripslashes( wc_clean( $_POST['recipient_name'] ) );
        $from = stripslashes( wc_clean( $_POST['from'] ) );
        $message = stripslashes( wc_clean( $_POST['message'] ) );
        $email_design_id = absint( $_POST['design_id'] );
        $quantity = absint( $_POST['quantity'] );
        $number = stripslashes( wc_clean( $_POST['number'] ) );
        $note = stripslashes( wc_clean( $_POST['note'] ) );
        $send_email = boolval( wc_clean( $_POST['send_email'] ) );

        if ( empty( $quantity ) ) {
            $quantity = 1;
        }

        if ( !empty( $expiration_date ) ) {
            $date_array = date_parse( $expiration_date );
            if ( $date_array !== false ) {
                $expiration_date = date('Y-m-d H:i:s', mktime( $date_array['hour'], $date_array['minute'], $date_array['second'], $date_array['month'], $date_array['day'], $date_array['year'] ));
            }
        }

        if ( !empty( $variation_id ) ) {
            $variation = wc_get_product( $variation_id );
            $product_id = $variation->get_parent_id(); // Overwrite the posted value to ensure it syncs with the variation_id.
        } else {
            $product = pwgc_get_gift_card_product();
            $product_id = ( !empty( $product ) ) ? $product->get_id() : false;
        }

        // Remember the checkbox for the "Send gift card email to Recipient Email if provided" option.
        if ( $send_email ) {
            update_option( 'pwgc_create_send_email', 'yes' );
        } else {
            delete_option( 'pwgc_create_send_email' );
        }

        $gift_cards = array();
        $errors = '';

        //
        // If a comma-separated list of recipients is provided, extract them into
        // an array.
        //
        // Recipients == Quantity:
        //      When the gift cards are created, each recipient will receive their
        //      own unique gift card.
        //
        // Recipients != Quantity:
        //      All recipients will be emailed all gift card created.
        //
        $recipients = array();
        if ( !empty( $recipient_email ) && strpos( $recipient_email, ',' ) ) {
            $recipients = array_map('trim', explode( ',', $recipient_email ) );
            if ( count( $recipients ) != $quantity ) {
                $recipients = array();
            }
        }

        for ( $x = 0; $x < $quantity; $x++ ) {
            $gift_card = PW_Gift_Card::create_card( $note, $number );

            if ( is_a( $gift_card, 'PW_Gift_Card' ) ) {

                if ( !empty( $amount ) && $amount > 0 ) {
                    $gift_card->credit( $amount );
                    $gift_card->get_balance( true );
                }

                if ( !empty( $expiration_date ) ) {
                    $gift_card->set_expiration_date( $expiration_date );
                }

                $gift_cards[] = $gift_card;

                // Get the next recipient in the list.
                if ( !empty( $recipients ) ) {
                    $recipient_email = array_shift( $recipients );
                }

                $gift_card->set_recipient_email( $recipient_email );
                $gift_card->set_recipient_name( $recipient_name );
                $gift_card->set_from( $from );
                $gift_card->set_message( $message );
                $gift_card->set_email_design_id( $email_design_id );

                if ( !empty( $product_id ) ) {
                    $gift_card->set_product_id( $product_id );
                }

                if ( !empty( $variation_id ) ) {
                    $gift_card->set_variation_id( $variation_id );
                }

                if ( $send_email ) {
                    $GLOBALS['pw_gift_card_design_id'] = $email_design_id;

                    $pw_gift_cards->set_current_currency_to_default();

                    do_action( 'pw_gift_cards_send_email_manually', $gift_card->get_number(), $recipient_email, $from, $recipient_name, $message, $amount, '' );
                }
            } else {
                $errors .= $gift_card . '<br>';
            }
        }

        ob_start();

        ?>
        <h3>
            <?php
                /* translators: %s is the number of gift cards created. */
                printf( __( '%s created.', 'pw-woocommerce-gift-cards' ), number_format( count( $gift_cards ) ) );
            ?>
        </h3>
        <?php

        ?>
        <span style="color: red;"><?php echo $errors; ?></span>
        <?php

        $pw_gift_cards->set_current_currency_to_default();

        if ( count( $gift_cards ) > 0 ) {
            require( 'ui/sections/search-results.php' );
        }

        $html = ob_get_clean();

        wp_send_json( array( 'html' => $html ) );
    }

    function ajax_import_gift_cards() {
        global $pw_gift_cards;

        if ( isset( $_FILES['file'] ) ) {
            $upload = $_FILES['file'];

            if ( $upload['error'] > 0 ) {
                wp_die( __( 'Error', 'pw-woocommerce-gift-cards' ) . ': ' . $_FILES['file']['error'] );
            }

            ini_set( 'auto_detect_line_endings', true );
            $csv_data = array_map( 'str_getcsv', file( $upload['tmp_name'] ) );
            $success_count = 0;
            $failure_count = 0;
            $create_note = __( 'Imported', 'pw-woocommerce-gift-cards' );

            $product = pwgc_get_gift_card_product();
            $product_id = ( !empty( $product ) ) ? $product->get_id() : false;

            $designs = $GLOBALS['pw_gift_cards_email_designer']->get_designs();
            $email_design_id = array_key_first( $designs );

            $import_results = array();

            foreach ( $csv_data as $index => $columns ) {
                $result = true;
                $number = '';
                $balance = 0;
                $recipient = '';
                $expiration_date = '';
                $expiration_date_html = '';

                if ( count( $columns ) > 4 ) {
                    $result = __( 'Too many columns.', 'pw-woocommerce-gift-cards' );
                } else if ( count( $columns ) == 1 && empty( $columns[0] ) ) {
                    // Ignore blank lines.
                    continue;
                } else {
                    // Ignore the header row
                    if ( count( $columns ) == 4 && $columns[0] == 'number' && $columns[1] == 'balance' && $columns[2] == 'expiration_date' && $columns[3] == 'recipient_email' ) {
                        continue;
                    }

                    if ( count( $columns ) > 0 ) {
                        $number = trim( $columns[0] );

                        if ( empty( $number ) ) {
                            $number = PW_Gift_Card::random_card_number();
                        }
                    }

                    if ( count( $columns ) > 1 && $result === true ) {
                        if ( is_numeric( $columns[1] ) ) {
                            $balance = $columns[1];
                        } else {
                            $result = __( 'Invalid balance amount', 'pw-woocommerce-gift-cards' ) . ': ' . substr( $columns[1], 0, 20 );
                        }
                    }

                    if ( count( $columns ) > 2 && $result === true ) {
                        if ( !empty( $columns[2] ) ) {
                            $date_array = date_parse( $columns[2] );
                            if ( $date_array !== false ) {
                                $expiration_date = date('Y-m-d H:i:s', mktime( $date_array['hour'], $date_array['minute'], $date_array['second'], $date_array['month'], $date_array['day'], $date_array['year'] ));
                                $expiration_date_html = date_i18n( wc_date_format(), strtotime( $expiration_date ) );
                            } else {
                                $result = __( 'Invalid expiration date', 'pw-woocommerce-gift-cards' ) . ': ' . substr( $columns[2], 0, 20 );
                            }
                        }
                    }

                    if ( count( $columns ) > 3 && $result === true ) {
                        if ( !empty( $columns[3] ) ) {
                            $recipient = $columns[3];
                        }
                    }

                    if ( !empty( $number ) ) {
                        $gift_card = new PW_Gift_Card( $number );
                        if ( $gift_card->get_id() && !isset( $_POST['overwrite'] ) ) {
                            $result = __( 'Gift card number already exists.', 'pw-woocommerce-gift-cards' );
                        }
                    }

                    if ( isset( $_POST['confirm'] ) && $result === true ) {

                        if ( isset( $_POST['overwrite'] ) && is_a( $gift_card, 'PW_Gift_Card' ) && $gift_card->get_id() ) {
                            if ( $balance >= 0 ) {
                                $adjustment_amount = $balance - $gift_card->get_balance();
                                if ( $adjustment_amount != 0 ) {
                                    $gift_card->adjust_balance( $adjustment_amount, $create_note );
                                }
                            }

                        } else {
                            $gift_card = PW_Gift_Card::add_card( $number, $create_note );
                            if ( $balance > 0 ) {
                                $gift_card->credit( $balance, $create_note );
                            }
                        }

                        if ( is_a( $gift_card, 'PW_Gift_Card' ) ) {
                            if ( !empty( $expiration_date ) ) {
                                $gift_card->set_expiration_date( $expiration_date );
                            }

                            if ( !empty( $recipient ) ) {
                                $gift_card->set_recipient_email( $recipient );

                                if ( isset( $_POST['send_email'] ) ) {
                                    $from = stripslashes( wc_clean( $_POST['from'] ) );
                                    $GLOBALS['pw_gift_card_design_id'] = absint( $_POST['design_id'] );

                                    do_action( 'pw_gift_cards_send_email_manually', $gift_card->get_number(), $recipient, $from, '', '', $balance, '' );
                                }
                            }

                            if ( !empty( $product_id ) ) {
                                $gift_card->set_product_id( $product_id );
                            }

                            if ( !empty( $email_design_id ) ) {
                                $gift_card->set_email_design_id( $email_design_id );
                            }

                        } else {
                            $result = $gift_card;
                        }
                    }
                }

                $import_results[] = array(
                    'number' => $number,
                    'balance' => $balance,
                    'expiration_date' => !empty( $expiration_date_html ) ? $expiration_date_html : __( 'None', 'pw-woocommerce-gift-cards' ),
                    'recipient' => $recipient,
                    'result' => $result,
                );

                if ( $result === true ) {
                    $success_count++;
                } else {
                    $failure_count++;
                }
            }

            $pw_gift_cards->set_current_currency_to_default();

            ob_start();
            require( 'ui/sections/import-results.php' );
            $html = ob_get_clean();

            wp_send_json_success( array( 'html' => $html ) );
        }

        wp_send_json_error( array( 'message' => __( 'Malformed request.', 'pw-woocommerce-gift-cards' ) ) );
    }

    function export_gift_card() {
        global $wpdb;

        check_ajax_referer( 'pw-gift-cards-export', 'security' );

        if ( ! current_user_can( 'edit_products' ) ) {
            wp_die( -1 );
        }

        $date_range = wc_clean( $_REQUEST['date_range'] );
        $begin_date = !empty( $_REQUEST['begin_date'] ) ? date( 'Y-m-d', strtotime( $_REQUEST['begin_date'] . ' 00:00:00' ) ) : '1900-01-01';
        $end_date = !empty( $_REQUEST['end_date'] ) ? date( 'Y-m-d', strtotime( $_REQUEST['end_date'] . ' 23:59:59' ) ) : '2900-01-01';

        $date_sql_where = '';
        switch ( $date_range ) {
            case 'create_date':
                $date_sql_where = $wpdb->prepare( '
                    AND gift_card.create_date BETWEEN %s AND %s
                ', $begin_date, $end_date );
            break;

            case 'expiration_date':
                $date_sql_where = $wpdb->prepare( '
                    AND gift_card.expiration_date BETWEEN %s AND %s
                ', $begin_date, $end_date );
            break;
        }

        $sql = "
            SELECT
                gift_card.number,
                (SELECT SUM(amount) FROM {$wpdb->pimwick_gift_card_activity} AS a WHERE a.pimwick_gift_card_id = gift_card.pimwick_gift_card_id) AS balance,
                gift_card.expiration_date,
                gift_card.recipient_email
            FROM
                `{$wpdb->pimwick_gift_card}` AS gift_card
            WHERE
                active = 1
                $date_sql_where
            ORDER BY
                gift_card.create_date DESC,
                gift_card.pimwick_gift_card_id DESC
        ";

        $sql = apply_filters( 'pwgc_export_sql', $sql );

        $results = apply_filters( 'pwgc_export_results', $wpdb->get_results( $sql, ARRAY_A ) );
        $rows = array();

        if ( !empty( $results ) ) {
            // Header row.
            $rows = array( array_keys( $results[0] ) );

            foreach ( $results as $row ) {
                $rows[] = array_map( 'trim', $row );
            }
        }

        $rows = apply_filters( 'pwgc_export_rows', $rows );

        header( "Content-Type: text/csv" );
        header( "Content-Disposition: attachment; filename=pw-gift-cards-export.csv" );

        header( "Cache-Control: no-cache, no-store, must-revalidate" );
        header( "Pragma: no-cache" );
        header( "Expires: 0" );

        $out = fopen('php://output', 'w');
        foreach ( $rows as $row ) {
            fputcsv( $out, $row );
        }
        fclose( $out );

        die();
    }

    function ajax_save_settings() {
        check_ajax_referer( 'pw-gift-cards-save-settings', 'security' );

        $form = array();
        parse_str( $_REQUEST['form'], $form );

        $redirect = ( get_option( 'hide_pimwick_menu', 'no' ) != ( isset( $form['hide_pimwick_menu'] ) ? 'yes' : 'no' ) );

        WC_Admin_Settings::save_fields( $this->settings, $form );

        $html = '<span style="color: blue;">' . __( 'Settings saved.', 'pw-woocommerce-gift-cards' ) . '</span>';

        if ( $redirect ) {
            $redirect = pwgc_admin_url( 'settings' );
        }

        wp_send_json_success( array( 'html' => $html, 'redirectUrl' => $redirect ) );
    }

    function ajax_create_product() {
        global $pw_gift_cards;

        check_ajax_referer( 'pw-gift-cards-create-product', 'security' );

        $pw_gift_cards->set_current_currency_to_default();

        $gift_card_product = pwgc_get_gift_card_product();
        if ( empty( $gift_card_product ) ) {
            $gift_card_product = new WC_Product_PW_Gift_Card();
            $gift_card_product->set_props( array(
                'name'                       => __( 'Gift Card', 'pw-woocommerce-gift-cards' ),
                'pwgc_custom_amount_allowed' => true,
                'pwgc_custom_amount_min'     => '5',
                'pwgc_custom_amount_max'     => '1000',
                'tax_status'                 => PWGC_PURCHASE_TAX_STATUS,
                'pwgc_is_physical_card'      => false,
                'pwgc_no_coupons_allowed'    => false,
                'pwgc_physical_email'        => '',
                'pwgc_expire_days'           => '',
                'pwgc_email_design_ids'      => array(),
            ) );
            $gift_card_product->save();

            $gift_card_product->add_amount( '10' );
            $gift_card_product->add_amount( '25' );
            $gift_card_product->add_amount( '50' );
            $gift_card_product->add_amount( '100' );

            $this->attach_default_image( $gift_card_product->get_id() );
        }

        wp_send_json_success();
    }

    function attach_default_image( $product_id ) {

        // Get the uploads directory, we'll need it in a bit.
        $wp_upload_dir = wp_upload_dir();

        // Copy our generic gift card image from the plugin directory to the uploads directory.
        $source_file = trailingslashit( PWGC_PLUGIN_ROOT ) . 'assets/images/pw-gift-card.png';
        $upload_file = trailingslashit( $wp_upload_dir['path'] ) . basename( 'pw-gift-card.png' );

        if ( !file_exists( $upload_file ) ) {
            copy( $source_file, $upload_file );
        }

        // Check the type of file. We'll use this as the 'post_mime_type'.
        $filetype = wp_check_filetype( basename( $upload_file ), null );

        // Prepare an array of post data for the attachment.
        $attachment = array(
            'guid'           => $wp_upload_dir['url'] . '/' . basename( $upload_file ),
            'post_mime_type' => $filetype['type'],
            'post_title'     => preg_replace( '/\.[^.]+$/', '', basename( $upload_file ) ),
            'post_content'   => '',
            'post_status'    => 'inherit'
        );

        // Insert the attachment.
        $attach_id = wp_insert_attachment( $attachment, $upload_file, $product_id );

        // Make sure that this file is included, as wp_generate_attachment_metadata() depends on it.
        require_once( ABSPATH . 'wp-admin/includes/image.php' );

        // Generate the metadata for the attachment, and update the database record.
        $attach_data = wp_generate_attachment_metadata( $attach_id, $upload_file );
        wp_update_attachment_metadata( $attach_id, $attach_data );

        set_post_thumbnail( $product_id, $attach_id );
    }

    function ajax_create_balance_page() {
        global $pw_gift_cards;

        check_ajax_referer( 'pw-gift-cards-create-balance-page', 'security' );

        $balance_page = pwgc_get_balance_page();
        if ( empty( $balance_page ) ) {

            $slug = 'balance';

            $existing_page = get_page_by_path( $slug );
            if ( $existing_page ) {

                $slug = 'check-balance';
                $existing_page = get_page_by_path( $slug );
                if ( $existing_page ) {

                    $slug = 'check-pw-gift-card-balance';
                    $existing_page = get_page_by_path( $slug );
                    if ( $existing_page ) {
                        wp_send_json_error( array( 'message' => __( 'Unable to find suitable slug for check balance page.', 'pw-woocommerce-gift-cards' ) ) );
                    }
                }
            }

            $page_id = wp_insert_post(
                array(
                    'comment_status'    =>  'closed',
                    'ping_status'       =>  'closed',
                    'post_name'         =>  $slug,
                    'post_title'        =>  __( 'Gift Card Balance', 'pw-woocommerce-gift-cards' ),
                    'post_status'       =>  'publish',
                    'post_type'         =>  'page',
                    'post_content'      => '[' . PWGC_BALANCE_SHORTCODE . ']',
                )
            );
        }

        wp_send_json_success();
    }

    function ajax_adjustment() {
        global $pw_gift_cards;

        check_ajax_referer( 'pw-gift-cards-adjustment', 'security' );

        $number = wc_clean( $_POST['card_number'] );

        $pw_gift_cards->set_current_currency_to_default();

        $balance = 0;

        $gift_card = new PW_Gift_Card( $number );
        if ( $gift_card->get_id() ) {
            $amount = $pw_gift_cards->sanitize_amount( $_POST['amount'] );
            $amount = floatval( $amount );
            if ( isset( $_POST['note'] ) ) {
                $note = stripslashes( wc_clean( $_POST['note'] ) );
            } else {
                $note = '';
            }

            if ( !empty( $amount ) || !empty( $note ) ) {
                $gift_card->adjust_balance( $amount, $note );
            }

            $balance = wc_price( $gift_card->get_balance() );
        }

        if ( !empty( $amount ) ) {
            wp_send_json( array( 'message' => __( 'Balance adjusted.', 'pw-woocommerce-gift-cards' ), 'balance' => $balance ) );
        } else {
            wp_send_json( array( 'message' => __( 'Note added.', 'pw-woocommerce-gift-cards' ), 'balance' => $balance ) );
        }
    }

    function ajax_set_expiration_date() {
        check_ajax_referer( 'pw-gift-cards-expiration-date', 'security' );

        $number = wc_clean( $_POST['card_number'] );

        $gift_card = new PW_Gift_Card( $number );
        if ( $gift_card->get_id() ) {
            $new_expiration_date = wc_clean( $_POST['expiration_date'] );
            if ( empty( $new_expiration_date ) ) {
                $gift_card->set_expiration_date( null );
            } else {
                $date_array = date_parse( $new_expiration_date );
                if ( $date_array !== false ) {
                    $expiration_date = date('Y-m-d H:i:s', mktime( $date_array['hour'], $date_array['minute'], $date_array['second'], $date_array['month'], $date_array['day'], $date_array['year'] ));
                    $gift_card->set_expiration_date( $expiration_date );
                } else {
                    wp_send_json_error( array( 'message' => __( 'Unable to parse expiration date.', 'pw-woocommerce-gift-cards' ) ) );
                }
            }

        } else {
            wp_send_json_error( array( 'message' => __( 'Gift card not found.', 'pw-woocommerce-gift-cards' ) ) );
        }

        wp_send_json( array( 'expiration_date' => $gift_card->get_expiration_date_html() ) );
    }

    function ajax_get_email_form() {
        check_ajax_referer( 'pw-gift-cards-get-email-form', 'security' );

        ob_start();
        require_once( 'ui/sections/search-results-email-form.php' );
        $html = ob_get_clean();

        wp_send_json( array( 'html' => $html ) );
    }

    function ajax_email_gift_card() {
        global $pw_gift_card_design_id;

        check_ajax_referer( 'pw-gift-cards-send-email', 'security' );

        $number = wc_clean( $_POST['card_number'] );
        $email_address = stripslashes( wc_clean( $_POST['email_address'] ) );
        $recipient_name = stripslashes( wc_clean( $_POST['recipient_name'] ) );
        $from = stripslashes( wc_clean( $_POST['from'] ) );
        $message = stripslashes( wc_clean( $_POST['note'] ) );
        $pw_gift_card_design_id = absint( $_POST['design_id'] );
        $save_meta = boolval( wc_clean( $_POST['save_meta'] ) );

        if ( empty( $number ) || empty( $email_address ) ) {
            wp_send_json_error( array( 'message' => __( 'Gift Card Number and Email Address are both required.', 'pw-woocommerce-gift-cards' ) ) );
        }

        $gift_card = new PW_Gift_Card( $number );
        if ( $gift_card->get_id() ) {

            // Optionally save this meta data to the gift card.
            if ( $save_meta ) {
                $gift_card->set_recipient_email( $email_address );
                $gift_card->set_recipient_name( $recipient_name );
                $gift_card->set_from( $from );
                $gift_card->set_message( $message );
                $gift_card->set_email_design_id( $pw_gift_card_design_id );
            }

            do_action( 'pw_gift_cards_send_email_manually', $gift_card->get_number(), $email_address, $from, $recipient_name, $message, $gift_card->get_balance(), '' );

        } else {
            wp_send_json_error( array( 'message' => __( 'Gift card not found.', 'pw-woocommerce-gift-cards' ) ) );
        }

        wp_send_json_success();
    }

    function ajax_delete() {
        check_ajax_referer( 'pw-gift-cards-delete', 'security' );

        $number = wc_clean( $_POST['card_number'] );

        $gift_card = new PW_Gift_Card( $number );
        if ( $gift_card->get_id() ) {
            $deleted = false;

            if ( $gift_card->get_active() ) {
                $gift_card->deactivate();
            } else {
                $gift_card->delete();
                $deleted = true;
            }

            wp_send_json_success( array( 'deleted' => $deleted ) );
        } else {
            wp_send_json_error( array( 'message' => _e( 'Gift card not found.', 'pw-woocommerce-gift-cards' ) ) );
        }
    }

    function ajax_restore() {
        check_ajax_referer( 'pw-gift-cards-restore', 'security' );

        $number = wc_clean( $_POST['card_number'] );

        $gift_card = new PW_Gift_Card( $number );
        if ( $gift_card->get_id() ) {
            $gift_card->reactivate();
            wp_send_json_success();
        } else {
            wp_send_json_error( array( 'message' => _e( 'Gift card not found.', 'pw-woocommerce-gift-cards' ) ) );
        }
    }

    function ajax_select_design() {
        global $pw_gift_cards_email_designer;

        check_ajax_referer( 'pw-gift-cards-select-design', 'security' );

        $design_id = absint( $_REQUEST['design_id'] );

        $designs = $pw_gift_cards_email_designer->get_designs();

        if ( isset( $designs[ $design_id ] ) ) {
            $design = $designs[ $design_id ];

            ob_start();
            require( 'ui/sections/designer-panel.php' );
            $html = ob_get_clean();

        } else {
            $html = __( 'Error: Invalid Design ID', 'pw-woocommerce-gift-cards' ) . ': ' . $design_id;
        }

        wp_send_json( array( 'html' => $html ) );
    }

    function ajax_create_design() {
        global $pw_gift_cards_email_designer;

        check_ajax_referer( 'pw-gift-cards-create-design', 'security' );

        $designs = $pw_gift_cards_email_designer->get_designs();

        $design_id = max( array_keys( $designs ) ) + 1;

        // Use the currently selected design as the template for the new design.
        $designs[] = $designs[ absint( $_REQUEST['design_id'] ) ];

        // Change the name.
        // translators: %s is a counter.
        $name = sprintf( __( 'Design %s', 'pw-woocommerce-gift-cards' ), ( $design_id + 1 ) );
        $designs[ $design_id ]['name'] = $name;

        foreach ( $designs as $design ) {
            if ( $design['order'] > $designs[ $design_id ]['order'] ) {
                $designs[ $design_id ]['order'] = $design['order'] + 1;
            }
        }

        // Save the designs.
        update_option( 'pw_gift_card_designs', $designs, false );

        wp_send_json( array( 'design_id' => $design_id, 'name' => $name ) );
    }

    function ajax_save_design() {
        global $pw_gift_cards;
        global $pw_gift_cards_email_designer;

        check_ajax_referer( 'pw-gift-cards-save-design', 'security' );

        $form = array();
        parse_str( $_REQUEST['form'], $form );

        $designs = $pw_gift_cards_email_designer->get_designs();

        $design_id = absint( $form['design_id'] );
        if ( isset( $designs[ $design_id ] ) ) {

            $default_designs = $pw_gift_cards_email_designer->get_default_designs();
            $default_design = reset( $default_designs );
            foreach( $default_design as $key => $value ) {
                $designs[ $design_id ][ $key ] = isset( $form[ $key ] ) ? stripslashes( $form[ $key ] ) : '';

                // Ensure that the Dropdown Menu Order is numeric for comparisons.
                if ( $key == 'order' && !is_numeric( $designs[ $design_id ][ $key ] ) ) {
                    $designs[ $design_id ][ $key ] = intval( $designs[ $design_id ][ $key ] );
                }
            }

            update_option( 'pw_gift_card_designs', $designs, false );

            $html = '<span style="color: blue;">' . __( 'Design saved.', 'pw-woocommerce-gift-cards' ) . '</span>';
        } else {
            $html = '<span style="color: red;">' . __( 'Error: Invalid Design ID', 'pw-woocommerce-gift-cards' ) . ': ' . $design_id . '</span>';
        }

        wp_send_json( array( 'html' => $html, 'designs' => $this->get_design_options_html( $design_id ) ) );
    }

    function ajax_delete_design() {
        global $pw_gift_cards;
        global $pw_gift_cards_email_designer;

        check_ajax_referer( 'pw-gift-cards-delete-design', 'security' );

        $designs = $pw_gift_cards_email_designer->get_designs();

        $design_id = absint( $_REQUEST['design_id'] );
        if ( isset( $designs[ $design_id ] ) ) {
            unset( $designs[ $design_id ] );

            // Make sure we always have designs;
            if ( 0 == count( $designs ) ) {
                $designs = $pw_gift_cards_email_designer->get_default_designs();
            }

            update_option( 'pw_gift_card_designs', $designs, false );

            wp_send_json( array( 'designs' => $this->get_design_options_html( 0 ) ) );
        } else {
            wp_send_json_error();
        }
    }

    function ajax_preview_email() {
        global $pw_gift_card_design_id;
        global $pw_gift_cards_email_designer;

        check_ajax_referer( 'pw-gift-cards-preview-email', 'security' );

        $designs = $pw_gift_cards_email_designer->get_designs();

        $design_id = absint( $_REQUEST['design_id'] );
        if ( isset( $designs[ $design_id ] ) ) {

            $pw_gift_card_design_id = $design_id;

            $gift_card_number = pwgc_get_example_gift_card_number();
            $recipient = wc_clean( $_REQUEST['email_address'] );
            $from = __( 'Preview email system', 'pw-woocommerce-gift-cards' );
            $recipient_name = __( 'Recipient Name', 'pw-woocommerce-gift-cards' );
            $message = __( 'Gift card message to the recipient from the sender.', 'pw-woocommerce-gift-cards' );
            $amount = '123.45';
            $expiration_date = date_i18n( wc_date_format() );

            do_action( 'pw_gift_cards_send_email_manually', $gift_card_number, $recipient, $from, $recipient_name, $message, $amount, $expiration_date );

            $html = '<span style="color: blue;">' . __( 'Email sent.', 'pw-woocommerce-gift-cards' ) . '</span>';
        } else {
            $html = '<span style="color: red;">' . __( 'Error: Invalid Design ID', 'pw-woocommerce-gift-cards' ) . ': ' . $design_id . '</span>';
        }

        wp_send_json( array( 'html' => $html ) );
    }

    function get_design_options_html( $design_id ) {
        global $pw_gift_cards_email_designer;

        $html = '';
        foreach ( $pw_gift_cards_email_designer->get_designs( true ) as $id => $design_option ) {
            $html .= sprintf( '<option value="%s" %s>%s</option>', $id, selected( $design_id, $id, false ), esc_html( $design_option['name'] ) );
        }

        return $html;
    }
}

global $pw_gift_cards_admin;
$pw_gift_cards_admin = new PW_Gift_Cards_Admin();

endif;
