<?php

defined( 'ABSPATH' ) or exit;

final class PWLPAR_Admin {

    public $meta_boxes;

    function __construct() {
        if ( !current_user_can( PWLPAR_REQUIRES_PRIVILEGE ) ) {
            return;
        }

        require_once( PWLPAR_PLUGIN_DIR . '/admin/pwlpara-admin-functions.php' );
        require_once( PWLPAR_PLUGIN_DIR . '/admin/class-pwlpar-admin-meta-boxes.php' );

        // Show an alert on the backend if we don't have the minimum required version.
        if ( !pwlpara_wc_min_version( PWLPAR_WC_VERSION_MINIMUM ) ) {
            add_action( 'admin_notices', array( $this, 'woocommerce_version_error' ) );
            return;
        }

        $this->meta_boxes = new PWLPAR_Admin_Meta_Boxes();

        add_action( 'admin_menu', array( $this, 'admin_menu' ) );
        add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
        add_filter( 'woocommerce_screen_ids', array( $this, 'woocommerce_screen_ids' ) );

        add_action( 'wp_ajax_pwlpar-save_welcome_wizard', array( $this, 'ajax_save_welcome_wizard' ) );
        add_action( 'wp_ajax_pwlpar-load_members', array( $this, 'ajax_load_members' ) );
        add_action( 'wp_ajax_pwlpar-save_member', array( $this, 'ajax_save_member' ) );
        add_action( 'wp_ajax_pwlpar-delete_transaction', array( $this, 'ajax_delete_transaction' ) );
        add_action( 'wp_ajax_pwlpar-delete_reward', array( $this, 'ajax_delete_reward' ) );

        add_action( 'wp_ajax_pwlpar-load_offers', array( $this, 'ajax_load_offers' ) );
        add_action( 'wp_ajax_pwlpar-sort_offers', array( $this, 'ajax_sort_offers' ) );
        add_action( 'wp_ajax_pwlpar-save_offer', array( $this, 'ajax_save_offer' ) );
        add_action( 'wp_ajax_pwlpar-delete_offer', array( $this, 'ajax_delete_offer' ) );

        add_action( 'wp_ajax_pwlpar-save_settings', array( $this, 'ajax_save_settings' ) );

        add_action( 'show_user_profile', array( $this, 'admin_user_profile' ) );
        add_action( 'edit_user_profile', array( $this, 'admin_user_profile' ) );

        add_action( 'personal_options_update', array( $this, 'save_user_meta_fields' ) );
        add_action( 'edit_user_profile_update', array( $this, 'save_user_meta_fields' ) );

        add_action( 'wp_ajax_pwlpar-view_transactions', array( $this, 'ajax_view_transactions' ) );
        add_action( 'wp_ajax_pwlpar-adjust_balance', array( $this, 'ajax_adjust_balance' ) );

        add_filter( 'plugin_action_links_' . plugin_basename( PWLPAR_PLUGIN_FILE ), array( $this, 'plugin_action_links' ) );

        //
        // Nonce verification not needed because we only look for the existence of the parameter.
        //
        // phpcs:ignore WordPress.Security.NonceVerification
        if ( isset( $_GET['skip_setup'] ) && current_user_can( PWLPAR_REQUIRES_PRIVILEGE ) ) {
            pwlpara_setup_wizard_is_complete();
        }
    }

    function woocommerce_version_error() {
        ?>
        <div class="error notice">
            <p>
                <?php
                    // translators: %1$s is the plugin name, %2$s is the minimum WooCommerce version number required.
                    printf( esc_html__( '%1$s requires WooCommerce version %2$s or later.', 'pw-loyalty-points-and-rewards-for-woocommerce' ), esc_html( PWLPAR_PLUGIN_NAME ), esc_html( PWLPAR_WC_VERSION_MINIMUM ) );
                ?>
            </p>
        </div>
        <?php
    }

