<?php
/**
 * The WCVendors Pro Reports Controller class
 *
 * This is the reports controller class for all front end reports
 *
 * @package    WCVendors_Pro
 * @subpackage WCVendors_Pro/public
 * @author     Jamie Madden <support@wcvendors.com>
 */

use WC_Vendors\Classes\Front\WCV_Product_Controller;
use WC_Vendors\Classes\Front\WCV_Reports_Controller;
use WC_Vendors\Classes\Front\WCV_Table_Helper;
use WC_Vendors\Classes\Front\WCV_Vendor_Controller;

/**
 * WCVendors Pro Reports Controller class
 *
 * @version 2.4.8
 * @since   2.4.8 Added HPOS Compatibility
 * @since   1.0.0 - Added.
 */
class WCVendors_Pro_Reports_Controller extends WCV_Reports_Controller { //phpcs:ignore

    /**
     * The ID of this plugin.
     *
     * @since    1.0.0
     * @var      string $wcvendors_pro The ID of this plugin.
     */
    private $wcvendors_pro;

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

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

    /**
     * Is the plugin base directory
     *
     * @since    1.0.0
     * @var      string $base_dir string path for the plugin directory
     */
    private $base_dir;


    /**
     * Initialize the class and set its properties.
     *
     * @since    1.0.0
     *
     * @param      string $wcvendors_pro The name of the plugin.
     * @param      string $version       The version of this plugin.
     * @param      bool   $debug         Whether debug is enabled or not.
     */
    public function __construct( $wcvendors_pro, $version, $debug ) {

        $this->wcvendors_pro = $wcvendors_pro;
        $this->version       = $version;
        $this->debug         = $debug;
        $this->base_dir      = plugin_dir_path( __DIR__ );
        add_action( 'wcvendors_dashboard_product_totals', array( $this, 'product_totals' ) );
        add_action( 'wcvendors_dashboard_overview_recent', array( $this, 'overview_recent' ), 10, 3 );
    }

    /**
     * Product totals
     *
     * @param object $store_report Store report object.
     */
    public function product_totals( $store_report ) {
        wc_get_template(
            'product-totals.php',
            array(
                'store_report' => $store_report,
            ),
            'wc-vendors/dashboard/reports/',
            $this->base_dir . 'templates/dashboard/reports/'
        );
    }

    /**
     * Overview recent
     *
     * @param object $store_report Store report object.
     * @param bool   $products_disabled   Are products disabled.
     * @param boot   $orders_disabled     Are orders disabled.
     */
    public function overview_recent( $store_report, $products_disabled, $orders_disabled ) {
        $products_disabled = wc_string_to_bool( get_option( 'wcvendors_product_management_cap', 'no' ) );
        $orders_disabled   = wc_string_to_bool( get_option( 'wcvendors_order_management_cap', 'no' ) );
        wc_get_template(
            'overview-recent.php',
            array(
                'store_report'      => $store_report,
                'products_disabled' => $products_disabled,
                'orders_disabled'   => $orders_disabled,
                'pro_store_report'  => $this,
            ),
            'wc-vendors/dashboard/reports/',
            $this->base_dir . 'templates/dashboard/reports/'
        );
    }

