<?php
/**
 * Registrar of custom post type.
 *
 * @link       https://codingfix.com
 * @since      1.0.0
 *
 * @package    Instalist
 * @subpackage Instalist/includes
 */

/**
 * Registrar of custom post type.
 *
 * Register the new custom post type Plugin List
 *
 * @package    Instalist
 * @subpackage Instalist/includes
 * @author     Marco Gasi <info@codingfix.com>
 */
class Pluginer_CPT {

	/**
	 * Initialize the class and set its properties.
	 *
	 * @since    1.0.0
	 */
	public function __construct() {
		add_action( 'init', array( $this, 'register_cpt_plugin_list' ) );
		add_filter( 'save_post', array( $this, 'validate_plugin_list_title' ), 10, 2 );
		add_filter( 'gettext', array( $this, 'change_publish_button_text' ), 10, 2 );
		add_filter( 'post_row_actions', array( $this, 'add_custom_row_actions' ), 10, 2 );
		add_action( 'admin_notices', array( $this, 'show_upgrade_notice' ) );
		add_action( 'load-post-new.php', array( $this, 'restrict_plugin_list_creation' ) );
		add_filter( 'manage_plgnr_plugin_list_posts_columns', array( $this, 'set_custom_edit_columns' ) );
		add_action( 'manage_plgnr_plugin_list_posts_custom_column', array( $this, 'custom_column' ), 10, 2 );
		add_action( 'save_post_plgnr_plugin_list', array( $this, 'plgnr_save_post_plugin_list' ), 10, 3 );
		add_filter(
			'bulk_actions-edit-plgnr_plugin_list',
			function ( $actions ) {
				unset( $actions['trash'] ); // rimuove Trash.
				return $actions;
			}
		);
		$this->init_submit_box();
	}

	/**
	 * Force post status to private on save.
	 *
	 * @param int     $post_id The ID of the post being saved.
	 * @param WP_Post $post The post object.
	 * @param bool    $update Whether this is an existing post being updated or not.
	 * @since 1.0.0
	 */
	public function plgnr_save_post_plugin_list( $post_id, $post, $update ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed

		// Evitiamo ricorsioni.
		remove_action( 'save_post_plgnr_plugin_list', __FUNCTION__, 10 );

		// Eseguiamo la logica solo se non è un "auto-draft" o una revisione.
		if ( 'auto-draft' !== $post->post_status && ! wp_is_post_revision( $post_id ) ) {
			// Se non è già privato, lo forziamo.
			if ( 'private' !== $post->post_status ) {
				wp_update_post(
					array(
						'ID'          => $post_id,
						'post_status' => 'private',
					)
				);
			}
		}

		// Riaffiliamo l'hook per i futuri salvataggi. Questa riga DEVE essere l'ultima.
		add_action( 'save_post_plgnr_plugin_list', __FUNCTION__, 10, 3 );
	}

	/**
	 * Inist la submit box
	 */
	public function init_submit_box() {
		// Hook specifico del tuo CPT, così sei sicuro dell’ordine.
		add_action( 'add_meta_boxes_plgnr_plugin_list', array( $this, 'replace_submit_box' ), 20 );
	}

	/**
	 * Sostituisce il box di submit standard con uno personalizzato.
	 */
	public function replace_submit_box() {
		// Rimuove il box standard.
		remove_meta_box( 'submitdiv', 'plgnr_plugin_list', 'side' );

		// Aggiunge il tuo box.
		add_meta_box(
			'pluginer_submitdiv',
			__( 'Save', 'pluginer' ),
			array( $this, 'render_submit_box' ),
			'plgnr_plugin_list',
			'side',
			'high'
		);
	}

