<?php

if ( ! class_exists( 'WP_List_Table' ) ) {
    require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
}

/**
 * The WCVendors Pro Rating Admin Table Class
 *
 * This class outputs the ratings table in the admin dashboard
 *
 * @since      1.0.0
 * @package    WCVendors_Pro
 * @subpackage WCVendors_Pro/includes
 * @author     Jamie Madden <support@wcvendors.com>
 */
class WCVendors_Pro_Ratings_Admin_Table extends WP_List_Table {

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

    /**
     * The version of this plugin.
     *
     * @since    1.0.0
     * @access   private
     * @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
     * @access   private
     * @var      string $base_dir string path for the plugin directory
     */
    private $base_dir;

    /**
     * Is the ratings table name
     *
     * @since    1.0.0
     * @access   private
     * @var      string $table_name name of the ratings table
     */
    public $table_name;

    /**
     * Constructor.
     *
     * @param string $wcvendors_pro The plugin name.
     * @param string $version       The plugin version.
     * @param bool   $debug         Debug mode flag.
     * @param string $table_name    The table name.
     *
     * @since 1.0.0
     */
    public function __construct( $wcvendors_pro, $version, $debug, $table_name ) {

        global $wpdb;

        parent::__construct(
            array(
                'singular' => 'vendor_rating', // Singular label.
                'plural'   => 'vendor_ratings', // Plural label, also this well be one of the table css class.
                'ajax'     => false, // We won't support Ajax for this table.
            )
        );

        $this->wcvendors_pro = $wcvendors_pro;
        $this->version       = $version;
        $this->debug         = $debug;
        $this->base_dir      = plugin_dir_path( __DIR__ );
        $this->table_name    = $wpdb->prefix . 'wcv_feedback';

        add_filter( 'init', array( $this, 'vendor_rating_actions' ) );
    }

    /**
     * Get the table columns.
     *
     * @return array List of columns.
     *
     * @since 1.0.0
     */
    public function get_columns() {
        $columns = array(
            'cb'           => '<input type="checkbox" />',
            'order_id'     => __( 'Order #', 'wcvendors-pro' ),
            'rating_title' => __( 'Title', 'wcvendors-pro' ),
            '_vendor_id'   => wcv_get_vendor_name(),
            'product_id'   => __( 'Product', 'wcvendors-pro' ),
            'customer_id'  => __( 'Customer', 'wcvendors-pro' ),
            'comments'     => __( 'Comments', 'wcvendors-pro' ),
            'rating'       => __( 'Rating', 'wcvendors-pro' ),
            'postdate'     => __( 'Date', 'wcvendors-pro' ),
        );

        return $columns;
    }

    /**
     * Get the sortable columns.
     *
     * @return array List of sortable columns.
     *
     * @since 1.0.0
     */
    public function get_sortable_columns() {
        $sortable_columns = array(
            '_vendor_id' => array( '_vendor_id', false ),
            'product_id' => array( 'product_id', false ),
            'order_id'   => array( 'order_id', false ),
            'postdate'   => array( 'postdate', false ),
        );

        return $sortable_columns;
    }

    /**
     * Return the column check box.
     *
     * @param object $item The rating item.
     *
     * @return string The checkbox HTML.
     *
     * @since 1.0.0
     */
    public function column_cb( $item ) {
        return sprintf(
            '<input type="checkbox" name="%1$s[]" value="%2$s" />',
            /*$1%s*/
            'wcv_vendor_rating_id',
            /*$2%s*/
            $item->id
        );
    }

