<?php
/**
 * Custom Fields field group list table.
 *
 * Uses WordPress WP_List_Table for default admin list styling and row actions.
 *
 * @package CustomFields
 * @since 1.1.0
 */

namespace CustomFields;

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

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

/**
 * List table for field group definitions.
 */
final class FieldGroupListTable extends \WP_List_Table {

	/**
	 * Custom fields admin controller.
	 */
	private Admin $admin;

	/**
	 * Status filter: all, enabled, disabled.
	 */
	private string $status_filter;

	/**
	 * Search query.
	 */
	private string $search_query;

	/**
	 * @param Admin  $admin  Admin controller.
	 * @param string $status Status filter.
	 * @param string $search Search query.
	 */
	public function __construct( Admin $admin, string $status = 'all', string $search = '' ) {
		$this->admin         = $admin;
		$this->status_filter = in_array( $status, [ 'all', 'enabled', 'disabled' ], true ) ? $status : 'all';
		$this->search_query  = $search;

		parent::__construct(
			[
				'singular' => 'field_group',
				'plural'   => 'field_groups',
				'ajax'     => false,
			]
		);
	}

	/**
	 * @return array<string, string>
	 */
	public function get_columns(): array {
		return [
			'cb'       => '<input type="checkbox" />',
			'title'    => __( 'Field Group', 'wppowersuite-lite' ),
			'fields'   => __( 'Fields', 'wppowersuite-lite' ),
			'key'      => __( 'Key', 'wppowersuite-lite' ),
			'status'   => __( 'Status', 'wppowersuite-lite' ),
			'location' => __( 'Location', 'wppowersuite-lite' ),
		];
	}

	/**
	 * @return array<string, array<int, bool|string>>
	 */
	protected function get_sortable_columns(): array {
		return [
			'title'  => [ 'title', false ],
			'key'    => [ 'key', false ],
			'status' => [ 'status', false ],
			'fields' => [ 'fields', false ],
		];
	}

	/**
	 * @return array<string, string>
	 */
	protected function get_bulk_actions(): array {
		return [
			'enable'  => __( 'Enable', 'wppowersuite-lite' ),
			'disable' => __( 'Disable', 'wppowersuite-lite' ),
			'delete'  => __( 'Delete', 'wppowersuite-lite' ),
		];
	}

	public function prepare_items(): void {
		$definitions = $this->admin->getDefinitionsForList();

		if ( $this->status_filter === 'enabled' ) {
			$definitions = array_filter( $definitions, static fn( array $item ): bool => ! empty( $item['definition']['enabled'] ) );
		} elseif ( $this->status_filter === 'disabled' ) {
			$definitions = array_filter( $definitions, static fn( array $item ): bool => empty( $item['definition']['enabled'] ) );
		}

		if ( $this->search_query !== '' ) {
			$search      = strtolower( $this->search_query );
			$definitions = array_filter(
				$definitions,
				static function ( array $item ) use ( $search ): bool {
					$key   = (string) ( $item['key'] ?? '' );
					$title = (string) ( $item['definition']['title'] ?? '' );

					return str_contains( strtolower( $key ), $search )
						|| str_contains( strtolower( $title ), $search );
				}
			);
		}

		$orderby = isset( $_REQUEST['orderby'] ) ? sanitize_key( wp_unslash( (string) $_REQUEST['orderby'] ) ) : 'title'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$order   = isset( $_REQUEST['order'] ) && strtolower( wp_unslash( (string) $_REQUEST['order'] ) ) === 'desc' ? 'desc' : 'asc'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended

		usort(
			$definitions,
			static function ( array $a, array $b ) use ( $orderby, $order ): int {
				$definition_a = is_array( $a['definition'] ?? null ) ? $a['definition'] : [];
				$definition_b = is_array( $b['definition'] ?? null ) ? $b['definition'] : [];

				$va = match ( $orderby ) {
					'key'    => (string) ( $a['key'] ?? '' ),
					'status' => ! empty( $definition_a['enabled'] ) ? '1' : '0',
					'fields' => str_pad( (string) count( is_array( $definition_a['fields'] ?? null ) ? $definition_a['fields'] : [] ), 6, '0', STR_PAD_LEFT ),
					default  => (string) ( $definition_a['title'] ?? $a['key'] ?? '' ),
				};
				$vb = match ( $orderby ) {
					'key'    => (string) ( $b['key'] ?? '' ),
					'status' => ! empty( $definition_b['enabled'] ) ? '1' : '0',
					'fields' => str_pad( (string) count( is_array( $definition_b['fields'] ?? null ) ? $definition_b['fields'] : [] ), 6, '0', STR_PAD_LEFT ),
					default  => (string) ( $definition_b['title'] ?? $b['key'] ?? '' ),
				};

				$compare = strcasecmp( $va, $vb );
				return $order === 'asc' ? $compare : -$compare;
			}
		);

		$total_items = count( $definitions );
		$per_page    = $this->get_items_per_page( 'wpps_cf_field_groups_per_page', 20 );
		$current     = max( 1, $this->get_pagenum() );
		$this->items = array_slice( array_values( $definitions ), ( $current - 1 ) * $per_page, $per_page );
		$this->set_pagination_args(
			[
				'total_items' => $total_items,
				'per_page'    => $per_page,
				'total_pages' => max( 1, (int) ceil( $total_items / $per_page ) ),
			]
		);

		$this->_column_headers = [
			$this->get_columns(),
			[],
			$this->get_sortable_columns(),
			'title',
		];
	}