	/**
	 * Render the submit box
	 *
	 * @param WP_Post $post The post object.
	 * @since 1.0.0
	 */
	public function render_submit_box( $post ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found
		?>
	<div class="submitbox" id="submitbox">
		<div id="major-publishing-actions">
			<div id="publishing-action">
			<?php
			// Nome "publish" per mantenere il flusso nativo di salvataggio.
			submit_button( __( 'Save List', 'pluginer' ), 'primary large', 'publish', false );
			?>
			</div>
			<div class="clear"></div>
		</div>
	</div>
			<?php
	}


	/**
	 * Register Plugin List post type.
	 *
	 * @since    1.0.0
	 */
	public function register_cpt_plugin_list() {
		$args = array(
			'label'               => __( 'All', 'pluginer' ),
			'labels'              => array(
				'name'               => __( 'Plugin Lists', 'pluginer' ),
				'singular_name'      => __( 'Plugin List', 'pluginer' ),
				'add_new'            => __( 'Add Plugin List', 'pluginer' ),
				'add_new_item'       => __( 'Add Plugin List', 'pluginer' ),
				'edit'               => __( 'Edit', 'pluginer' ),
				'edit_item'          => __( 'Edit Plugin List', 'pluginer' ),
				'new_item'           => __( 'New Plugin List', 'pluginer' ),
				'view'               => __( 'View Plugin List', 'pluginer' ),
				'view_item'          => __( 'View Plugin List', 'pluginer' ),
				'search_items'       => __( 'Search Plugin List', 'pluginer' ),
				'not_found'          => __( 'No Plugin List', 'pluginer' ),
				'not_found_in_trash' => __( 'No plugin list found in trash', 'pluginer' ),
				'menu_name'          => __( 'All Plugin Lists', 'pluginer' ),
			),
			'public'              => false,
			'show_ui'             => true,
			'publicly_queryable'  => false,
			'exclude_from_search' => true,
			'show_in_menu'        => 'pluginer',
			'hierarchical'        => false,
			'show_in_nav_menus'   => false,
			'rewrite'             => false,
			'query_var'           => false,
			'supports'            => array( 'title' ),
			'has_archive'         => false,
			'menu_positon'        => 65,
		);

		register_post_type( 'plgnr_plugin_list', $args );
	}

	/**
	 * Validate list data
	 *
	 * @param array $data The data of the plugin list.
	 * @param array $postarr Non ne ho idea.
	 * @since 1.0.0
	 */
	public function validate_plugin_list_title( $data, $postarr ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed
		global $post;
		if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
			return;
		}

