<?php
/**
 * Functions to perform snippet operations
 *
 * @package Code_Snippets
 */

namespace Code_Snippets\Cloud;

use function Code_Snippets\code_snippets;

/**
 * Build the nonce action string for cloud snippet state-changing operations.
 *
 * @param string $action    Action - 'download' or 'update'.
 * @param int    $snippet_id Cloud snippet ID.
 * @param string $source    Source - 'search' or 'cloud'.
 *
 * @return string
 */
function cloud_lts_get_snippet_action_nonce_action( string $action, int $snippet_id, string $source ): string {
	return sprintf( 'cloud-snippet-action|%s|%s|%d', $action, $source, $snippet_id );
}

/**
 * Display a hidden input field for a certain column and snippet value.
 *
 * @param string        $column_name Column name.
 * @param Cloud_Snippet $snippet     Column item.
 *
 * @return void
 */
function cloud_lts_display_column_hidden_input( string $column_name, Cloud_Snippet $snippet ) {
	printf(
		'<input id="cloud-snippet-%s-%s" class="cloud-snippet-item" type="hidden" name="%s" value="%s" />',
		esc_attr( $column_name ),
		esc_attr( $snippet->id ),
		esc_attr( $column_name ),
		esc_attr( $snippet->$column_name )
	);
}

/**
 * Display a hidden input field for a certain column and snippet value.
 *
 * @param string        $column_name Column name.
 * @param Cloud_Snippet $snippet     Column item.
 *
 * @return string HTML
 */
function cloud_lts_build_column_hidden_input( string $column_name, Cloud_Snippet $snippet ): string {
	return sprintf(
		'<input id="cloud-snippet-%s-%s" class="cloud-snippet-item" type="hidden" name="%s" value="%s" />',
		esc_attr( $column_name ),
		esc_attr( $snippet->id ),
		esc_attr( $column_name ),
		esc_attr( $snippet->$column_name )
	);
}

/**
 * Process the download snippet action
 *
 * @param string $action         Action - 'download' or 'update'.
 * @param string $source         Source - 'search' or 'cloud'.
 * @param string $snippet        Snippet ID.
 * @param int    $codevault_page Page number for Codevault pagination.
 *
 * @return void
 */
function cloud_lts_process_download_action( string $action, string $source, string $snippet, int $codevault_page = 0 ) {
	if ( 'download' === $action || 'update' === $action ) {
		$result = code_snippets()->cloud_api->download_or_update_snippet( $snippet, $source, $action, $codevault_page );

		if ( $result['success'] ) {
			$redirect_uri = $result['snippet_id'] ?
				code_snippets()->get_snippet_edit_url( (int) $result['snippet_id'] ) :
				add_query_arg( 'result', $result['action'] );

			wp_safe_redirect( esc_url_raw( $redirect_uri ) );
			exit;
		}
	}
}

/**
 * Build action links for snippet.
 *
 * @param Cloud_Snippet $cloud_snippet Snippet/Column item.
 * @param string        $source        Source - 'search' or 'codevault'.
 *
 * @return string Action link HTML.
 */
function cloud_lts_build_action_links( Cloud_Snippet $cloud_snippet, string $source ): string {
	$lang = Cloud_API::get_type_from_scope( $cloud_snippet->scope );
	$link = code_snippets()->cloud_api->get_link_for_cloud_snippet( $cloud_snippet );
	$is_licensed = code_snippets()->licensing->is_licensed();
	$download = $is_licensed || ! in_array( $lang, [ 'css', 'js' ], true );
	$snippet_id = (int) $cloud_snippet->id;

	if ( $link ) {
		if ( $is_licensed && $link->update_available ) {
			$update_url = wp_nonce_url(
				add_query_arg(
					[
						'action'  => 'update',
						'snippet' => $snippet_id,
						'source'  => $source,
					]
				),
				cloud_lts_get_snippet_action_nonce_action( 'update', $snippet_id, $source )
			);
			return sprintf(
				'<li><a class="button button-primary" href="%s">%s</a></li>',
				esc_url( $update_url ),
				esc_html__( 'Update Available', 'code-snippets' )
			);
		} else {
			return sprintf(
				'<li><a class="button" href="%s">%s</a></li>',
				esc_url( code_snippets()->get_snippet_edit_url( $link->local_id ) ),
				esc_html__( 'View', 'code-snippets' )
			);
		}
	}

	if ( $download ) {
			$download_query = [
				'action'  => 'download',
				'snippet' => $snippet_id,
				'source'  => $source,
			];

			// Preserve current cloud page if present so downstream handlers receive pagination context.
			if ( isset( $_REQUEST['cloud_page'] ) ) {
				$download_query['cloud_page'] = (int) wp_unslash( $_REQUEST['cloud_page'] );
			}

			// Preserve bundle context for bundle downloads.
			if ( isset( $_REQUEST['cloud_bundles'] ) ) {
				$download_query['cloud_bundles'] = (int) wp_unslash( $_REQUEST['cloud_bundles'] );
			}
			if ( isset( $_REQUEST['bundle_share_name'] ) ) {
				$download_query['bundle_share_name'] = sanitize_text_field( wp_unslash( $_REQUEST['bundle_share_name'] ) );
			}

			$download_url = wp_nonce_url(
				add_query_arg( $download_query ),
				cloud_lts_get_snippet_action_nonce_action( 'download', $snippet_id, $source )
			);

		$download_button = sprintf(
			'<li><a class="button button-primary" href="%s">%s</a></li>',
			esc_url( $download_url ),
			esc_html__( 'Download', 'code-snippets' )
		);
	} else {
		$download_button = sprintf(
			'<li><span class="%s">%s <span class="tooltip-content">%s</span></span></li>',
			'button button-primary button-disabled tooltip tooltip-block tooltip-end',
			esc_html__( 'Download', 'code-snippets' ),
			esc_html__( 'This snippet type is only available in Code Snippets Pro', 'code-snippets' )
		);
	}

	$preview_button = sprintf(
		'<li><a href="%s" aria-label="%s" class="%s" data-snippet="%s" data-lang="%s">%s</a></li>',
		'#TB_inline?&width=700&height=500&inlineId=show-code-preview',
		esc_attr( $cloud_snippet->name ),
		'cloud-snippet-preview thickbox button',
		esc_attr( $cloud_snippet->id ),
		esc_attr( $lang ),
		esc_html__( 'Preview', 'code-snippets' )
	);

	return $download_button . $preview_button;
}

