<?php
/**
 * Attendance log 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 attendance admin list with filters, sorting, and bulk actions.
 */
class MKAM_Admin_Attendance_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' => 'attendance',
				'plural'   => 'attendances',
				'ajax'     => false,
			)
		);
	}

	/**
	 * Define columns.
	 *
	 * @return array
	 */
	public function get_columns() {
		return array(
			'cb'             => '<input type="checkbox" />',
			'employee'       => __( 'Employee', 'merchantkits-attendance-manager' ),
			'date'           => __( 'Date', 'merchantkits-attendance-manager' ),
			'clock_in'       => __( 'Clock In', 'merchantkits-attendance-manager' ),
			'clock_out'      => __( 'Clock Out', 'merchantkits-attendance-manager' ),
			'total_hours'    => __( 'Total Hours', 'merchantkits-attendance-manager' ),
			'overtime_hours' => __( 'Overtime', 'merchantkits-attendance-manager' ),
			'status'         => __( 'Status', 'merchantkits-attendance-manager' ),
			'late_minutes'   => __( 'Late (min)', 'merchantkits-attendance-manager' ),
		);
	}

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

	/**
	 * Bulk actions.
	 *
	 * @return array
	 */
	public function get_bulk_actions() {
		return array(
			'delete'   => __( 'Delete', 'merchantkits-attendance-manager' ),
			'approve'  => __( 'Mark as Approved', '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="attendance[]" value="%d" />', absint( $item['id'] ) );
	}

	/**
	 * 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 detail link.
	 *
	 * @param array $item Row.
	 * @return string
	 */
	public function column_employee( $item ) {
		$detail_url = add_query_arg(
			array(
				'page'   => 'mkam-attendance',
				'action' => 'view',
				'id'     => absint( $item['id'] ),
			),
			admin_url( 'admin.php' )
		);

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

		$actions = array(
			'view'   => sprintf( '<a href="%s">%s</a>', esc_url( $detail_url ), esc_html__( 'View Detail', 'merchantkits-attendance-manager' ) ),
			'delete' => sprintf(
				'<a href="%s" onclick="return confirm(\'%s\');">%s</a>',
				esc_url( $delete_url ),
				esc_js( __( 'Delete this record?', 'merchantkits-attendance-manager' ) ),
				esc_html__( 'Delete', 'merchantkits-attendance-manager' )
			),
		);

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

	/**
	 * Format a datetime cell as a local time string.
	 *
	 * @param string $value MySQL datetime or null.
	 * @return string
	 */
	private function format_time( $value ) {
		if ( empty( $value ) ) {
			return '&mdash;';
		}

		return esc_html( mysql2date( get_option( 'time_format', 'g:i a' ), $value ) );
	}

	/**
	 * Clock-in column.
	 *
	 * @param array $item Row.
	 * @return string
	 */
	public function column_clock_in( $item ) {
		return $this->format_time( $item['clock_in'] );
	}

	/**
	 * Clock-out column.
	 *
	 * @param array $item Row.
	 * @return string
	 */
	public function column_clock_out( $item ) {
		return $this->format_time( $item['clock_out'] );
	}

	/**
	 * 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( str_replace( '_', ' ', $item['status'] ) ) )
		);
	}

	/**
	 * 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 attendance records found.', 'merchantkits-attendance-manager' );
	}

	/**
	 * Date range and status filters.
	 *
	 * @param string $which Top or bottom.
	 * @return void
	 */
	protected function extra_tablenav( $which ) {
		if ( 'top' !== $which ) {
			return;
		}

		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$date_from = isset( $_REQUEST['date_from'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['date_from'] ) ) : gmdate( 'Y-m-01' );
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$date_to = isset( $_REQUEST['date_to'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['date_to'] ) ) : gmdate( 'Y-m-t' );
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$status = isset( $_REQUEST['status_filter'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['status_filter'] ) ) : '';

		echo '<div class="alignleft actions">';
		echo '<input type="date" name="date_from" value="' . esc_attr( $date_from ) . '" /> ';
		echo '<input type="date" name="date_to" value="' . esc_attr( $date_to ) . '" /> ';

		echo '<select name="status_filter">';
		echo '<option value="">' . esc_html__( 'All statuses', 'merchantkits-attendance-manager' ) . '</option>';
		foreach ( MKAM_Attendance::STATUSES as $value ) {
			printf(
				'<option value="%s" %s>%s</option>',
				esc_attr( $value ),
				selected( $status, $value, false ),
				esc_html( ucwords( str_replace( '_', ' ', $value ) ) )
			);
		}
		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
		$date_from = isset( $_REQUEST['date_from'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['date_from'] ) ) : gmdate( 'Y-m-01' );
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$date_to = isset( $_REQUEST['date_to'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['date_to'] ) ) : gmdate( 'Y-m-t' );
		// 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
		$orderby = isset( $_REQUEST['orderby'] ) ? sanitize_key( wp_unslash( $_REQUEST['orderby'] ) ) : 'date';
		// 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,
			'date_from'   => $date_from,
			'date_to'     => $date_to,
			'orderby'     => $orderby,
			'order'       => $order,
			'per_page'    => $per_page,
			'page'        => $paged,
		);

		$all               = MKAM_Attendance::query( array_merge( $args, array( 'per_page' => 0 ) ) );
		$this->total_items = count( $all );
		$this->items       = MKAM_Attendance::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;
		}

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

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

		switch ( $action ) {
			case 'delete':
				foreach ( $ids as $id ) {
					MKAM_Attendance::delete( $id );
				}
				break;

			case 'approve':
				foreach ( $ids as $id ) {
					MKAM_Attendance::update( $id, array( 'approved_by' => get_current_user_id() ) );
				}
				break;

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