	/**
	 * @param array<string, mixed> $item Row item.
	 */
	protected function column_cb( $item ): string {
		return sprintf(
			'<input type="checkbox" name="field_group[]" value="%s" />',
			esc_attr( (string) ( $item['key'] ?? '' ) )
		);
	}

	/**
	 * @param array<string, mixed> $item Row item.
	 */
	protected function column_title( $item ): string {
		$key        = (string) ( $item['key'] ?? '' );
		$definition = isset( $item['definition'] ) && is_array( $item['definition'] ) ? $item['definition'] : [];
		$title      = (string) ( $definition['title'] ?? $key );
		$enabled    = ! empty( $definition['enabled'] );

		$edit_url      = $this->admin->url( [ 'action' => 'edit', 'key' => $key ] );
		$toggle_url    = $this->admin->actionUrl( 'wpps_cf_toggle', 'wpps_cf_toggle_' . $key, [ 'key' => $key ] );
		$duplicate_url = $this->admin->actionUrl( 'wpps_cf_duplicate', 'wpps_cf_duplicate_' . $key, [ 'key' => $key ] );
		$export_url    = $this->admin->actionUrl( 'wpps_cf_export', 'wpps_cf_export', [ 'key' => $key ] );
		$delete_url    = $this->admin->actionUrl( 'wpps_cf_delete', 'wpps_cf_delete_' . $key, [ 'key' => $key ] );

		$actions = [
			'edit'      => sprintf(
				'<a href="%s">%s</a>',
				esc_url( $edit_url ),
				esc_html__( 'Edit', 'wppowersuite-lite' )
			),
			'toggle'    => sprintf(
				'<a href="%s">%s</a>',
				esc_url( $toggle_url ),
				$enabled ? esc_html__( 'Disable', 'wppowersuite-lite' ) : esc_html__( 'Enable', 'wppowersuite-lite' )
			),
			'duplicate' => sprintf(
				'<a href="%s">%s</a>',
				esc_url( $duplicate_url ),
				esc_html__( 'Duplicate', 'wppowersuite-lite' )
			),
			'export'    => sprintf(
				'<a href="%s">%s</a>',
				esc_url( $export_url ),
				esc_html__( 'Export', 'wppowersuite-lite' )
			),
			'delete'    => sprintf(
				'<a href="%s" class="submitdelete cf-delete">%s</a>',
				esc_url( $delete_url ),
				esc_html__( 'Delete', 'wppowersuite-lite' )
			),
		];

		$output = '<strong><a class="row-title" href="' . esc_url( $edit_url ) . '">' . esc_html( $title ) . '</a></strong>';

		return $output . $this->row_actions( $actions );
	}

	/**
	 * @param array<string, mixed> $item Row item.
	 */
	protected function column_fields( $item ): string {
		$definition = isset( $item['definition'] ) && is_array( $item['definition'] ) ? $item['definition'] : [];
		$fields     = isset( $definition['fields'] ) && is_array( $definition['fields'] ) ? $definition['fields'] : [];

		return esc_html( (string) count( $fields ) );
	}