    function admin_menu() {
        if ( get_option( 'hide_pimwick_menu', 'no' ) === 'no' ) {
            if ( empty ( $GLOBALS['admin_page_hooks']['pimwick'] ) ) {
                add_menu_page(
                    PWLPAR_PLUGIN_NAME,
                    'Pimwick Plugins',
                    PWLPAR_REQUIRES_PRIVILEGE,
                    'pimwick',
                    array( $this, 'index' ),
                    pwlpar_relative_url( '/assets/images/pimwick-icon-120x120.png' ),
                    6
                );

                add_submenu_page(
                    'pimwick',
                    PWLPAR_PLUGIN_NAME,
                    'Pimwick Plugins',
                    PWLPAR_REQUIRES_PRIVILEGE,
                    'pimwick',
                    array( $this, 'index' )
                );

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

            add_submenu_page(
                'pimwick',
                PWLPAR_PLUGIN_NAME,
                PWLPAR_PLUGIN_SHORT_NAME,
                PWLPAR_REQUIRES_PRIVILEGE,
                'pw-loyalty-points-and-rewards-for-woocommerce',
                array( $this, 'index' )
            );
        }

        add_submenu_page(
            'woocommerce',
            PWLPAR_PLUGIN_NAME,
            PWLPAR_PLUGIN_SHORT_NAME,
            PWLPAR_REQUIRES_PRIVILEGE,
            'wc-pw-loyalty-points-and-rewards-for-woocommerce',
            array( $this, 'index' )
        );
    }

    function index() {
        require_once( PWLPAR_PLUGIN_DIR . '/admin/ui/index.php' );
    }

    function admin_enqueue_scripts( $hook ) {

        wp_enqueue_style( 'pwlpar-icon', pwlpar_relative_url( '/assets/css/icon-style.css' ), array( 'admin-menu' ), PWLPAR_VERSION );

        if ( empty( $hook ) ) {
            return;
        }

        if ( $hook == 'pimwick-plugins_page_pw-loyalty-points-and-rewards-for-woocommerce' || $hook == 'woocommerce_page_wc-pw-loyalty-points-and-rewards-for-woocommerce' ) {
            // For the image uploader and color picker.
            wp_enqueue_media();
            wp_enqueue_style( 'wp-color-picker' );

            // For the date picker.
            wp_enqueue_script( 'jquery-ui-datepicker' );
            wp_enqueue_style( 'jquery-ui-style' );

            // For sorting.
            wp_enqueue_script( 'jquery-ui-sortable' );

            // Enqueue the styles for the Preview sections.
            wp_enqueue_style( 'pwlpar-header' );
            wp_enqueue_style( 'pwlpar-offer' );
            wp_enqueue_script( 'pwlpar-offer' );
            wp_enqueue_style( 'pwlpar-reward' );
            wp_enqueue_script( 'pwlpar-reward' );
            wp_enqueue_style( 'pwlpar-frontend' );

            // Admin stuff.
            wp_enqueue_style( 'pwlpar-admin' );

            wp_enqueue_script( 'pwlpar-admin' );
            wp_enqueue_script( 'pwlpar-admin-welcome' );
            wp_enqueue_script( 'pwlpar-admin-dashboard' );
            wp_enqueue_script( 'pwlpar-admin-members' );
            wp_enqueue_script( 'pwlpar-admin-offers' );
            wp_enqueue_script( 'pwlpar-admin-settings' );
            wp_enqueue_script( 'pwlpar-admin-help' );

        }
    }

    function woocommerce_screen_ids( $screen_ids ) {
        $screen_ids[] = 'pimwick-plugins_page_pw-loyalty-points-and-rewards-for-woocommerce';
        $screen_ids[] = 'woocommerce_page_wc-pw-loyalty-points-and-rewards-for-woocommerce';

        return $screen_ids;
    }

    function ajax_save_welcome_wizard() {
        check_ajax_referer( 'pwlpar-submit-form', 'security' );

        if ( !isset( $_POST['form'] ) ) { wp_send_json_error( array( 'message' => __( 'Form missing error', 'pw-loyalty-points-and-rewards-for-woocommerce' ) ) ); }

        $errors = array();
        $form = array();

        //
        // Sanitation directly on $_POST['form'] isn't done since the form is split into an array and then all the fields are sanitized below.
        //
        // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
        wp_parse_str( wp_unslash( $_POST['form'] ), $form );

        $program_name               = trim( wc_clean( $form['program_name'] ) );
        $reward_value               = wc_clean( $form['reward_value'] );
        $reward_points              = absint( $form['reward_points'] );
        $signup_bonus_points        = absint( $form['signup_bonus_points'] );

        if ( empty( $program_name ) ) {
            $errors[] = __( 'Program name is required.', 'pw-loyalty-points-and-rewards-for-woocommerce' );
        }

        if ( empty( $errors ) ) {
            update_option( 'pwlpar_program_name', $program_name );
            update_option( 'pwlpar_reward_value', $reward_value, false );
            update_option( 'pwlpar_reward_points', $reward_points, false );
            update_option( 'pwlpar_signup_bonus_points', $signup_bonus_points, false );

            if ( isset( $form['welcome_offers'] ) && is_array( $form['welcome_offers'] ) ) {
                $welcome_offers = pwlpara_get_welcome_offers();
                foreach ( $welcome_offers as $index => $offer ) {
                    if ( in_array( $index, $form['welcome_offers'] ) ) {
                        $offer->save();
                    }
                }
            }

            pwlpara_setup_wizard_is_complete();

            wp_send_json_success( array( 'url' => pwlpara_admin_url( 'settings', array( 'saved' => '1' ) ) ) );
        } else {
            $html = '<span style="color: red; font-weight: bold;">' . __( 'Error', 'pw-loyalty-points-and-rewards-for-woocommerce' ) . ': ' . implode( ', ', $errors ) . '</span>';
            wp_send_json_error( array( 'html' => $html ) );
        }
    }

    function ajax_load_members() {
        check_ajax_referer( 'pwlpar-load-members', 'security' );

        $search = isset( $_POST['search'] ) ? trim( sanitize_text_field( wp_unslash( $_POST['search'] ) ) ) : '';

        ob_start();
        require_once( PWLPAR_PLUGIN_DIR . '/admin/ui/sections/members-table.php' );
        $html = ob_get_clean();

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

    function ajax_save_member() {
        check_ajax_referer( 'pwlpar-submit-form', 'security' );

        if ( !isset( $_POST['form'] ) ) { wp_send_json_error( array( 'message' => __( 'Form missing error', 'pw-loyalty-points-and-rewards-for-woocommerce' ) ) ); }

        $form = array();

        //
        // Sanitation directly on $_POST['form'] isn't done since the form is split into an array and then all the fields are sanitized below.
        //
        // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
        parse_str( wp_unslash( $_POST['form'] ), $form );

        $member = pwlpar_get_member( absint( $form['member_id'] ) );
        if ( !$member ) {
            wp_send_json_error( array( 'html' => '<span style="color: red; font-weight: bold;">' . __( 'Error', 'pw-loyalty-points-and-rewards-for-woocommerce' ) . ': ' . __( 'Member not found.', 'pw-loyalty-points-and-rewards-for-woocommerce' ) . '</span>' ) );
        }

        if ( isset( $form['is_enrolled'] ) ) {
            $result = pwlpar_enroll_user( $member->get_id() );
        } else {
            $result = pwlpar_unenroll_user( $member->get_id() );
        }

        if ( $result === true ) {
            $html = '<span style="color: blue;">' . __( 'Saved', 'pw-loyalty-points-and-rewards-for-woocommerce' ) . '</span>';
            wp_send_json_success( array( 'url' => pwlpara_admin_url( 'members', array( 'id' => $member->get_id(), 'saved' => '1' ) ) ) );
        } else {
            $html = '<span style="color: red; font-weight: bold;">' . __( 'Error', 'pw-loyalty-points-and-rewards-for-woocommerce' ) . ': ' . $result . '</span>';
            wp_send_json_error( array( 'html' => $html ) );
        }
    }

    function ajax_delete_transaction() {
        check_ajax_referer( 'pwlpar-delete-transaction', 'security' );

        $transaction = isset( $_POST['transaction_id'] ) ? pwlpar_get_transaction( absint( $_POST['transaction_id'] ) ) : 0;
        if ( empty( $transaction ) ) {
            wp_send_json_error( array( 'message' => __( 'Transaction not found.', 'pw-loyalty-points-and-rewards-for-woocommerce' ) ) );
        }

        $result = $transaction->delete();
        if ( $result === true ) {
            wp_send_json_success();
        } else {
            wp_send_json_error( array( 'message' => __( 'Error', 'pw-loyalty-points-and-rewards-for-woocommerce' ) . ' ' . $result ) );
        }
    }

    function ajax_delete_reward() {
        check_ajax_referer( 'pwlpar-delete-reward', 'security' );

        $reward = isset( $_POST['reward_id'] ) ? pwlpar_get_reward( absint( $_POST['reward_id'] ) ) : false;
        if ( empty( $reward ) ) {
            wp_send_json_error( array( 'message' => __( 'Reward not found.', 'pw-loyalty-points-and-rewards-for-woocommerce' ) ) );
        }

        $result = $reward->delete();
        if ( $result === true ) {
            wp_send_json_success();
        } else {
            wp_send_json_error( array( 'message' => __( 'Error', 'pw-loyalty-points-and-rewards-for-woocommerce' ) . ' ' . $result ) );
        }

        wp_send_json_success();
    }

    function ajax_load_offers() {
        check_ajax_referer( 'pwlpar-load-offers', 'security' );

        ob_start();
        require_once( PWLPAR_PLUGIN_DIR . '/admin/ui/sections/offers-table.php' );
        $html = ob_get_clean();

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

    function ajax_sort_offers() {
        check_ajax_referer( 'pwlpar-sort-offers', 'security' );

        if ( isset( $_POST['offer_ids'] ) && is_array( $_POST['offer_ids'] ) ) {
            $offer_ids = isset( $_POST['offer_ids'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['offer_ids'] ) ) : array();

            foreach ( $offer_ids as $index => $offer_id ) {
                $offer = pwlpar_get_offer( absint( $offer_id ) );
                $offer->set_menu_order( absint( $index ) );
                $offer->save();
            }
        } else {
            wp_send_json_error( array( 'message' => __( 'Error', 'pw-loyalty-points-and-rewards-for-woocommerce' ) ) );
        }

        wp_send_json_success();
    }

    function ajax_save_offer() {
        check_ajax_referer( 'pwlpar-submit-form', 'security' );

        if ( !isset( $_POST['form'] ) ) { wp_send_json_error( array( 'message' => __( 'Form missing error', 'pw-loyalty-points-and-rewards-for-woocommerce' ) ) ); }

        $form = array();

        //
        // Sanitation directly on $_POST['form'] isn't done since the form is split into an array and then all the fields are sanitized below.
        //
        // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
        parse_str( wp_unslash( $_POST['form'] ), $form );

        $offer = pwlpar_get_offer( absint( $form['offer_id'] ) );

        $title                  = !empty( $form['title'] ) ? trim( wc_clean( $form['title'] ) ) : $offer->get_title( 'edit' );
        $description            = $form['description'];
        $points                 = !empty( $form['points'] ) ? absint( $form['points'] ) : null;
        $coupon_amount          = !empty( $form['coupon_amount'] ) ? absint( $form['coupon_amount'] ) : null;
        $free_shipping          = isset( $form['free_shipping'] );
        $individual_use         = isset( $form['individual_use'] );
        $exclude_sale_items     = isset( $form['exclude_sale_items'] );
        $status                 = isset( $form['active'] ) ? 'publish' : 'draft';
        $product_ids            = isset( $form['product_ids'] ) ? array_filter( array_map( 'intval', (array) $form['product_ids'] ) ) : array();
        $excluded_product_ids   = isset( $form['excluded_product_ids'] ) ? array_filter( array_map( 'intval', (array) $form['excluded_product_ids'] ) ) : array();
        $category_ids           = isset( $form['category_ids'] ) ? array_filter( array_map( 'intval', (array) $form['category_ids'] ) ) : array();
        $excluded_category_ids  = isset( $form['excluded_category_ids'] ) ? array_filter( array_map( 'intval', (array) $form['excluded_category_ids'] ) ) : array();

        $errors = array();

        if ( empty( $errors ) ) {
            $offer->set_title( $title );
            $offer->set_description( $description );
            $offer->set_points( $points );
            $offer->set_coupon_amount( $coupon_amount );
            $offer->set_free_shipping( $free_shipping );
            $offer->set_individual_use( $individual_use );
            $offer->set_exclude_sale_items( $exclude_sale_items );
            $offer->set_status( $status );
            $offer->set_product_ids( $product_ids );
            $offer->set_excluded_product_ids( $excluded_product_ids );
            $offer->set_category_ids( $category_ids );
            $offer->set_excluded_category_ids( $excluded_category_ids );

            $offer->save();

            wp_send_json_success( array( 'url' => pwlpara_admin_url( 'offers', array( 'id' => $offer->get_id(), 'saved' => '1' ) ) ) );
        } else {
            $html = '<span style="color: red; font-weight: bold;">' . __( 'Error', 'pw-loyalty-points-and-rewards-for-woocommerce' ) . ': ' . implode( ', ', $errors ) . '</span>';
            wp_send_json_error( array( 'html' => $html ) );
        }
    }

    function ajax_delete_offer() {
        check_ajax_referer( 'pwlpar-delete-offer', 'security' );

        $offer_id = isset( $_POST['offer_id'] ) ? absint( $_POST['offer_id'] ) : 0;

        if ( !empty( $offer_id ) ) {
            $offer = pwlpar_get_offer( $offer_id );
            $offer->delete();

            wp_send_json_success();
        } else {
            wp_send_json_error( array( 'message' => __( 'Error', 'pw-loyalty-points-and-rewards-for-woocommerce' ) ) );
        }
    }

    function ajax_save_settings() {
        check_ajax_referer( 'pwlpar-submit-form', 'security' );

        if ( !isset( $_POST['form'] ) ) { wp_send_json_error( array( 'message' => __( 'Form missing error', 'pw-loyalty-points-and-rewards-for-woocommerce' ) ) ); }

        $errors = array();
        $form = array();

        //
        // Sanitation directly on $_POST['form'] isn't done since the form is split into an array and then all the fields are sanitized below.
        //
        // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
        parse_str( wp_unslash( $_POST['form'] ), $form );

        $is_active                  = isset( $form['is_active'] ) ? 'yes' : 'no';
        $program_name               = trim( wc_clean( $form['program_name'] ) );
        $custom_logo                = wc_clean( $form['custom_logo'] );
        $logo_url                   = ( $form['logo_url'] != 'custom' ) ? wc_clean( $form['logo_url'] ) : $custom_logo;
        $primary_color              = wc_clean( $form['primary_color'] );
        $secondary_color            = wc_clean( $form['secondary_color'] );
        $background_color           = wc_clean( $form['background_color'] );
        $text_color                 = wc_clean( $form['text_color'] );
        $reward_value               = wc_clean( $form['reward_value'] );
        $reward_points              = absint( $form['reward_points'] );
        $earning_excludes_coupons   = isset( $form['earning_excludes_coupons'] ) ? 'yes' : 'no';
        $earning_includes_tax       = isset( $form['earning_includes_tax'] ) ? 'yes' : 'no';
        $earning_includes_shipping  = isset( $form['earning_includes_shipping'] ) ? 'yes' : 'no';
        $earning_excludes_on_sale   = isset( $form['earning_excludes_on_sale'] ) ? 'yes' : 'no';
        $signup_bonus_points        = absint( $form['signup_bonus_points'] );
        $join_page_id               = absint( $form['join_page_id'] );
        $checkout_join_cta          = $form['checkout_join_cta'];
        $home_page_id               = absint( $form['home_page_id'] );

        if ( empty( $program_name ) ) {
            $errors[] = __( 'Program name is required.', 'pw-loyalty-points-and-rewards-for-woocommerce' );
        }

        if ( empty( $errors ) ) {
            update_option( 'pwlpar_is_active', $is_active );
            update_option( 'pwlpar_program_name', $program_name );
            update_option( 'pwlpar_logo_url', $logo_url, false );
            update_option( 'pwlpar_primary_color', $primary_color );
            update_option( 'pwlpar_secondary_color', $secondary_color );
            update_option( 'pwlpar_background_color', $background_color );
            update_option( 'pwlpar_text_color', $text_color );
            update_option( 'pwlpar_reward_value', $reward_value, false );
            update_option( 'pwlpar_reward_points', $reward_points, false );
            update_option( 'pwlpar_earning_excludes_coupons', $earning_excludes_coupons, false );
            update_option( 'pwlpar_earning_includes_tax', $earning_includes_tax, false );
            update_option( 'pwlpar_earning_includes_shipping', $earning_includes_shipping, false );
            update_option( 'pwlpar_earning_excludes_on_sale', $earning_excludes_on_sale, false );
            update_option( 'pwlpar_signup_bonus_points', $signup_bonus_points, false );
            update_option( 'pwlpar_join_page_id', $join_page_id, false );
            update_option( 'pwlpar_checkout_join_cta', $checkout_join_cta, false );
            update_option( 'pwlpar_home_page_id', $home_page_id, false );

            wp_send_json_success( array( 'url' => pwlpara_admin_url( 'settings', array( 'saved' => '1' ) ) ) );
        } else {
            $html = '<span style="color: red; font-weight: bold;">' . __( 'Error', 'pw-loyalty-points-and-rewards-for-woocommerce' ) . ': ' . implode( ', ', $errors ) . '</span>';
            wp_send_json_error( array( 'html' => $html ) );
        }
    }

    function admin_user_profile( $user ) {
        $is_member = pwlpar_user_is_rewards_member( $user->ID );

        ?>
        <h2 id="pwlpar-member-section"><?php echo esc_html( pwlpar_program_name() ); ?></h2>
        <table class="form-table">
            <tr>
                <th>
                    <label for="pwlpar-user-edit-is-member">
                        <?php
                            /* translators: %s is the rewards program name. */
                            printf( esc_html__( '%s Member', 'pw-loyalty-points-and-rewards-for-woocommerce' ), esc_html( pwlpar_program_name() ) );
                        ?>
                    </label>
                </th>
                <td>
                    <input type="checkbox" name="pwlpar_is_member" id="pwlpar-user-edit-is-member" value="true" <?php checked( $is_member, true ); ?> />
                </td>
            </tr>
            <?php if ( $is_member ) : ?>
                <tr class="pwlpar-user-edit-details">
                    <th>
                        <?php esc_html_e( 'Details', 'pw-loyalty-points-and-rewards-for-woocommerce' ); ?>
                    </th>
                    <td>
                        <a href="<?php echo esc_attr( pwlpara_admin_url( 'members', array( 'id' => $user->ID ) ) ); ?>" class="button"><?php esc_html_e( 'View details', 'pw-loyalty-points-and-rewards-for-woocommerce' ); ?></a>
                    </td>
                </tr>
            <?php endif; ?>
        </table>
        <?php
    }

    function save_user_meta_fields( $user_id ) {
        check_admin_referer( 'update-user_' . $user_id );

        if ( isset( $_POST['pwlpar_is_member'] ) ) {
            $result = pwlpar_enroll_user( $user_id );
        } else {
            $result = pwlpar_unenroll_user( $user_id );
        }

        if ( $result !== true ) {
            wp_die( esc_html__( 'Error', 'pw-loyalty-points-and-rewards-for-woocommerce' ) . ': ' . esc_html( $result ) );
        }
    }

    function ajax_view_transactions() {
        check_ajax_referer( 'pwlpar-view-transactions', 'security' );

        $member = isset( $_POST['user_id'] ) ? pwlpar_get_member( absint( $_POST['user_id'] ) ) : false;
        if ( !$member ) {
            wp_send_json_error( array( 'message' => __( 'Member not found.', 'pw-loyalty-points-and-rewards-for-woocommerce' ) ) );
        }

        ob_start();
        require_once( PWLPAR_PLUGIN_DIR . '/admin/ui/sections/member-transactions.php' );
        $html = ob_get_clean();

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

    function ajax_adjust_balance() {
        global $wpdb;

        check_ajax_referer( 'pwlpar-adjust-balance', 'security' );

        $member = isset( $_POST['user_id'] ) ? pwlpar_get_member( absint( $_POST['user_id'] ) ) : false;
        if ( !$member ) {
            wp_send_json_error( array( 'message' => __( 'Member not found.', 'pw-loyalty-points-and-rewards-for-woocommerce' ) ) );
        }

        $amount = isset( $_POST['amount'] ) ? sanitize_text_field( wp_unslash( $_POST['amount'] ) ) : false;
        if ( empty( $amount ) || !is_numeric( $amount ) ) {
            wp_send_json_error( array( 'message' => __( 'Adjustment amount must be numeric.', 'pw-loyalty-points-and-rewards-for-woocommerce' ) ) );
        }

        $note = isset( $_POST['note'] ) ? stripslashes( sanitize_text_field( wp_unslash( $_POST['note'] ) ) ) : '';

        $result = pwlpar_add_transaction( array(
            'user_id' => $member->get_id(),
            'points' => $amount,
            'note' => $note,
        ) );

        $balance = pwlpar_format_points( pwlpar_get_member_point_balance( $member->get_id() ) );

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

    function plugin_action_links( $links ) {

        array_unshift( $links,
            sprintf(
                '<a href="%1$s" title="%2$s" style="color: #d46f4d; font-weight: bold;" target="_blank">%3$s</a>',
                'https://www.pimwick.com/pw-loyalty-points-and-rewards-for-woocommerce/',
                esc_attr__( 'Upgrade to Pro', 'pw-loyalty-points-and-rewards-for-woocommerce' ),
                esc_html__( 'Go Pro', 'pw-loyalty-points-and-rewards-for-woocommerce' )
            )
        );

        array_unshift( $links,
            sprintf( '<a href="%s">' . __( 'Settings', 'pw-loyalty-points-and-rewards-for-woocommerce' ) . '</a>', esc_url( pwlpara_admin_url() ) )
        );

        return $links;
    }
}

return new PWLPAR_Admin();
