<?php
/**
 * Holds the admin coupons class
 *
 * @category Admin
 * @package  WC_Vendors_Pro/Admin
 *
 * @version 1.8.5
 * @since   1.8.5
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * The admin class handles all admin coupons
 *
 * @category    Admin
 *
 * @version 1.8.5
 * @since   1.8.5
 */
class WCVendors_Pro_Admin_Shop_Coupon {
    /**
     * The ID of this plugin.
     *
     * @version  1.8.5
     * @since    1.8.5
     * @access   private
     * @var      string $wcvendors_pro The ID of this plugin.
     */
    private $wcvendors_pro;

    /**
     * The version of this plugin.
     *
     * @version  1.8.5
     * @since    1.8.5
     * @access   private
     * @var      string $version The current version of this plugin.
     */
    private $version;

    /**
     * Is the plugin in debug mode
     *
     * @version  1.8.5
     * @since    1.8.5
     * @access   private
     * @var      bool $debug plugin is in debug mode
     */
    private $debug;

    /**
     * The plugin base dir of the current file.
     *
     * @var string
     */
    private $base_dir;

    /**
     * Initialize the class and set its properties.
     *
     * @version  1.8.5
     * @since    1.8.5
     *
     * @param    string $wcvendors_pro The name of this plugin.
     * @param    string $version       The version of this plugin.
     * @param    bool   $debug         Plugin in debug mode.
     */
    public function __construct( $wcvendors_pro, $version, $debug ) {

        $this->wcvendors_pro = $wcvendors_pro;
        $this->version       = $version;
        $this->debug         = $debug;
        $this->base_dir      = plugin_dir_url( __FILE__ );

        // Add post type support for author on shop_coupon.
        add_post_type_support( 'shop_coupon', 'author' );
    }

    /**
     * Add coupon author select box.
     *
     * @param string $output The current HTML output.
     * @return string The html to output.
     * @version 1.8.6
     * @since   1.8.5
     */
    public function coupon_vendor_selectbox( $output ) {
        global $post;
        $screen    = get_current_screen();
        $screen_id = $screen->id;
        if ( 'edit-shop_coupon' !== $screen_id ) {
            return $output;
        }

        $media  = false;
        $args   = array(
            'selected' => get_post_field( 'post_author', $post->ID ),
        );
        $output = wcv_vendor_selectbox( $args, $media );

        return apply_filters( 'wcvendors_product_vendor_selectbox', $output, $media, $args );
    }

    /**
     * Hook into the current screen so that the gettext filter only runs on the coupon edit screen.
     *
     * @param WP_Screen $screen The current screen object.
     * @return void
     * @version 1.8.6
     * @since   1.8.6
     */
    public function current_screen_coupon( $screen ) {
        if ( 'edit-shop_coupon' === $screen->id ) {
            add_filter( 'gettext', array( $this, 'change_author_to_vendor' ), 99, 3 );
        }
    }

    /**
     * Change author metabox label to vendor
     *
     * @param string $label The current post Author label.
     * @return string
     * @version 1.8.5
     * @since   1.8.5
     */
    public function change_author_to_vendor( $label ) {
        if ( 'Author' === $label ) {
            return wcv_get_vendor_name();
        }

        return $label;
    }

    /**
     * Change the "Author" metabox to "Vendor"
     *
     * @return void
     * @version 1.8.5
     * @since   1.8.5
     */
    public function change_author_meta_box_title() {

        global $wp_meta_boxes;
        $wp_meta_boxes['shop_coupon']['normal']['core']['authordiv']['title'] = wcv_get_vendor_name(); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
        $wp_meta_boxes['shop_coupon']['normal']['core']['authordiv']['args']  = array( // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
            '__block_editor_compatible_meta_box' => true,
            '__back_compat_meta_box'             => false,
        );
    }

    /**
     * Add vendor coupon field
     *
     * @param WC_Coupon $coupon The coupon object.
     * @return void
     * @version 1.8.5
     * @since   1.8.5
     */
    public function add_coupon_author_field( $coupon ) {

        $args = $this->get_default_coupon_field_args( $coupon );

        $output_type = 'echo';
        wcv_vendor_select_field( $args, $output_type );
    }

