<?php
/**
 * Leave requests list table.
 *
 * @package MerchantKits\AttendanceManager
 */

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

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

/**
 * Renders the leave requests admin list with filters, sorting, and bulk actions.
 */
class MKAM_Admin_Leaves_Table extends WP_List_Table {

	/**
	 * Total items for pagination.
	 *
	 * @var int
	 */
	private $total_items = 0;

	/**
	 * Cache of employee rows keyed by ID.
	 *
	 * @var array
	 */
	private $employee_cache = array();

	/**
	 * Set up the table.
	 */
	public function __construct() {
		parent::__construct(
			array(
				'singular' => 'leave',
				'plural'   => 'leaves',
				'ajax'     => false,
			)
		);
	}

	/**
	 * Define columns.
	 *
	 * @return array
	 */
	public function get_columns() {
		return array(
			'cb'         => '<input type="checkbox" />',
			'employee'   => __( 'Employee', 'merchantkits-attendance-manager' ),
			'leave_type' => __( 'Leave Type', 'merchantkits-attendance-manager' ),
			'start_date' => __( 'From', 'merchantkits-attendance-manager' ),
			'end_date'   => __( 'To', 'merchantkits-attendance-manager' ),
			'total_days' => __( 'Days', 'merchantkits-attendance-manager' ),
			'status'     => __( 'Status', 'merchantkits-attendance-manager' ),
			'created_at' => __( 'Applied On', 'merchantkits-attendance-manager' ),
		);
	}

	/**
	 * Sortable columns.
	 *
	 * @return array
	 */
	public function get_sortable_columns() {
		return array(
			'created_at' => array( 'created_at', true ),
			'employee'   => array( 'employee_id', false ),
			'status'     => array( 'status', false ),
			'total_days' => array( 'total_days', false ),
			'start_date' => array( 'start_date', false ),
		);
	}

	/**
	 * Bulk actions.
	 *
	 * @return array
	 */
	public function get_bulk_actions() {
		return array(
			'approve' => __( 'Approve', 'merchantkits-attendance-manager' ),
			'reject'  => __( 'Reject', 'merchantkits-attendance-manager' ),
			'delete'  => __( 'Delete', 'merchantkits-attendance-manager' ),
			'export'  => __( 'Export CSV', 'merchantkits-attendance-manager' ),
		);
	}

	/**
	 * Checkbox column.
	 *
	 * @param array $item Row.
	 * @return string
	 */
	public function column_cb( $item ) {
		return sprintf( '<input type="checkbox" name="leave[]" value="%d" />', absint( $item['id'] ) );
	}

	/**
	 * Highlight pending rows.
	 *
	 * @param array $item Row.
	 * @return void
	 */
	public function single_row( $item ) {
		$class = ( 'pending' === $item['status'] ) ? ' class="mkam-row-pending"' : '';
		echo '<tr' . $class . '>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		$this->single_row_columns( $item );
		echo '</tr>';
	}

	/**
	 * Resolve and cache an employee display name.
	 *
	 * @param int $employee_id Employee ID.
	 * @return string
	 */
	private function employee_name( $employee_id ) {
		$employee_id = absint( $employee_id );

		if ( ! isset( $this->employee_cache[ $employee_id ] ) ) {
			$this->employee_cache[ $employee_id ] = MKAM_Employee::get( $employee_id );
		}

		$employee = $this->employee_cache[ $employee_id ];

		return $employee ? MKAM_Employee::full_name( $employee ) : __( '(deleted)', 'merchantkits-attendance-manager' );
	}