    /**
     * Render a column when no column specific method exist.
     *
     * @param object $item        The rating item.
     * @param string $column_name The column name.
     *
     * @return string The column HTML.
     *
     * @since 1.0.0
     */
    public function column_default( $item, $column_name ) {

        switch ( $column_name ) {
            case 'id':
                return $item->id;

            case '_vendor_id':
                $user = get_userdata( stripslashes( $item->vendor_id ) );
                $link = '<a href="' . admin_url( 'user-edit.php?user_id=' . stripslashes( $item->vendor_id ) ) . '">' . WCV_Vendors::get_vendor_shop_name( stripslashes( $item->vendor_id ) ) . '</a>';
                return $link;

            case 'product_id':
                $product_title = get_the_title( stripslashes( $item->product_id ) );
                // Handle deleted products gracefully.
                if ( empty( $product_title ) ) {
                    return __( 'Deleted Product', 'wcvendors-pro' );
                }
                $link = '<a href="' . admin_url( 'post.php?post=' . stripslashes( $item->product_id ) . '&action=edit' ) . '">' . $product_title . '</a>';
                return $link;

            case 'order_id':
                $link = '<a href="' . admin_url( 'post.php?post=' . stripslashes( $item->order_id ) . '&action=edit' ) . '">' . stripslashes( $item->order_id ) . '</a>';
                return $link;

            case 'customer_id':
                $user = get_userdata( stripslashes( $item->customer_id ) );
                // Handle deleted customers gracefully.
                if ( ! $user || empty( $user->display_name ) ) {
                    return __( 'Unknown Customer', 'wcvendors-pro' );
                }
                $link = '<a href="' . admin_url( 'user-edit.php?user_id=' . stripslashes( $item->customer_id ) ) . '">' . $user->display_name . '</a>';
                return $link;

            case 'rating_title':
                return stripslashes( $item->rating_title );

            case 'comments':
                return stripslashes( $item->comments );

            case 'rating':
                $rating       = '';
                $rating_value = stripslashes( $item->rating );
                $rating_max   = 5;

                for ( $i = 1; $i <= $rating_value; $i++ ) {
                    $rating .= '<svg class="wcv-icon wcv-icon-sm">
								<use xlink:href="' . WCV_PRO_PUBLIC_ASSETS_URL . 'svg/wcv-icons.svg#wcv-icon-star"></use>
							</svg>';
                }

                for ( $i = $rating_value; $i < $rating_max; $i++ ) {
                    $rating .= '<svg class="wcv-icon wcv-icon-sm">
									<use xlink:href="' . WCV_PRO_PUBLIC_ASSETS_URL . 'svg/wcv-icons.svg#wcv-icon-star-o"></use>
								</svg>';
                }

                return $rating;

            case 'postdate':
                return date_i18n( get_option( 'date_format' ), strtotime( $item->postdate ) );

            default:
                return '';
        }
    }

    /**
     * Get the bulk actions
     *
     * @since 1.0.0
     *
     * @return array $actions available bulk actions
     */
    public function get_bulk_actions() {
        $actions = array(
            'delete_ratings' => __( 'Delete', 'wcvendors-pro' ),
        );

        return $actions;
    }

    /**
     * Process the bulk actions for the table
     *
     * @since 1.0.0
     */
    public function process_bulk_action() {

        if ( 'delete_ratings' === $this->current_action() ) {

            $id = $_REQUEST['wcv_vendor_rating_id']; // phpcs:ignore WordPress.Security.NonceVerification.Recommended

            $result = $this->delete_ratings( $id );

            if ( $result ) {
                // translators: %s is the vendor name.
                echo '<div class="updated"><p>' . sprintf( esc_html__( '%s rating(s) deleted.', 'wcvendors-pro' ), esc_html( wcv_get_vendor_name() ) ) . '</p></div>';
            }
        }
    }

    /**
     * Display the feedback edit form.
     *
     * @param object $feedback The feedback to edit.
     *
     * @since 1.0.0
     */
    public function display_edit_form( $feedback ) {

        include apply_filters( 'wcvendors_pro_display_edit_form_path', 'partials/ratings/admin/wcvendors-pro-ratings-feedback-form.php' );
    }

    /**
     * Add the screen options to the table
     *
     * @since 1.0.0
     */
    public static function add_options() {

        $option = 'per_page';

        $args = array(
            // translators: %s is the vendor name.
            'label'   => sprintf( __( '%s ratings', 'wcvendors-pro' ), wcv_get_vendor_name() ),
            'default' => 20,
            'option'  => 'ratings_per_page',
        );

        add_screen_option( $option, $args );
    }