/**
 * Build the pagination functionality
 *
 * @param string $which       Context where the pagination will be displayed.
 * @param string $source      Source - 'search' or 'cloud'.
 * @param int    $total_items Total number of items.
 * @param int    $total_pages Total number of pages.
 * @param int    $pagenum     Current page number.
 *
 * @return array
 */
function cloud_lts_pagination( string $which, string $source, int $total_items, int $total_pages, int $pagenum ): array {
	/* translators: %s: Number of items. */
	$num = sprintf( _n( '%s item', '%s items', $total_items, 'code-snippets' ), number_format_i18n( $total_items ) );
	$output = '<span class="displaying-num">' . $num . '</span>';

	$param_key = $source . '_page';
	$current = isset( $_REQUEST[ $param_key ] ) ? (int) $_REQUEST[ $param_key ] : $pagenum;
	$current_url = remove_query_arg( wp_removable_query_args() ) . '#' . $source;

	$page_links = array();

	$html_current_page = '';
	$total_pages_before = '<span class="paging-input">';
	$total_pages_after = '</span></span>';

	$disable_first = false;
	$disable_last = false;
	$disable_prev = false;
	$disable_next = false;

	if ( 1 === $current ) {
		$disable_first = true;
		$disable_prev = true;
	}

	if ( $total_pages === $current ) {
		$disable_last = true;
		$disable_next = true;
	}

	if ( $disable_first ) {
		$page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&laquo;</span>';
	} else {
		$page_links[] = sprintf(
			'<a class="first-page button" href="%s"><span class="screen-reader-text">%s</span><span aria-hidden="true">&laquo;</span></a>',
			esc_url( remove_query_arg( $source . '_page', $current_url ) ),
			esc_html__( 'First page', 'code-snippets' )
		);
	}

	if ( $disable_prev ) {
		$page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&lsaquo;</span>';
	} else {
		$page_links[] = sprintf(
			'<a class="prev-page button" href="%s"><span class="screen-reader-text">%s</span><span aria-hidden="true">&lsaquo;</span></a>',
			esc_url( add_query_arg( $source . '_page', max( 1, $current - 1 ), $current_url ) ),
			esc_html__( 'Previous page', 'code-snippets' )
		);
	}

	if ( 'bottom' === $which ) {
		$html_current_page = $current;
		$total_pages_before = sprintf( '<span class="screen-reader-text">%s</span><span id="table-paging" class="paging-input"><span class="tablenav-paging-text">', __( 'Current page', 'code-snippets' ) );
	}

	if ( 'top' === $which ) {
		$html_current_page = sprintf(
			'<label for="current-page-selector" class="screen-reader-text">%s</label><input class="current-page-selector" id="current-page-selector" type="text" name="%s_page" value="%s" size="%d" aria-describedby="table-paging" /><span class="tablenav-paging-text">',
			__( 'Current page', 'code-snippets' ),
			$source,
			$current,
			strlen( $total_pages )
		);
	}

	$html_total_pages = sprintf( '<span class="total-pages">%s</span>', number_format_i18n( $total_pages ) );

	/* translators: 1: Current page, 2: Total pages. */
	$current_html = _x( '%1$s of %2$s', 'paging', 'code-snippets' );
	$page_links[] = $total_pages_before . sprintf( $current_html, $html_current_page, $html_total_pages ) . $total_pages_after;

	if ( $disable_next ) {
		$page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&rsaquo;</span>';
	} else {
		$page_links[] = sprintf(
			'<a class="next-page button" href="%s"><span class="screen-reader-text">%s</span><span aria-hidden="true">%s</span></a>',
			esc_url( add_query_arg( $source . '_page', min( $total_pages, $current + 1 ), $current_url ) ),
			esc_html__( 'Next page', 'code-snippets' ),
			'&rsaquo;'
		);
	}

	if ( $disable_last ) {
		$page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&raquo;</span>';
	} else {
		$page_links[] = sprintf(
			'<a class="last-page button" href="%s"><span class="screen-reader-text">%s</span><span aria-hidden="true">%s</span></a>',
			esc_url( add_query_arg( $source . '_page', $total_pages, $current_url ) ),
			esc_html__( 'Last page', 'code-snippets' ),
			'&raquo;'
		);
	}

	$pagination_links_class = 'pagination-links';
	if ( ! empty( $infinite_scroll ) ) {
		$pagination_links_class .= ' hide-if-js';
	}

	$output .= "\n<span class='$pagination_links_class'>" . implode( "\n", $page_links ) . '</span>';

	$page_class = $total_pages ? '' : ' no-pages';

	return [
		'output'     => $output,
		'page_class' => $page_class,
	];
}
