<?php
namespace Prodigy\Admin;

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


use Prodigy\Includes\Content\Prodigy_Api_Client;
use Prodigy\Includes\Content\Prodigy_Request_Maker;
use Prodigy\Includes\Demo\Exception\Prodigy_Demo_Content_Exception;
use Prodigy\Includes\Helpers\Prodigy_Logger;
use Prodigy\Includes\Helpers\Prodigy_Template;
use Prodigy\Includes\Prodigy;
use Prodigy\Includes\Prodigy_Pagination;
use Prodigy\Includes\Synchronization\Content\Prodigy_Process_Factory;
use Prodigy\Includes\Synchronization\Prodigy_Synchronization;

/**
 * Prodigy admin products class
 *
 * @version 2.0.0
 * @package prodigy/admin
 */
class Prodigy_Admin_Products_List extends Prodigy_Admin_Page {

	/**
	 * Sync.
	 *
	 * @var Prodigy_Synchronization $sync
	 */
	public Prodigy_Synchronization $sync;

	/**
	 * Process factory.
	 *
	 * @var Prodigy_Process_Factory $process_factory
	 */
	public Prodigy_Process_Factory $process_factory;

	public const PRODIGY_PRODUCTS_PAGE = 'prodigy_products';

	/**
	 * Prodigy_Admin_Menu constructor.
	 */
	public function __construct() {
		parent::__construct();
		$this->sync            = new Prodigy_Synchronization();
		$this->process_factory = new Prodigy_Process_Factory();
		add_action( 'admin_menu', array( $this, 'add_prodigy_products_menu' ) );
		add_action( 'wp_ajax_prodigy-get-products-content', array( $this, 'prodigy_get_products_content' ) );
		add_action( 'wp_ajax_prodigy-start-sync-process', array( $this, 'prodigy_start_manual_sync_process' ) );
		add_action( 'wp_ajax_prodigy-check-sync-status', array( $this, 'check_sync_status' ) );
	}

	/**
	 * Start manual process
	 *
	 * @throws Prodigy_Demo_Content_Exception
	 */
	public function prodigy_start_manual_sync_process(): void {
		if ( ! check_ajax_referer( 'ajax-nonce', 'nonce' ) ) {
			return;
		}

		$this->process_factory->delete_queue_key( 'prodigy_set_synchronization_process_types' );
		$is_save_sync_options = $this->sync->run_sync_process( Prodigy_Api_Client::SYNC_CONTENT_URL, Prodigy_Synchronization::PRODIGY_MANUAL_PROCESS );
		if ( ! $is_save_sync_options && PRODIGY_DEBUG_MODE ) {
			$message = __LINE__ . __METHOD__ . __CLASS__ . ' Sync settings saving error';
			Prodigy_Logger::add_record( Prodigy_Logger::TYPE_ERROR, $message );
		}
	}

	/**
	 * @return void
	 */
	public function check_sync_status(): void {
		$status                       = get_option( Prodigy_Synchronization::PRODIGY_SYNC_STATUS );
		$is_need_to_show_notification = get_option( Prodigy_Synchronization::PRODIGY_NEEDS_SYNC_NOTIFICATION );
		if ( $status === 'success' && $is_need_to_show_notification ) {
			$this->reset_sync_process_options();
			wp_send_json_success( compact( 'status' ), 200 );
		} elseif ( $status === 'error' ) {
			$this->reset_sync_process_options();
			wp_send_json_error( compact( 'status' ), 404 );
		}
	}

	/**
	 * @return void
	 */
	public function reset_sync_process_options(): void {
		delete_option( Prodigy_Synchronization::PRODIGY_NEEDS_SYNC_NOTIFICATION );
		delete_option( Prodigy_Synchronization::PRODIGY_SYNC_MESSAGE_OPTION );
		delete_option( Prodigy_Synchronization::PRODIGY_SYNC_STATUS );
		delete_option( Prodigy_Synchronization::PRODIGY_SYNCHRONIZATION_TYPE );
	}

	/**
	 * Create products submenu
	 */
	public function add_prodigy_products_menu(): void {
		global $submenu;
		unset( $submenu[ 'edit.php?post_type=' . Prodigy::PRODIGY_POST_TYPE_DEFAULT ][15], $submenu[ 'edit.php?post_type=' . Prodigy::PRODIGY_POST_TYPE_DEFAULT ][16] );

		add_submenu_page(
			'',
			__( 'Prodigy Products', 'prodigy-commerce' ),
			__( 'Products list', 'prodigy-commerce' ),
			'edit_pages',
			self::PRODIGY_PRODUCTS_PAGE,
			array( $this, 'get_products_page' )
		);
	}


	/**
	 * Retrieve and send products content via AJAX.
	 *
	 * @return void
	 */
	public function prodigy_get_products_content(): void {
		if ( ! $this->is_valid_request() ) {
			return;
		}

		$params      = $this->get_request_params();
		$request_url = $this->build_request_url( $params );
		$products    = Prodigy_Request_Maker::get_instance()->do_admin_products_request( $request_url );
		$total_count = $products['data'][0]['attributes']['products-count'] ?? 0;

		$pagination_params = $this->get_pagination_params( $products, $total_count ?? 0, $params );
		$sort              = $this->get_sort_order( $params );

		$result = array(
			'products'   => $products['data'] ?? null,
			'template'   => $this->get_products_template( $products, $params, $total_count ?? 0, $sort ),
			'pagination' => $this->get_pagination_template( $pagination_params ),
		);

		wp_send_json_success( $result );
	}

