<?php
declare(strict_types=1);

namespace EHxMe\Classes;

use EHxMe\Helpers\Helper;
use EHxMe\Services\Request;
use WP_List_Table;
use WP_User_Query;

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

class MemberDataTable extends WP_List_Table 
{
    /**
     * Constructor for the MemberDataTable class.
     *
     * Initializes the parent class and sets up the necessary properties.
     *
     * @param array $args Arguments for the WP_List_Table class constructor.
     */
    public function __construct() 
    {
        parent::__construct([
            'singular' => esc_html__('Member', 'ehx-members'),
            'plural'   => esc_html__('Members', 'ehx-members'),
            'ajax'     => false
        ]);
    }

    /**
     * Get the columns for the list table.
     *
     * @return array An associative array where the keys are the column slugs and the values are the column names.
     */
    public function get_columns() 
    {
        return [
            'cb'       => '<input type="checkbox" />',
            'username' => esc_html__('Username', 'ehx-members'),
            'name'     => esc_html__('Name', 'ehx-members'),
            'email'    => esc_html__('Email', 'ehx-members'),
            'user_status' => esc_html__('Status', 'ehx-members'),
            'role'   => esc_html__('Role', 'ehx-members') // Add a custom column
        ];
    }

    /**
     * Get the sortable columns for the list table.
     *
     * @return array An associative array where the keys are the column slugs and the values are arrays containing the column name and a boolean indicating whether the column is sortable.
     *
     * @since 1.0.0
     */
    public function get_sortable_columns() 
    {
        return [
            'username' => ['username', false],
            'email'    => ['email', false],
            'user_status' => ['status', false],
            'role'     => ['role', false],
        ];
    }

    /**
     * Handles the output for the extra navigation bar at the top of the list table.
     *
     * This function generates the HTML for the extra navigation bar at the top of the list table.
     * It includes dropdown filters for users and payment statuses.
     *
     * @param string $which The context for the extra table navigation.
     *                      It can be either 'top' or 'bottom'.
     *
     * @return void
     */
    public function extra_tablenav($which) 
    {
        if ($which == "top") {
            $roles = wp_roles()->roles;
            $current_role = Request::getInput('role_filter', '');
            
            ?>
                <div class="alignleft actions">
                    <input type="hidden" name="page" value="<?php echo esc_html(AdminMenuHandler::$pages['member']); ?>">
                    
                    <input type="hidden" name="<?php echo esc_html(Helper::NONCE_NAME) ?>" value="<?php echo esc_html(wp_create_nonce(Helper::NONCE_NAME)) ?>">

                    <select name="role_filter">
                        <option value=""><?php esc_html_e('All Roles', 'ehx-members') ?></option>
                        <?php foreach ($roles as $role_key => $role) : ?>
                            <option value="<?php echo esc_attr($role_key); ?>" <?php selected($current_role, $role_key, false); ?>>
                                <?php echo esc_html($role['name']); ?>
                            </option>
                        <?php endforeach; ?>
                    </select>
                    <input type="submit" class="button" value="Filter">
                </div>
            <?php
        }
    }

    /**
     * Prepares the items to be displayed in the list table.
     *
     * This function retrieves the necessary data from the database, applies filters and sorting,
     * and sets up pagination for the list table. It then populates the items property with the
     * retrieved data.
     *
     * @return void
     */
    public function prepare_items() 
    {
        global $wpdb;

        $this->process_bulk_action();

        // Get search term
        $search_term = Request::getInput('s', '');

        // Get custom roles
        $customRoles = array_keys(Helper::customRoles());

        // Pagination parameters
        $per_page = $this->get_items_per_page('users_per_page', 10); // 20 items per page
        $current_page = $this->get_pagenum();
        $offset = ($current_page - 1) * $per_page;

        // Base query args
        $args = [
            'orderby'   => 'user_registered',
            'order'     => 'DESC',
            'fields'    => ['ID', 'user_login', 'user_email', 'user_registered', 'display_name', 'user_status'],
            'search'    => '*' . esc_attr($search_term) . '*',
            'number'    => $per_page, // Items per page
            'offset'    => $offset,   // Skip previous pages
            'meta_query' => [
                'relation' => 'OR',
                [
                    'key'     => $wpdb->prefix . 'capabilities',
                    'value'   => $customRoles[0] ?? 'free_member',
                    'compare' => 'LIKE'
                ],
                [
                    'key'     => $wpdb->prefix . 'capabilities',
                    'value'   => $customRoles[1] ?? 'paid_member',
                    'compare' => 'LIKE'
                ]
            ]
        ];

        // Get users for current page
        $user_query = new WP_User_Query($args);
        $users = $user_query->get_results();
        
        // Get total count without pagination for pagination math
        $total_args = $args;
        unset($total_args['number'], $total_args['offset']);
        $total_query = new WP_User_Query($total_args);
        $total_items = $total_query->get_total();

        // Prepare data array
        $data = [];
        foreach ($users as $user) {
            $user_data = get_userdata($user->ID);
            $data[] = [
                'ID'          => $user->ID,
                'username'    => $user->user_login,
                'name'        => $user->display_name,
                'email'       => $user->user_email,
                'roles'       => $user_data->roles,
                'user_status' => (bool) $user->user_status,
            ];
        }

        // Set pagination
        $this->set_pagination_args([
            'total_items' => $total_items,
            'per_page'    => $per_page,
            'total_pages' => ceil($total_items / $per_page)
        ]);

        // Set column headers
        $columns  = $this->get_columns();
        $hidden   = [];
        $sortable = $this->get_sortable_columns();
        $this->_column_headers = [$columns, $hidden, $sortable];

        // Set items
        $this->items = $data;
    }