    /**
     *  Output the recent orders mini table
     *
     * @version 1.7.6
     * @since   1.0.0
     * @return   array  $recent_orders   array of recent orders
     *
     * @param array $orders Orders.
     */
    public function recent_orders_table( $orders = array() ) {
        global $wpdb;
        $shipping_disabled = wc_string_to_bool( get_option( 'wcvendors_shipping_management_cap', 'no' ) );

        // Get the last 10 recent orders.
        $max_orders    = apply_filters( 'wcv_recent_orders_max', 9 );
        $recent_orders = array_splice( $orders, 0, $max_orders );

        if ( empty( $recent_orders ) ) {
            echo '<p>' . esc_html__( 'No Recent Orders found.', 'wcvendors-pro' ) . '</p>'; //phpcs:ignore
            return array();
        }

        $recent_order_ids = array_map(
            function ( $order ) {
                return $order->order_id;
            },
            $recent_orders
        );

        $placeholders = array_fill( 0, count( $recent_order_ids ), '%d' );

        $rows_sql = $wpdb->prepare(
            "SELECT * FROM {$wpdb->prefix}pv_commission WHERE order_id IN (" . implode(',', $placeholders) . ") AND vendor_id = %d", //phpcs:ignore
            array_merge( $recent_order_ids, array( get_current_user_id() ) )
        );

        $commission_rows = $wpdb->get_results( $rows_sql ); //phpcs:ignore

        // Create recent orders table.
        $recent_order_table = new WCV_Table_Helper( $this->wcvendors_pro, $this->version, 'recent_order', null, get_current_user_id() );

        $recent_order_table->container_wrap = false;

        // Set the columns.
        $columns = apply_filters(
            'wcvendors_recent_order_table_columns',
            array(
                'ID'           => __( 'ID', 'wcvendors-pro' ),
                'order_number' => __( 'Order', 'wcvendors-pro' ),
                'product'      => __( 'Products', 'wcvendors-pro' ),
                'totals'       => __( 'Commission', 'wcvendors-pro' ),
                'shipping'     => __( 'Shipping', 'wcvendors-pro' ),
                'commission'   => __( 'Status', 'wcvendors-pro' ),
            )
        );
        $recent_order_table->set_columns( $columns );

        // Set the rows.
        $rows = array();

        if ( ! empty( $recent_orders ) ) {
            foreach ( $recent_orders as $order ) {
                $parent_order    = $order->order->get_parent_order();
                $parent_order_id = $parent_order ? $parent_order->get_id() : $order->order->get_id();
                $order_items     = isset( $order->order_items ) && is_array( $order->order_items ) ? $order->order_items : array();

                if ( empty( $order_items ) || ! $parent_order || ! is_a( $order->order, 'WC_Order_Vendor' ) ) {
                    continue;
                }

                $products_html          = '';
                $commission_total       = '';
                $commission_status_html = '';
                $shipping_html          = '';
                $total_products         = 0;

                // Make sure the order exists before attempting to loop over it.
                $total_products = count( $order_items );

                // Get products to output.
                foreach ( $order_items as $key => $item ) {
                    $item_product_id = $item->get_variation_id() ? $item->get_variation_id() : $item->get_product_id();

                    if ( ! $item_product_id ) {
                        continue;
                    }

                    $status = 'due';

                    $matching_rows = array_values(
                        array_filter(
                            $commission_rows,
                            function ( $row ) use ( $item_product_id, $parent_order_id ) {
                                return (int) $row->product_id === $item_product_id && (int) $row->order_id === $parent_order_id;
                            }
                        )
                    );

                    if ( ! empty( $matching_rows ) ) {
                        $status = array_shift( $matching_rows )->status;
                    }

                    $commission_status_html .= '<strong class="wcv-commission-status ' . esc_attr( $status ) . '">' . esc_html( ucfirst( $status ) ) . '</strong>';
                    // May need to fix for variations.
                    $products_html .= '<strong>' . $item['qty'] . ' x ' . $item['name'] . '</strong>';

                    $commission_total .= isset( $order->product_commissions[ $item_product_id ] )
                        ? wc_price( $order->product_commissions[ $item_product_id ] )
                        : '';

                    if ( $total_products > 1 ) {
                        $products_html          .= '<br />';
                        $commission_status_html .= '<br />';
                        $commission_total       .= '<br />';
                    }
                }

                if ( ! $shipping_disabled ) {
                    $shipping_html .= wc_price( $order->total_shipping );
                }

                $new_row = new stdClass();

                $new_row->ID           = $parent_order->get_id();
                $new_row->order_number = $parent_order->get_order_number() . '<br />' . date_i18n( get_option( 'date_format', 'F j, Y' ), ( $parent_order->get_date_created()->getOffsetTimestamp() ) );
                $new_row->product      = $products_html;
                $new_row->totals       = $commission_total;
                $new_row->shipping     = $shipping_html;
                $new_row->commission   = $commission_status_html;

                $rows[] = $new_row;
            }
        }

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

        $recent_order_table->set_rows( $rows );

        // Disable row actions.
        $recent_order_table->set_actions( array() );

        // display the table.
        $recent_order_table->display();

        return $recent_orders;
    }