    /**
     * Save coupon author
     *
     * @param int $coupon_id The post ID of the coupon.
     * @return void
     * @version 1.8.5
     * @since   1.8.5
     */
    public function save_coupon_author( $coupon_id ) {
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
        $post_author = isset( $_REQUEST['post_author'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['post_author'] ) ) : 0;

        if ( ! $post_author ) {
            return;
        }

        $coupon_update = array(
            'ID'          => $coupon_id,
            'post_author' => $post_author,
        );

        wp_update_post( $coupon_update );
    }

    /**
     * Add custom columns to the coupons table
     *
     * @param array $columns The currently registered columns.
     * @return array
     * @version 1.8.5
     * @since   1.8.5
     */
    public function define_columns( $columns ) {
        /* translators: %s Vendor name */
        $columns['vendor_store'] = sprintf( __( '%s store', 'wc-vendors' ), wcv_get_vendor_name() );

        /**
         * Filter to define columns to the coupons table
         *
         * @param array $columns The list of currently registered columns.
         *
         * @version 1.8.5
         * @since   1.8.5
         *
         * @return array $columns
         */
        return apply_filters( 'wcvendors_pro_admin_coupons_table_columns', $columns );
    }

    /**
     * Render custom columns
     *
     * @param string $column    The name or slug of the column.
     * @param int    $coupon_id The Post ID of the current coupon.
     * @return void
     * @version 1.8.5
     * @since   1.8.5
     */
    public function render_column( $column, $coupon_id ) {
        if ( ! $coupon_id ) {
            return;
        }
        switch ( $column ) {
            case 'vendor_store':
                $this->render_vendor_column( $coupon_id );
                break;
            default:
                /**
                 * Hook to display custom columns on the coupons table.
                 *
                 * @version 1.8.5
                 * @since   1.8.5
                 */
                do_action( 'wcvendors_pro_display_shop_coupons_table_column', $column, $coupon_id );
                break;
        }
    }

    /**
     * Custom bulk edit - form.
     *
     * @param string $column_name Column being shown.
     * @param string $post_type Post type being shown.
     */
    public function render_bulk_edit_fields( $column_name, $post_type ) {
        global $post;
        if ( 'shop_coupon' !== $post_type ) {
            return;
        }

        $coupon = new WC_Coupon( $post->ID );

        /**
         * Action to render custom bulk edit screens for coupons
         *
         * @version 1.8.5
         * @since   1.8.5
         */
        do_action( 'wcvendors_pro_admin_shop_coupon_render_bulk_edit_field_' . $column_name, $coupon, $post_type );
    }

    /**
     * Get coupon field args
     *
     * @param WC_Coupon $coupon The current coupon.
     * @return array
     * @version 1.8.5
     * @since   1.8.5
     */
    public function get_default_coupon_field_args( $coupon ) {
        $args = array(
            'id'            => 'post_author',
            'label'         => wcv_get_vendor_name(),
            'placeholder'   => sprintf(
                // translators: %s Name used to refer to a vendor.
                __( 'Select a %s', 'wc-vendors' ),
                wcv_get_vendor_name( true, false )
            ),
            'wrapper_class' => 'form-field',
            'label_class'   => '',
            'selected'      => get_post_field( 'post_author', $coupon->get_id() ),
            'wrapper'       => 'p',
        );

        /**
         * Filter to change the properties of the vendor select field
         *
         * @param array     $args The current arguments for the select field.
         * @param int       $coupon_id The ID of the coupon.
         * @param WC_Coupon $coupon The coupon object.
         */
        return apply_filters( 'wcvendors_pro_admin_shop_coupon_field_args', $args, $coupon->get_id(), $coupon );
    }