	/**
	 * Validate request by checking nonce.
	 *
	 * @return bool
	 */
	private function is_valid_request(): bool {
		return isset( $_GET['nonce'] ) && wp_verify_nonce( sanitize_key( $_GET['nonce'] ), 'ajax-nonce' );
	}

	/**
	 * Get and sanitize request parameters.
	 *
	 * @return array
	 */
	private function get_request_params(): array {
		$query = isset( $_GET ) ? http_build_query( $_GET ) : '';
		parse_str( $query, $params );

		return $params;
	}

	/**
	 * Build request URL for products API.
	 *
	 * @param array $params
	 *
	 * @return string
	 */
	private function build_request_url( array $params ): string {
		$product_params = $this->parse_product_params( http_build_query( $params ) );
		$query_string   = http_build_query( $product_params );

		return urldecode( preg_replace( '/%5B(?:[0-9]|[1-9][0-9]+)%5D/', '[]', $query_string ) );
	}

	/**
	 * Calculate and return pagination parameters.
	 *
	 * @param array $products
	 * @param int   $total_count
	 * @param array $params
	 *
	 * @return array
	 */
	public function get_pagination_params( array $products, int $total_count, array $params ): array {
		$base_url = $this->get_base_url();
		$page     = $this->get_current_page( $params );

		return array(
			'pages'       => ! empty( $products['data'] ) ? Prodigy_Pagination::calculate_count_pages( $total_count, self::COUNT_ITEMS_ON_PAGE ) : 1,
			'url'         => $base_url,
			'page'        => $page,
			'page_number' => sanitize_key( $page ),
		);
	}

	/**
	 * Determine the sort order.
	 *
	 * @param array $params
	 *
	 * @return string
	 */
	private function get_sort_order( array $params ): string {
		if ( ! empty( $params['sort'] ) && strripos( $params['sort'], '_asc' ) ) {
			return 'asc';
		}

		return 'desc';
	}

	/**
	 *
	 * @param array  $products
	 * @param array  $params
	 * @param int    $total_count
	 * @param string $sort
	 *
	 * @return string
	 */
	private function get_products_template( array $products, array $params, int $total_count, string $sort ): string {
		return Prodigy_Template::prodigy_get_template_html(
			'prodigy-admin-products-list.php',
			array(
				'products' => $products['data'] ?? null,
				'search'   => $params['search'] ?? '',
				'count'    => $total_count,
				'sort'     => $sort,
			),
			'admin'
		);
	}

	/**
	 * Retrieve the pagination template.
	 *
	 * @param array $pagination_params
	 *
	 * @return string
	 */
	private function get_pagination_template( array $pagination_params ): string {
		return Prodigy_Template::prodigy_get_template_html( 'shop/pagination.php', array( 'data' => $pagination_params ) );
	}

	/**
	 * Get and sanitize the current page from the request parameters.
	 *
	 * @param array $params
	 *
	 * @return int
	 */
	private function get_current_page( array $params ): int {
		if ( isset( $params['pg'] ) ) {
			return sanitize_key( wp_unslash( $params['pg'] ) );
		}

		return 1;
	}

	/**
	 * Retrieve the base URL from HTTP referrer or default admin URL.
	 *
	 * @return string
	 */
	private function get_base_url(): string {
		if ( isset( $_SERVER['HTTP_REFERER'] ) ) {
			return remove_query_arg( 'pg', sanitize_url( wp_unslash( $_SERVER['HTTP_REFERER'] ) ) );
		}

		return admin_url();
	}

	/**
	 * @param string $query
	 *
	 * @return array
	 */
	public function parse_product_params( string $query ): array {
		if ( ! empty( $query ) ) {
			parse_str( urldecode( $query ), $request_attr );
		}

		if ( isset( $request_attr ) && ! empty( $request_attr['search'] ) ) {
			$params['search'] = $request_attr['search'];
		}

		if ( ! empty( $request_attr ) ) {
			$params['page']['size']   = self::COUNT_ITEMS_ON_PAGE;
			$params['page']['number'] = $request_attr['pg'] ?? 1;
		}

		if ( isset( $request_attr['sort'] ) ) {
			$patterns[0]    = '/_asc/';
			$patterns[1]    = '/_desc/';
			$replacements   = '';
			$sort           = preg_replace( $patterns, $replacements, $request_attr['sort'] );
			$params['sort'] = $sort;
		} else {
			$params['sort'] = '-created_at';
		}
		$params['admin'] = true;

		return $params;
	}

	/**
	 * Init the products page.
	 */
	public function get_products_page(): void {
		$this->render_view();
	}

	/**
	 * Render view from page
	 */
	public function render_view(): void {
		$products   = array();
		$empty_view = true;
		require_once PRODIGY_PLUGIN_PATH . 'admin/partials/prodigy-admin-products-list.php';
	}
}