    /**
     * Column rating_title actions single edit/delete functions.
     *
     * @param object $item The item data.
     *
     * @return string HTML output.
     *
     * @since 1.0.0
     */
    public function column_rating_title( $item ) {
        $actions = array(
            'edit'   => sprintf( '<a href="?page=%s&action=%s&wcv_vendor_rating_id=%s">%s</a>', $_REQUEST['page'], 'edit', $item->id, __( 'Edit', 'wcvendors-pro' ) ), // phpcs:ignore WordPress.Security.NonceVerification.Recommended
            'delete' => sprintf( '<a href="?page=%s&action=%s&wcv_vendor_rating_id=%s">%s</a>', $_REQUEST['page'], 'delete', $item->id, __( 'Delete', 'wcvendors-pro' ) ), // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        );

        return sprintf( '%1$s %2$s', $item->rating_title, $this->row_actions( $actions ) );
    }

    /**
     * Prepare the items for display
     *
     * @since 1.0.0
     */
    public function prepare_items() {

        $screen                            = get_current_screen();
        $hidden                            = array();
        $sortable                          = $this->get_sortable_columns();
        $columns                           = $this->get_columns();
        $this->_column_headers             = array( $columns, $hidden, $sortable );
        $_wp_column_headers[ $screen->id ] = $columns;

        /** Process bulk action */
        $this->process_bulk_action();

        $per_page     = $this->get_items_per_page( 'ratings_per_page', 10 );
        $current_page = $this->get_pagenum();
        $total_items  = self::count_feedback();

        $this->set_pagination_args(
            array(
                'total_items' => $total_items,
                'per_page'    => $per_page,
            )
        );

        $this->items = self::get_feedback( $per_page, $current_page );
    }

    /**
     * Retrieve feedback data from the database.
     *
     * @param int $per_page    Number of items per page.
     * @param int $page_number Current page number.
     *
     * @since 1.0.0
     *
     * @return array Array of feedback objects.
     */
    public function get_feedback( $per_page = 5, $page_number = 1 ) {

        global $wpdb;

        $per_page    = absint( $per_page );
        $page_number = absint( $page_number );
        $offset      = ( $page_number - 1 ) * $per_page;

        $orderby = 'postdate';
        $order   = 'DESC';

        if ( ! empty( $_REQUEST['orderby'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
            $orderby = sanitize_sql_orderby( $_REQUEST['orderby'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        }

        if ( ! empty( $_REQUEST['order'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
            $order = strtoupper( $_REQUEST['order'] ) === 'ASC' ? 'ASC' : 'DESC'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        }

        $result = $wpdb->get_results(
            $wpdb->prepare(
                "SELECT *, vendor_id AS _vendor_id FROM {$wpdb->prefix}wcv_feedback ORDER BY {$orderby} {$order} LIMIT %d OFFSET %d", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
                $per_page,
                $offset
            )
        );

        return $result;
    }

    /**
     * Returns the count of feedback in the database.
     *
     * @return int Number of feedback entries.
     *
     * @since 1.0.0
     */
    public static function count_feedback() {
        global $wpdb;

        return (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}wcv_feedback" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
    }

    /**
     * Update a specific rating.
     *
     * @param array $feedback The feedback post array.
     *
     * @return int|false The number of rows updated, or false on error.
     *
     * @since 1.0.0
     */
    public function update_rating( $feedback ) {

        global $wpdb;

        $result = $wpdb->update(
            $this->table_name,
            array(
                'comments'     => esc_html( $feedback['rating_comments'] ),
                'rating_title' => esc_html( $feedback['rating_title'] ),
            ),
            array( 'id' => $feedback['id'] ),
            array(
                '%s',
                '%s',
            )
        );

        return $result;
    }

    /**
     * Delete the ratings by IDs.
     *
     * @param array|int $ids The feedback IDs to delete.
     *
     * @return int|false The number of rows deleted, or false on error.
     *
     * @since 1.0.0
     */
    public function delete_ratings( $ids ) {

        global $wpdb;

        // Convert to an array to process multiple results if required.
        $ids = ( is_array( $ids ) ) ? $ids : array( $ids );

        foreach ( $ids as $id ) {
            $id     = absint( $id );
            $result = $wpdb->query( $wpdb->prepare( "DELETE FROM {$this->table_name} WHERE id = %d", $id ) ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
        }

        return $result;
    }

    /**
     * Display if no ratings found.
     *
     * @since 1.0.0
     */
    public function no_items() {
        // translators: %s is the vendor name.
        printf( esc_html__( 'No %s ratings found.', 'wcvendors-pro' ), esc_html( wcv_get_vendor_name( true, false ) ) );
    }
}