    /**
     * Custom quick edit - form.
     *
     * @param string $column_name Column being shown.
     * @param string $post_type Post type being shown.
     */
    public function render_quick_edit_field( $column_name, $post_type ) {
        /**
         * Action hook to render quick edit actions
         *
         * @param string $column_name The column name.
         * @param string $post_type The current post type.
         *
         * @version 1.8.5
         * @since   1.8.5
         */
        do_action( 'wcvendors_pro_admin_coupons_render_quick_edit_field_' . $column_name, $column_name, $post_type );
    }


    /**
     * Add a vendor store column data to coupons in the WP_LIST_TABLE
     *
     * @version 1.8.5
     * @since   1.8.5
     *
     * @param int $coupon_id The post id the coupon.
     */
    public function render_vendor_column( $coupon_id ) {

        $vendor_id = get_post_field( 'post_author', $coupon_id );

        if ( ! $vendor_id ) {
            return;
        }

        $vendor_store_name = get_user_meta( $vendor_id, 'pv_shop_name', true );
        $vendor_store_link = WCV_Vendors::get_vendor_shop_page( $vendor_id );

        require apply_filters(
            'wcvendors_pro_shop_coupon_admin_column_path',
            'partials/shop_coupon/html-admin-shop-coupon-column.php'
        );
    }

    /**
     * Add custom bulk actions
     *
     * @param array $actions The current bulk actions.
     * @return array
     * @version 1.8.5
     * @since   1.8.5
     */
    public function bulk_edit_actions( $actions ) {
        /**
         * Filter to modify admin coupon quick edit screens.
         *
         * @version 1.8.5
         * @since   1.8.5
         * @return array
         */
        return apply_filters( 'wcvendors_pro_admin_coupons_bulk_edit_actions', $actions );
    }

    /**
     * Handle bulk and quick edit actions.
     *
     * @param int     $post_id The ID of the coupon.
     * @param WP_Post $post    The post.
     * @return void
     */
    public function bulk_and_quick_edit_actions( $post_id, $post ) {
        remove_action( 'save_post_shop_coupon', array( $this, 'bulk_and_quick_edit_actions' ), 11, 2 );
        do_action( 'wcvendors_pro_bulk_and_quick_edit_save_coupons', $post_id, $post );
        add_action( 'save_post_shop_coupon', array( $this, 'bulk_and_quick_edit_actions' ), 11, 2 );
    }

