<?php
/**
 * Admin Groups List Table.
 *
 * @package AdvancedAds
 * @author  Advanced Ads <info@wpadvancedads.com>
 * @since   1.48.2
 */

namespace AdvancedAds\Admin\Groups;

use WP_Term_Query;
use AdvancedAds\Modal;
use WP_Terms_List_Table;
use AdvancedAds\Constants;
use AdvancedAds\Framework\Utilities\Params;
use AdvancedAds\Admin\Upgrades;

defined( 'ABSPATH' ) || exit;

/**
 * Admin Groups List Table.
 */
class List_Table extends WP_Terms_List_Table {
	/**
	 * Missing type error.
	 *
	 * @var string
	 */
	private $type_error = '';

	/**
	 * Array with all ads.
	 *
	 * @var $all_ads
	 */
	private $all_ads = [];

	/**
	 * Construct the current list table.
	 */
	public function __construct() {
		parent::__construct();
		add_action( 'pre_get_terms', [ $this, 'pre_get_terms' ] );
		add_filter( 'default_hidden_columns', [ $this, 'default_hidden_columns' ] );

		$this->prepare_items();
		$this->_actions = [];
		$this->all_ads  = wp_advads_get_ads_dropdown();
	}

	/**
	 * Modify sorting query
	 *
	 * @param WP_Term_Query $query Query object.
	 *
	 * @return WP_Term_Query
	 */
	public function pre_get_terms( $query ) {
		if ( empty( $query->query_vars['meta_query'] ) ) {
			$query->query_vars['meta_query'] = []; // phpcs:ignore
		}

		// Filter terms by group type.
		$group_type = Params::get( 'group_type' );
		if ( $group_type ) {
			$query->query_vars['meta_query'][] = [
				'key'     => '_advads_group_type',
				'value'   => $group_type,
				'compare' => '=',
			];
		}

		// Handle sorting.
		switch ( $query->query_vars['orderby'] ?? '' ) {
			case 'date':
				$query->query_vars['meta_query'][] = [
					'relation' => 'OR',
					[
						'key'     => 'modified_date',
						'compare' => 'EXISTS',
					],
					[
						'key'     => 'modified_date',
						'compare' => 'NOT EXISTS',
					],
				];

				$query->query_vars['orderby'] = 'meta_value';
				break;

			case 'details':
				// Sort by term ID.
				$query->query_vars['orderby'] = 'term_id';
				break;
		}

		return $query;
	}

	/**
	 * Displays extra controls between bulk actions and pagination.
	 *
	 * @since 3.1.0
	 *
	 * @param string $which The location: 'top' or 'bottom'.
	 */
	protected function extra_tablenav( $which ) {
		if ( 'top' === $which ) {
			include_once ADVADS_ABSPATH . 'views/admin/groups/filters.php';
		}
	}

	/**
	 * No groups found
	 *
	 * @return void
	 */
	public function no_items(): void {
		esc_html_e( 'No Ad Group found', 'advanced-ads' );
	}

	/**
	 * Get columns
	 *
	 * @return array
	 */
	public function get_columns(): array {
		return [
			'type'    => __( 'Type', 'advanced-ads' ),
			'name'    => _x( 'Name', 'term name', 'advanced-ads' ),
			'details' => __( 'Details', 'advanced-ads' ),
			'ads'     => __( 'Ads', 'advanced-ads' ),
			'date'    => __( 'Date', 'advanced-ads' ),
		];
	}

	/**
	 * Hidden columns
	 *
	 * @param string[] $hidden Column list.
	 *
	 * @return array
	 */
	public function default_hidden_columns( $hidden ): array {
		$hidden[] = 'date';
		return $hidden;
	}

	/**
	 * Sortable columns
	 *
	 * @return array
	 */
	public function get_sortable_columns(): array {
		return [
			'date'    => 'date',
			'name'    => 'name',
			'details' => 'details',
		];
	}


	/**
	 * Render single row.
	 *
	 * @param \WP_Term|object $term  Term object.
	 * @param int             $level Depth level.
	 *
	 * @return void
	 */
	public function single_row( $term, $level = 0 ): void {
		$this->type_error = '';
		$group            = wp_advads_get_group( $term->term_id );

		// Set the group to behave as default, if the original type is not available.
		$group_type = $group->get_type_object();
		if ( $group_type->is_premium() ) {
			$this->type_error = sprintf(
			/* translators: %s is the group type string */
				__( 'The originally selected group type “%s” is not enabled.', 'advanced-ads' ),
				$group_type->get_title()
			);
		}

		echo '<tr id="tag-' . $group->get_id() . '" class="' . $level . '">'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		$this->single_row_columns( $group );
		echo '</tr>';
	}

	/**
	 * Column type
	 *
	 * @param Group $group Group instance.
	 *
	 * @return void
	 */
	public function column_type( $group ): void {
		include ADVADS_ABSPATH . 'views/admin/groups/columns/type.php';
	}