    /**
     * Handles the output for the default columns in the list table.
     *
     * This function is called when the default columns are being displayed in the list table.
     * It checks the column name and returns the appropriate value based on the column.
     *
     * @param array $item An associative array representing a single row in the list table.
     *                    The array should contain the column slugs as keys and their corresponding values.
     * @param string $column_name The name of the column being displayed.
     *
     * @return mixed The value to be displayed in the specified column.
     */
    public function column_default($item, $column_name) 
    { 
        $page = AdminMenuHandler::$pages['member'];

        switch ($column_name) {
            case 'username':
                $avatar = get_avatar($item['ID'], 32); // Get user avatar (size: 32px)
                
                $delete_link = Helper::generateQueryArg(['action' => 'ehxme_member_delete', 'page' => $page, 'id' => $item['ID']]);
                $view_link = Helper::generateQueryArg(['page' => AdminMenuHandler::$pages['user_details'], 'user_id' => $item['ID']]);

                $actions = [
                    'edit'   => '<a href="' . esc_url(get_edit_user_link($item['ID'])) . '">Edit</a>',
                    'delete' => '<a href="' . esc_url($delete_link) . '" onclick="return confirm(\'Are you sure?\')">Delete</a>',
                    'view'   => '<a href="' . esc_url($view_link) . '">' . esc_html__('View', 'ehx-members') . '</a>'
                ];

                return '<div style="display:flex; align-items:center; gap:10px;">' . 
                            $avatar . 
                            '<strong>' . esc_html($item['username']) . '</strong>' . 
                    '</div>' . 
                    $this->row_actions($actions);
            case 'email':
                return esc_html($item['email']);
            case 'name':
                return esc_html($item['name']);
            case 'role':
                return Helper::memberRole($item['roles']);
            case 'user_status': 
                $current_status = Helper::memberStatus($item['user_status'], null);
                $status_text = !$current_status ? esc_html__('Deny', 'ehx-members') : esc_html__('Approve', 'ehx-members');
                $toggle_text = !$current_status ? esc_html__('Approve', 'ehx-members') : esc_html__('Deny', 'ehx-members');
                $toggle_status = !$current_status ? esc_html__('Activate', 'ehx-members') : esc_html__('Deactivate', 'ehx-members');
                
                $status_link = Helper::generateQueryArg(['action' => 'ehxme_status_update', 'page' => $page, 'user_id' => $item['ID']]);
                
                $actions[$toggle_status] = '<a href="' . esc_url($status_link) . '">' . esc_html($toggle_text) . '</a>';

                return esc_html($status_text) . $this->row_actions($actions);
    
            default:
                return '';
        }
    }        
    
    /**
     * Generate the checkbox HTML for the list table.
     *
     * This function generates the HTML for a checkbox input element that will be used in the list table.
     * The checkbox is used for selecting multiple items for bulk actions.
     *
     * @param array $item An associative array representing a single row in the list table.
     *                    The array should contain the 'id' key, which corresponds to the transaction ID.
     *
     * @return string The HTML for the checkbox input element.
     */
    public function column_cb($item) 
    {
        return '<input type="checkbox" name="user[]" value="' . $item['ID'] . '" />';
    }
}