	/**
	 * Employee column with row actions.
	 *
	 * @param array $item Row.
	 * @return string
	 */
	public function column_employee( $item ) {
		$view_url = add_query_arg(
			array(
				'page'   => 'mkam-leaves',
				'action' => 'view',
				'id'     => absint( $item['id'] ),
			),
			admin_url( 'admin.php' )
		);

		$approve_url = wp_nonce_url(
			add_query_arg(
				array(
					'page'   => 'mkam-leaves',
					'action' => 'approve',
					'id'     => absint( $item['id'] ),
				),
				admin_url( 'admin.php' )
			),
			'mkam_leave_approve_' . $item['id']
		);

		$reject_url = wp_nonce_url(
			add_query_arg(
				array(
					'page'   => 'mkam-leaves',
					'action' => 'reject',
					'id'     => absint( $item['id'] ),
				),
				admin_url( 'admin.php' )
			),
			'mkam_leave_reject_' . $item['id']
		);

		$delete_url = wp_nonce_url(
			add_query_arg(
				array(
					'page'   => 'mkam-leaves',
					'action' => 'delete',
					'id'     => absint( $item['id'] ),
				),
				admin_url( 'admin.php' )
			),
			'mkam_leave_delete_' . $item['id']
		);

		$actions = array(
			'view' => sprintf( '<a href="%s">%s</a>', esc_url( $view_url ), esc_html__( 'View', 'merchantkits-attendance-manager' ) ),
		);

		if ( 'pending' === $item['status'] ) {
			$actions['approve'] = sprintf( '<a href="%s">%s</a>', esc_url( $approve_url ), esc_html__( 'Approve', 'merchantkits-attendance-manager' ) );
			$actions['reject']  = sprintf( '<a href="%s">%s</a>', esc_url( $reject_url ), esc_html__( 'Reject', 'merchantkits-attendance-manager' ) );
		}

		$actions['delete'] = sprintf(
			'<a href="%s" onclick="return confirm(\'%s\');">%s</a>',
			esc_url( $delete_url ),
			esc_js( __( 'Delete this request?', 'merchantkits-attendance-manager' ) ),
			esc_html__( 'Delete', 'merchantkits-attendance-manager' )
		);

		return sprintf(
			'<strong><a href="%s">%s</a></strong>%s',
			esc_url( $view_url ),
			esc_html( $this->employee_name( $item['employee_id'] ) ),
			$this->row_actions( $actions )
		);
	}

	/**
	 * Leave type column with policy label.
	 *
	 * @param array $item Row.
	 * @return string
	 */
	public function column_leave_type( $item ) {
		$policy = MKAM_Leave::get_policy( $item['leave_type'] );
		$label  = $policy ? $policy['label'] : ucwords( str_replace( '_', ' ', $item['leave_type'] ) );

		return esc_html( $label );
	}

	/**
	 * Status column with pill.
	 *
	 * @param array $item Row.
	 * @return string
	 */
	public function column_status( $item ) {
		return sprintf(
			'<span class="mkam-badge mkam-badge--%s">%s</span>',
			esc_attr( $item['status'] ),
			esc_html( ucwords( $item['status'] ) )
		);
	}

	/**
	 * Applied-on column.
	 *
	 * @param array $item Row.
	 * @return string
	 */
	public function column_created_at( $item ) {
		return esc_html( mysql2date( get_option( 'date_format', 'Y-m-d' ), $item['created_at'] ) );
	}

	/**
	 * Default column rendering.
	 *
	 * @param array  $item        Row.
	 * @param string $column_name Column key.
	 * @return string
	 */
	public function column_default( $item, $column_name ) {
		$value = isset( $item[ $column_name ] ) ? $item[ $column_name ] : '';
		return esc_html( $value );
	}

	/**
	 * Empty-state message.
	 *
	 * @return void
	 */
	public function no_items() {
		esc_html_e( 'No leave requests found.', 'merchantkits-attendance-manager' );
	}