	/**
	 * Column name
	 *
	 * @param Group $group Group instance.
	 *
	 * @return void
	 */
	public function column_name( $group ): void {
		$this->render_edit_modal( $group );
		$this->render_usage_modal( $group );
		include ADVADS_ABSPATH . 'views/admin/groups/columns/name.php';
	}

	/**
	 * Column details
	 *
	 * @param Group $group Group instance.
	 *
	 * @return void
	 */
	public function column_details( $group ): void {
		include ADVADS_ABSPATH . 'views/admin/groups/columns/details.php';
	}

	/**
	 * Column ads
	 *
	 * @param Group $group Group instance.
	 *
	 * @return void
	 */
	public function column_ads( $group ): void {
		$template = empty( $group->get_ad_weights() ) ? 'list-row-loop-none.php' : 'list-row-loop.php';

		include ADVADS_ABSPATH . 'views/admin/groups/columns/' . $template;
	}

	/**
	 * Column date
	 *
	 * @param Group $group Group instance.
	 *
	 * @return void
	 */
	public function column_date( $group ) {
		$publish_date  = $group->get_publish_date();
		$modified_date = $group->get_modified_date();

		if ( ! $publish_date && ! $modified_date ) {
			return;
		}

		$date_time_regex = get_option( 'date_format' ) . ' \\a\\t ' . get_option( 'time_format' );
		$date_prefix     = $publish_date === $modified_date ? __( 'Published', 'advanced-ads' ) : __( 'Last Modified', 'advanced-ads' );
		$date_to_show    = get_date_from_gmt( $publish_date === $modified_date ? $publish_date : $modified_date, $date_time_regex );

		echo esc_html( $date_prefix ) . '<br>' . esc_html( $date_to_show );
	}

	/**
	 * Generates and displays row action links.
	 *
	 * @param Group  $group Group instance.
	 * @param string $column_name Column name.
	 * @param string $primary     Primary column name.
	 *
	 * @return string
	 */
	protected function handle_row_actions( $group, $column_name, $primary ): string {
		global $tax;

		if ( $primary !== $column_name ) {
			return '';
		}

		$actions = [];

		if ( ! $this->type_error && current_user_can( $tax->cap->edit_terms ) ) {
			$actions['edit'] = '<a href="#modal-group-edit-' . $group->get_id() . '"
								class="edits">' . esc_html__( 'Edit', 'advanced-ads' ) . '</a>';

			// duplicate group upgrade link.
			if ( ! defined( 'AAP_VERSION' ) ) {
				$actions['duplicate-group'] = ( new Upgrades() )->create_duplicate_link();
			}
		}

		$actions['usage'] = '<a href="#modal-group-usage-' . $group->get_id() . '" class="edits">' . esc_html__( 'Show Usage', 'advanced-ads' ) . '</a>';

		if ( current_user_can( $tax->cap->delete_terms ) ) {
			$actions['delete'] = sprintf(
				'<a class="delete-tag" href="%s">%s</a>',
				wp_nonce_url(
					add_query_arg(
						[
							'action'   => 'group',
							'action2'  => 'delete',
							'group_id' => $group->get_id(),
							'page'     => 'advanced-ads-groups',
						],
						admin_url( 'admin.php' )
					),
					'delete-tag_' . $group->get_id()
				),
				esc_html__( 'Delete', 'advanced-ads' )
			);
		}

		$actions = apply_filters( Constants::TAXONOMY_GROUP . '_row_actions', $actions, $group );

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

	/**
	 * Render edit form modal
	 *
	 * @param Group $group Group instance.
	 *
	 * @return void
	 */
	private function render_edit_modal( $group ): void {
		ob_start();
		require ADVADS_ABSPATH . 'views/admin/groups/edit-modal/form.php';
		$modal_content = ob_get_clean();

		Modal::create(
			[
				'modal_slug'    => 'group-edit-' . $group->get_id(),
				'modal_content' => $modal_content,
				'modal_title'   => sprintf( '%s %s', __( 'Edit', 'advanced-ads' ), $group->get_name() ),
			]
		);
	}

	/**
	 * Render usage form modal
	 *
	 * @param Group $group Group instance.
	 *
	 * @return void
	 */
	private function render_usage_modal( $group ): void {
		ob_start();
		include ADVADS_ABSPATH . 'views/admin/groups/columns/usage.php';
		$modal_content = ob_get_clean();

		Modal::create(
			[
				'modal_slug'    => 'group-usage-' . $group->get_id(),
				'modal_content' => $modal_content,
				'modal_title'   => __( 'Usage', 'advanced-ads' ),
				'cancel_action' => false,
				'close_action'  => __( 'Close', 'advanced-ads' ),
			]
		);
	}
}
