<?php
/**
 * DuplicatePost
 *
 * Provides a simple way to duplicate posts/pages via the admin list.
 *
 * @package StrategySuite
 */

namespace StrategySuite;

/**
 * Handles duplication of posts, including copying content, taxonomies, and meta data.
 * Integrates with the StrategySuite module system to provide a "Duplicate" action in the admin.
 */
class DuplicatePost extends \StrategySuite\Module {

	/**
	 * Always enable this module.
	 *
	 * @return bool
	 */
	public function can_register() {
		return true;
	}

	/**
	 * Register hooks for duplicate post functionality.
	 */
	public function register() {
		add_filter( 'post_row_actions', [ $this, 'add_duplicate_link' ], 10, 2 );
		add_filter( 'page_row_actions', [ $this, 'add_duplicate_link' ], 10, 2 );
		add_action( 'admin_action_duplicate_post', [ $this, 'duplicate_post' ] );
	}

	/**
	 * Add a "Duplicate" link to the post/page row actions.
	 *
	 * @param array   $actions Current row actions.
	 * @param WP_Post $post Post object.
	 * @return array Modified actions.
	 */
	public function add_duplicate_link( $actions, $post ) {
		if ( ! $this->is_enabled_for_post( $post ) ) {
			return $actions;
		}

		if ( current_user_can( 'edit_posts', $post->ID ) ) {
			$url = wp_nonce_url(
				admin_url( 'admin.php?action=duplicate_post&post=' . $post->ID ),
				'duplicate_post_' . $post->ID
			);
			$actions['duplicate'] = '<a href="' . esc_url( $url ) . '" title="Duplicate this item">Duplicate</a>';
		}
		return $actions;
	}

	/**
	 * Duplicates a post by creating a new draft with the same content, taxonomies, and meta fields.
	 * Validates the request via nonce and redirects to the edit screen of the newly created post.
	 *
	 * @return void
	 */
	public function duplicate_post() {
		if ( empty( $_GET['post'] ) || ! isset( $_GET['_wpnonce'] ) ) {
			wp_die( 'Invalid request' );
		}

		$post_id = absint( $_GET['post'] );

		$nonce = isset( $_GET['_wpnonce'] )
			? sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) )
			: '';

		if ( ! wp_verify_nonce( $nonce, 'duplicate_post_' . $post_id ) ) {
			wp_die( 'Nonce verification failed' );
		}

		$post = get_post( $post_id );

		if ( ! $post ) {
			wp_die( 'Post not found' );
		}

		if ( ! $this->is_enabled_for_post( $post ) ) {
			wp_die( 'Duplication disabled for this post type' );
		}

		$new_post = [
			'post_title'    => $post->post_title . ' (Copy)',
			'post_content'  => wp_slash( $post->post_content ),
			'post_status'   => 'draft',
			'post_author'   => get_current_user_id(),
			'post_type'     => $post->post_type,
			'post_excerpt'  => $post->post_excerpt,
		];

		$new_post_id = wp_insert_post( $new_post );

		$taxonomies = get_object_taxonomies( $post->post_type );
		foreach ( $taxonomies as $taxonomy ) {
			$terms = wp_get_object_terms( $post_id, $taxonomy, array( 'fields' => 'ids' ) );
			wp_set_object_terms( $new_post_id, $terms, $taxonomy );
		}

		$meta = get_post_meta( $post_id );
		foreach ( $meta as $key => $values ) {
			foreach ( $values as $value ) {
				add_post_meta( $new_post_id, $key, maybe_unserialize( $value ) );
			}
		}

		wp_redirect( admin_url( 'post.php?action=edit&post=' . $new_post_id ) );
		exit;
	}

	/**
	 * Determine whether duplication is enabled for a given post.
	 *
	 * @param WP_Post $post Post object.
	 * @return bool
	 */
	protected function is_enabled_for_post( $post ) {
		/**
		 * Filter whether post duplication is enabled for a given post type.
		 *
		 * @param bool    $enabled   Whether duplication is enabled.
		 * @param string  $post_type Post type slug.
		 * @param WP_Post $post      Post object.
		 */
		return apply_filters(
			'strategy_suite_duplicate_post_enabled',
			true,
			$post->post_type,
			$post
		);
	}
}