	/**
	 * Status / leave-type / date filters.
	 *
	 * @param string $which Top or bottom.
	 * @return void
	 */
	protected function extra_tablenav( $which ) {
		if ( 'top' !== $which ) {
			return;
		}

		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$status = isset( $_REQUEST['status_filter'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['status_filter'] ) ) : '';
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$type = isset( $_REQUEST['type_filter'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['type_filter'] ) ) : '';

		echo '<div class="alignleft actions">';

		echo '<select name="status_filter">';
		echo '<option value="">' . esc_html__( 'All statuses', 'merchantkits-attendance-manager' ) . '</option>';
		foreach ( MKAM_Leave::STATUSES as $value ) {
			printf(
				'<option value="%s" %s>%s</option>',
				esc_attr( $value ),
				selected( $status, $value, false ),
				esc_html( ucwords( $value ) )
			);
		}
		echo '</select> ';

		echo '<select name="type_filter">';
		echo '<option value="">' . esc_html__( 'All leave types', 'merchantkits-attendance-manager' ) . '</option>';
		foreach ( MKAM_Leave::get_policies() as $policy ) {
			printf(
				'<option value="%s" %s>%s</option>',
				esc_attr( $policy['leave_type'] ),
				selected( $type, $policy['leave_type'], false ),
				esc_html( $policy['label'] )
			);
		}
		echo '</select> ';

		submit_button( __( 'Filter', 'merchantkits-attendance-manager' ), '', 'filter_action', false );
		echo '</div>';
	}

	/**
	 * Prepare items.
	 *
	 * @return void
	 */
	public function prepare_items() {
		$per_page = (int) get_option( 'mkam_items_per_page', 20 );
		$paged    = $this->get_pagenum();

		$this->_column_headers = array(
			$this->get_columns(),
			array(),
			$this->get_sortable_columns(),
		);

		$this->process_bulk_action();

		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$employee_id = isset( $_REQUEST['employee_id'] ) ? absint( $_REQUEST['employee_id'] ) : 0;
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$status = isset( $_REQUEST['status_filter'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['status_filter'] ) ) : '';
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$type = isset( $_REQUEST['type_filter'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['type_filter'] ) ) : '';
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$orderby = isset( $_REQUEST['orderby'] ) ? sanitize_key( wp_unslash( $_REQUEST['orderby'] ) ) : 'created_at';
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$order = isset( $_REQUEST['order'] ) ? sanitize_key( wp_unslash( $_REQUEST['order'] ) ) : 'desc';

		$args = array(
			'employee_id' => $employee_id,
			'status'      => $status,
			'leave_type'  => $type,
			'orderby'     => $orderby,
			'order'       => $order,
			'per_page'    => $per_page,
			'page'        => $paged,
		);

		$all               = MKAM_Leave::query( array_merge( $args, array( 'per_page' => 0 ) ) );
		$this->total_items = count( $all );
		$this->items       = MKAM_Leave::query( $args );

		$this->set_pagination_args(
			array(
				'total_items' => $this->total_items,
				'per_page'    => $per_page,
				'total_pages' => (int) ceil( $this->total_items / max( 1, $per_page ) ),
			)
		);
	}

	/**
	 * Handle bulk actions.
	 *
	 * @return void
	 */
	public function process_bulk_action() {
		$action = $this->current_action();

		if ( ! $action ) {
			return;
		}

		check_admin_referer( 'bulk-' . $this->_args['plural'] );

		if ( ! current_user_can( MKAM_Core::admin_capability() ) ) {
			return;
		}

		$user_id = get_current_user_id();

		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$ids = isset( $_REQUEST['leave'] ) ? array_map( 'absint', (array) wp_unslash( $_REQUEST['leave'] ) ) : array();

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

		switch ( $action ) {
			case 'approve':
				foreach ( $ids as $id ) {
					MKAM_Leave::approve( $id, $user_id );
				}
				break;

			case 'reject':
				foreach ( $ids as $id ) {
					MKAM_Leave::reject( $id, $user_id );
				}
				break;

			case 'delete':
				foreach ( $ids as $id ) {
					MKAM_Leave::delete( $id );
				}
				break;

			case 'export':
				if ( class_exists( 'MKAM_Export' ) ) {
					$export = new MKAM_Export();
					$export->leaves_csv( array( 'ids' => $ids ) );
				}
				break;
		}
	}
}