		if ( ! isset( $_POST['plugin_list_metabox_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['plugin_list_metabox_nonce'] ) ), 'plugin_list_metabox_nonce' ) ) {
			return;
		}

		if ( 'plgnr_plugin_list' !== $post->post_type ) {
			return;
		}

		if ( empty( $post->post_title ) ) {
			$nonce = wp_create_nonce( 'nolistnameerror' );
			wp_safe_redirect(
				add_query_arg(
					array(
						'_wpnonce'    => $nonce,
						'title_error' => '1',
					),
					get_edit_post_link( $post->post_id, 'url' )
				)
			);
			exit;
		}
	}

	/**
	 * Change Publish button text
	 *
	 * @param string $translation The data of the plugin list.
	 * @param string $text Non ne ho idea.
	 * @since 1.0.0
	 */
	public function change_publish_button_text( $translation, $text ) {
		global $post;
		if ( isset( $post ) && 'plgnr_plugin_list' === $post->post_type ) {
			if ( 'Publish' === $text ) {
				return 'Save List';
			}
		}
		return $translation;
	}

	/**
	 * Change Publish button text
	 *
	 * @param string $actions The data of the plugin list.
	 * @param object $post Non ne ho idea.
	 * @since 1.0.0
	 */
	public function add_custom_row_actions( $actions, $post ) {
		if ( 'plgnr_plugin_list' !== $post->post_type ) {
			return $actions;
		}

		// Rimuovi azioni non desiderate di default.
		unset( $actions['trash'] );
		unset( $actions['inline hide-if-no-js'] ); // this is quick edit action.
		$is_primary = get_post_meta( $post->ID, '_is_primary_list', true );

		// phpcs:disabled
		// The following was to prevent users from deleting the first list created but it's not needed

		// $args     = array(
		// 'post_type'      => 'plgnr_plugin_list',
		// 'posts_per_page' => -1,
		// );
		// $query    = new WP_Query( $args );
		// $one_post = false;
		// if ( 1 === $query->found_posts ) {
		// $one_post = true;
		// }

		// Delete permanently solo se non primaria.
		// if ( ! $is_primary || $one_post ) {
			// $delete_link       = get_delete_post_link( $post->ID, '', true );
			// $actions['delete'] = '<a href="' . esc_url( $delete_link ) . '">' . __( 'Delete permanently', 'pluginer' ) . '</a>';
		// }
		// phpcs:enabled

		$delete_link       = get_delete_post_link( $post->ID, '', true );
		$actions['delete'] = '<a href="' . esc_url( $delete_link ) . '">' . __( 'Delete permanently', 'pluginer' ) . '</a>';

		// Determina se l'utente ha diritto alle azioni.
		$is_allowed = false;

		if ( CFX_Helper::is_premium_fully_active() ) {
			$is_allowed = true;
		}
		// Azioni Premium solo se consentite.
		if ( ! $is_allowed && ! $is_primary ) {
			unset( $actions['edit'] ); // niente Edit per liste non consentite.
		}

		if ( 'publish' === $post->post_status || 'private' === $post->post_status ) {
			$actions['export_list'] = '<a data-post-id="' . $post->ID . '" data-nonce="' . wp_create_nonce( 'plgnr_exportpluginlist' ) . '" class="export_list_button" href="#">' . __( 'Export list', 'pluginer' ) . '</a>';

			$actions['install_list'] = '<a data-post-id="' . $post->ID . '" data-nonce="' . wp_create_nonce( 'plgnr_installpluginlist' ) . '" class="install_list_button install_list_action" href="#">' . __( 'Install list', 'pluginer' ) . '</a>';
		}
		return $actions;
	}


	/**
	 * Restrict new list creation
	 *
	 * @since    1.0.0
	 */
	public function restrict_plugin_list_creation() {
		$is_premium = apply_filters( 'pluginer_is_premium', false );

		$args  = array(
			'post_type'      => 'plgnr_plugin_list',
			'posts_per_page' => -1,
		);
		$query = new WP_Query( $args );

		if ( $query->found_posts >= 1 && ! $is_premium ) {
			$nonce = wp_create_nonce( 'upgradeneedederror' );
			wp_safe_redirect(
				add_query_arg(
					array(
						'result'    => 'error',
						'_wpnonce'  => $nonce,
						'post_type' => 'plgnr_plugin_list',
					),
					admin_url( 'edit.php' )
				)
			);
		}
	}

	/**
	 * Show upgrade notice
	 *
	 * @since    1.0.0
	 */
	public function show_upgrade_notice() {
		if ( isset( $_GET['_wpnonce'] ) ) {
			if ( wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ), 'upgradeneedederror' ) ) {
				if ( isset( $_GET['result'] ) && 'error' === $_GET['result'] ) {
					echo '<div class="notice notice-error is-dismissible"><p>' . esc_html__( 'You cannot create more than one plugin list with the free version. Please upgrade to the premium version.', 'pluginer' ) . '</p></div>';
				}
			}
		}
		$is_premium = apply_filters( 'pluginer_is_premium', false );
		$args       = array(
			'post_type'      => 'plgnr_plugin_list',
			'posts_per_page' => -1,
		);
		$query      = new WP_Query( $args );
		if ( $query->found_posts > 1 && ! $is_premium ) {
			echo '<div class="error notice"><p>Please activate your license to manage multiple lists.</p></div>';
		}
	}

	/**
	 * Set custom columns
	 *
	 * @param array $columns Custom columns.
	 * @since    1.0.0
	 */
	public function set_custom_edit_columns( $columns ) {
		$new_columns = array();
		if ( isset( $columns['cb'] ) ) {
			$new_columns['cb'] = $columns['cb'];
			unset( $columns['cb'] );
		}
		if ( isset( $columns['title'] ) ) {
			$new_columns['title'] = $columns['title'];
			unset( $columns['title'] );
		}

		$new_columns['plugins_number'] = __( 'Plugins number', 'pluginer' );
		$new_columns['plugins']        = __( 'Plugins', 'pluginer' );
		$new_columns['requirements']   = __( 'Requirements', 'pluginer' );
		$new_columns['notes']          = __( 'Notes', 'pluginer' );

		return array_merge( $new_columns, $columns );
	}

	/**
	 * Set custom columns
	 *
	 * @param string $plugin_name The plugin name.
	 * @since    1.0.9
	 */
	public function trim_plugins_name( $plugin_name ) {
		return wp_trim_words( $plugin_name, 3 );
	}

	/**
	 * Set custom columns
	 *
	 * @param string $column Custom columns.
	 * @param int    $post_id The iD of the post.
	 * @since    1.0.0
	 */
	public function custom_column( $column, $post_id ) {
		$allowed_html         = array(
			'p' => array(
				'title' => array(),
				'class' => array(),
			),
		);
		$all_required_plugins = array();
		$plugins_slugs        = get_post_meta( $post_id, '_plgnr_plugin_slugs', true );
		switch ( $column ) {
			case 'notes':
				$notes  = get_post_meta( $post_id, '_plgnr_plugin_list_notes', true );
				$output = "<p title='$notes'>" . wp_trim_words( $notes, 15 ) . '</p>';
				echo wp_kses( $output, $allowed_html );
				break;
			case 'plugins_number':
				$plugins_array   = get_post_meta( $post_id, '_plgnr_plugin_names', true );
				$installed_count = 0;
				if ( '' !== $plugins_slugs ) {
					$plugins_count = count( $plugins_slugs );
					if ( 0 < $plugins_count ) {
						foreach ( $plugins_slugs as $plugin_slug ) {
							$plugin_main_file = Pluginer_Helper::find_main_plugin_file( $plugin_slug );
							$installed        = Pluginer_Helper::is_plugin_installed( $plugin_main_file );
							if ( 1 === $installed ) {
								++$installed_count;
							}
						}
					}
				}
				if ( '' !== $plugins_array ) {
					echo 0 === $installed_count ? esc_html( count( $plugins_array ) ) : esc_html( count( $plugins_array ) . " (installed: $installed_count)" );
				}
				break;
			case 'plugins':
				$plugins_array = get_post_meta( $post_id, '_plgnr_plugin_names', true );
				if ( '' !== $plugins_slugs ) {
					$pa      = array_map( array( $this, 'trim_plugins_name' ), $plugins_array );
					$plugins = implode( ' · ', $plugins_array );
					echo wp_kses( "<p title='$plugins'>" . implode( ' &#164; ', $pa ) . '</p>', $allowed_html );
				}
				break;
			case 'requirements':
				if ( '' !== $plugins_slugs ) {
					$required_plugins     = get_post_meta( $post_id, '_plgnr_plugin_required_plugins', true ) ? get_post_meta( $post_id, '_plgnr_plugin_required_plugins', true ) : array();
					$all_required_plugins = array_merge( $all_required_plugins, array_unique( $required_plugins ) );
					$result               = '';
					$val                  = array( 'NR' );
					$new_required_plugins = array_diff( $all_required_plugins, $val );

					$result = '<p class="warning" title="One or more plugins in this list require the installation of the listed plugin(s)">' . rtrim( implode( ', ', $new_required_plugins ), ', ' ) . '</p>';
					if ( empty( $result ) ) {
						$result = '<p class="aram">All requirements are met.</p>';
					}
					echo wp_kses( $result, $allowed_html );
				}
				break;
		}
	}
}