	/**
	 * @param array<string, mixed> $item Row item.
	 */
	protected function column_key( $item ): string {
		return '<code>' . esc_html( (string) ( $item['key'] ?? '' ) ) . '</code>';
	}

	/**
	 * @param array<string, mixed> $item Row item.
	 */
	protected function column_status( $item ): string {
		$definition = isset( $item['definition'] ) && is_array( $item['definition'] ) ? $item['definition'] : [];
		$enabled    = ! empty( $definition['enabled'] );
		$key        = (string) ( $item['key'] ?? '' );
		$toggle_url = $this->admin->actionUrl( 'wpps_cf_toggle', 'wpps_cf_toggle_' . $key, [ 'key' => $key ] );
		$label      = $enabled ? __( 'Disable field group', 'wppowersuite-lite' ) : __( 'Enable field group', 'wppowersuite-lite' );

		return sprintf(
			'<a href="%1$s" class="cf-switch cf-switch--list cf-switch--%2$s" role="switch" aria-checked="%3$s" aria-label="%4$s"><span class="cf-switch__track" aria-hidden="true"><span class="cf-switch__thumb"></span></span><span class="cf-switch__label">%5$s</span></a>',
			esc_url( $toggle_url ),
			$enabled ? 'on' : 'off',
			$enabled ? 'true' : 'false',
			esc_attr( $label ),
			$enabled ? esc_html__( 'Enabled', 'wppowersuite-lite' ) : esc_html__( 'Disabled', 'wppowersuite-lite' )
		);
	}

	/**
	 * @param array<string, mixed> $item Row item.
	 */
	protected function column_location( $item ): string {
		$definition = isset( $item['definition'] ) && is_array( $item['definition'] ) ? $item['definition'] : [];

		return LocationTargets::listColumnHtml( $definition );
	}

	/**
	 * @param array<string, mixed> $item        Row item.
	 * @param string               $column_name Column name.
	 */
	protected function column_default( $item, $column_name ): string {
		return '';
	}

	public function no_items(): void {
		$all = $this->admin->getDefinitionsForList();
		if ( $all === [] ) {
			esc_html_e( 'No field groups found.', 'wppowersuite-lite' );
			return;
		}

		echo esc_html__( 'No field groups match your search or filter.', 'wppowersuite-lite' );
		echo ' <a href="' . esc_url( $this->admin->url() ) . '">' . esc_html__( 'Clear filters', 'wppowersuite-lite' ) . '</a>';
	}

	/**
	 * @return array<string, string>
	 */
	protected function get_views(): array {
		$all_items   = $this->admin->getDefinitionsForList();
		$search_args = $this->search_query !== '' ? [ 's' => $this->search_query ] : [];

		$count_all      = count( $all_items );
		$count_enabled  = count( array_filter( $all_items, static fn( array $item ): bool => ! empty( $item['definition']['enabled'] ) ) );
		$count_disabled = $count_all - $count_enabled;

		return [
			'all'      => sprintf(
				'<a href="%s" class="%s">%s <span class="count">(%d)</span></a>',
				esc_url( $this->admin->url( array_merge( [ 'status' => 'all' ], $search_args ) ) ),
				$this->status_filter === 'all' ? 'current' : '',
				esc_html__( 'All', 'wppowersuite-lite' ),
				$count_all
			),
			'enabled'  => sprintf(
				'<a href="%s" class="%s">%s <span class="count">(%d)</span></a>',
				esc_url( $this->admin->url( array_merge( [ 'status' => 'enabled' ], $search_args ) ) ),
				$this->status_filter === 'enabled' ? 'current' : '',
				esc_html__( 'Enabled', 'wppowersuite-lite' ),
				$count_enabled
			),
			'disabled' => sprintf(
				'<a href="%s" class="%s">%s <span class="count">(%d)</span></a>',
				esc_url( $this->admin->url( array_merge( [ 'status' => 'disabled' ], $search_args ) ) ),
				$this->status_filter === 'disabled' ? 'current' : '',
				esc_html__( 'Disabled', 'wppowersuite-lite' ),
				$count_disabled
			),
		];
	}
}