    /**
     *  Output the recent products mini table
     *
     * @since    1.0.0
     */
    public function recent_products_table() {

        $args              = array( 'numberposts' => apply_filters( 'wcv_recent_products_max', 5 ) ); //phpcs:ignore
        $recent_products   = WCV_Vendor_Controller::get_products_by_id( get_current_user_id(), $args );
        $products_disabled = wc_string_to_bool( get_option( 'wcvendors_product_management_cap', 'no' ) );
        $can_edit          = wc_string_to_bool( get_option( 'wcvendors_can_edit_published_products', 'no' ) );

        // Create the recent products table.
        $recent_product_table                 = new WCV_Table_Helper( $this->wcvendors_pro, $this->version, 'recent_product', null, get_current_user_id() );
        $recent_product_table->container_wrap = false;

        // Set the columns.
        $columns = apply_filters(
            'wcvendors_recent_product_table_columns',
            array(
                'ID'      => __( 'ID', 'wcvendors-pro' ),
                'tn'      => __( 'Thumbnail', 'wcvendors-pro' ),
                'details' => __( 'Details', 'wcvendors-pro' ),
                'status'  => __( 'Status', 'wcvendors-pro' ),
            )
        );
        $recent_product_table->set_columns( $columns );

        // Set the rows.
        $rows = array();
        $link = '';

        foreach ( $recent_products as $product_id ) {

            $new_row         = new stdClass();
            $product         = wc_get_product( $product_id );
            $vendor_disabled = ( 'yes' === $product->get_meta( '_disable_vendor_edit' ) );

            // Fix link based on template.
            $link          = ( $can_edit ) ? WCV_Product_Controller::get_product_edit_link( $product->get_id() ) : get_permalink( $product->get_id() );
            $link          = ( ! $products_disabled ) ? WCV_Product_Controller::get_product_edit_link( $product->get_id() ) : get_permalink( $product->get_id() );
            $link          = $vendor_disabled ? get_permalink( $product->get_id() ) : $link;
            $post          = get_post( $product->get_id() );
            $product_price = wc_get_price_to_display( $product );

            $target = '_self';
            if ( $products_disabled && wc_string_to_bool( get_option( 'wcvendors_dashboard_view_product_new_window', 'no' ) ) ) {
                $target = '_blank';
            }

            $new_row->ID      = $product->get_id();
            $new_row->tn      = get_the_post_thumbnail( $product->get_id(), array( 50, 50 ) );
            $new_row->details = sprintf( '<a href="%s" target="%s">%s<br />%s%s</a>', $link, $target, $product->get_title(), wc_price( $product_price ), $product->get_price_suffix() );
            $new_row->status  = sprintf( '%s <br /> %s', WCV_Product_Controller::product_status( $post->post_status ), date_i18n( get_option( 'date_format', 'F j, Y' ), strtotime( $post->post_date ) ) );

            $rows[] = $new_row;

        }

        $rows = apply_filters_deprecated(
            'wcv_recent_product_table_rows',
            array( $rows ),
            '1.8.0',
            'wcvendors_recent_product_table_rows'
        );
        $rows = apply_filters( 'wcv_recent_product_table_rows', $rows );

        $recent_product_table->set_rows( $rows );

        // Disable row actions.
        $recent_product_table->set_actions( array() );

        // display the table.
        $recent_product_table->display();

        return $recent_products;
    }

    /**
     *  Change the order text output when there are no rows
     *
     * @since    1.0.0
     *
     * @param     string $notice Notice output.
     *
     * @return   string $notice    filtered text
     */
    public function order_table_no_data_notice( $notice ) {

        $notice = __( 'No Orders found.', 'wcvendors-pro' );

        return $notice;
    }

    /**
     *  Change the product text output when there are no rows
     *
     * @since    1.0.0
     *
     * @param     string $notice Notice output.
     *
     * @return   string $notice    filtered text
     */
    public function product_table_no_data_notice( $notice ) {

        $notice = __( 'No Products found.', 'wcvendors-pro' );

        return $notice;
    }
}