    /**
     * Filter vendor products in coupon.
     *
     * @return void
     * @version 1.8.5
     * @since   1.8.5
     */
    public function filter_vendor_coupon_products() {
        if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['security'] ) ), 'filter-vendor-coupon-products' ) ) {
            wp_send_json_error(
                array(
                    'message' => __( 'Please provide a vendor to assign to the coupon', 'wcvendors-pro' ),
                    'nonce'   => wp_create_nonce( 'filter-vendor-coupon-products' ),
                )
            );
            exit;
        }

        $vendor_id = isset( $_POST['vendor_id'] ) ? sanitize_text_field( wp_unslash( $_POST['vendor_id'] ) ) : 0;
        $coupon_id = isset( $_POST['coupon_id'] ) ? sanitize_text_field( wp_unslash( $_POST['coupon_id'] ) ) : 0;

        if ( ! $vendor_id ) {
            wp_send_json_error(
                array(
                    'message' => __( 'Please provide a vendor to assign to the coupon', 'wcvendors-pro' ),
                    'nonce'   => wp_create_nonce( 'filter-vendor-coupon-products' ),
                )
            );
            exit;
        }

        if ( ! $coupon_id ) {
            wp_send_json_error(
                array(
                    'message' => __( 'No coupon id was provided on the request', 'wcvendors-pro' ),
                    'nonce'   => wp_create_nonce( 'filter-vendor-coupon-products' ),
                )
            );
            exit;
        }

        $coupon         = new WC_Coupon( $coupon_id );
        $product_ids    = $coupon->get_product_ids();
        $excluded_ids   = $coupon->get_excluded_product_ids();
        $products_posts = array();
        $excluded_posts = array();
        if ( ! empty( $product_ids ) ) {
            $products_posts = get_posts(
                array(
                    'include'   => $product_ids,
                    'post_type' => 'product',
                )
            );
        }

        if ( ! empty( $excluded_ids ) ) {
            $excluded_posts = get_posts(
                array(
                    'include'   => $excluded_ids,
                    'post_type' => 'product',
                )
            );
        }

        $products_posts = array_filter( $products_posts );
        $excluded_posts = array_filter( $excluded_posts );

        if ( empty( $products_posts ) && empty( $excluded_posts ) ) {
            wp_send_json_success( array(), 404 );
            exit;
        }

        $coupon_products = array();
        foreach ( $products_posts as $vendor_post ) {
            if ( $vendor_post->post_author === $vendor_id ) {
                $coupon_products[ $vendor_post->ID ] = array(
                    'id'    => $vendor_post->ID,
                    'title' => $vendor_post->post_title,
                );
            }
        }

        $excluded_products = array();
        foreach ( $excluded_posts as $vendor_post ) {
            if ( $vendor_post->post_author === $vendor_id ) {
                $excluded_products[ $vendor_post->ID ] = array(
                    'id'    => $vendor_post->ID,
                    'title' => $vendor_post->post_title,
                );
            }
        }

        $response = array(
            'coupon_products'   => $coupon_products,
            'excluded_products' => $excluded_products,
            'nonce'             => wp_create_nonce( 'filter-vendor-coupon-products' ),
        );

        wp_send_json_success( $response, 200 );
        exit;
    }

    /**
     * Check if coupon is valid for product.
     *
     * @param bool       $valid Whether coupon is valid or not.
     * @param WC_Product $product The product.
     * @param WC_Coupon  $coupon The coupon.
     * @param array      $values The values.
     * @return boolean
     * @version 1.8.5
     * @since   1.8.5
     */
    public function is_coupon_valid_for_product( $valid, $product, $coupon, $values ) {
        $coupon_vendor  = get_post_field( 'post_author', $coupon->get_id() );
        $parent_id      = $product->get_parent_id();
        $product_id     = 0 < $parent_id ? $parent_id : $product->get_id();
        $product_vendor = get_post_field( 'post_author', $product_id );

        $valid        = $coupon_vendor === $product_vendor || user_can( $coupon_vendor, 'manage_options' ) ? true : false;
        $excluded_ids = $coupon->get_excluded_product_ids();
        if ( in_array( $product_id, $excluded_ids, true ) ) {
            $valid = false;
        }
        return apply_filters( 'wcvendors_pro_is_coupon_valid_for_product', $valid, $product, $coupon, $values );
    }

    /**
     * Check coupon author in the coupon edit screen.
     */
    public function check_single_coupon_author_edit_screen() {
        $post_id = isset( $_GET['post'] ) ? wp_unslash( $_GET['post'] ) : false; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        $action  = isset( $_GET['action'] ) ? wp_unslash( $_GET['action'] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        if ( ! $post_id || empty( $action ) ) {
            return;
        }
        $post_type = get_post_type( $post_id );

        if ( 'shop_coupon' !== $post_type ) {
            return;
        }

        $post_author = get_post_field( 'post_author', $post_id );
        if ( ! $post_author || empty( $post_author ) ) {
            return;
        }
        $admin_users = get_users(
            array(
                'role'    => 'administrator',
                'fields'  => 'ID',
                'orderby' => 'ID',
            )
        );

        $admin_users = array_map( 'intval', $admin_users );

        if ( 0 !== $post_author && ( in_array( (int) $post_author, $admin_users, true ) || WCV_Vendors::is_vendor( $post_author ) ) ) {
            return;
        }

        $arg = array(
            'ID'          => $post_id,
            'post_author' => get_current_user_id(),
        );
        wp_update_post( $arg );
        printf(
            '<div class="updated notice dissmissable"><p>%s</p></div>',
            esc_html__( 'The author of the coupon is incorrect. So, it was automatically assigned to the administrator.', 'wcvendors-pro' )
        );
    }
}
