<?php
/**
 * Post Duplicate Feature
 *
 * @package Sifency_Core
 */
if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly.
}
/**
 * Class Sifency_Post_Duplicator
 *
 * Adds the ability to duplicate any post, page, or custom post type.
 */
class Sifency_Post_Duplicator {

	/**
	 * Constructor.
	 */
	public function __construct() {
		add_action( 'admin_action_sifency_duplicate_post', [ $this, 'handle_duplicate_action' ] );
		add_filter( 'post_row_actions', [ $this, 'add_duplicate_row_link' ], 10, 2 );
		add_filter( 'page_row_actions', [ $this, 'add_duplicate_row_link' ], 10, 2 );
		add_action( 'admin_bar_menu', [ $this, 'add_admin_bar_duplicate_link' ], 100 );
	}

	/**
	 * Add "Duplicate" link to post/page row actions.
	 */
	public function add_duplicate_row_link( $actions, $post ) {
		if ( ! current_user_can( 'edit_post', $post->ID ) ) {
			return $actions;
		}

		$duplicate_url = $this->get_duplicate_url( $post->ID );

		$actions['sifency_duplicate'] = sprintf(
			'<a href="%1$s" title="%2$s">%3$s</a>',
			esc_url( $duplicate_url ),
			esc_attr__( 'Duplicate this item', 'sifency-addons' ),
			esc_html__( 'Duplicate', 'sifency-addons' )
		);

		return $actions;
	}

	/**
	 * Add "Duplicate This" link to the WordPress Admin Bar.
	 */
	public function add_admin_bar_duplicate_link( $wp_admin_bar ) {
		if ( ! is_admin_bar_showing() || ! is_singular() ) {
			return;
		}

		$current_post = get_queried_object();

		if ( ! $current_post || empty( $current_post->ID ) ) {
			return;
		}

		if ( ! current_user_can( 'edit_post', $current_post->ID ) ) {
			return;
		}

		$wp_admin_bar->add_node(
			[
				'id'    => 'sifency-duplicate-this',
				'title' => esc_html__( 'Duplicate', 'sifency-addons' ),
				'href'  => esc_url( $this->get_duplicate_url( $current_post->ID ) ),
				'meta'  => [
					'title' => esc_attr__( 'Create a duplicate of this post', 'sifency-addons' ),
				],
			]
		);
	}

	/**
	 * Build the secure duplicate URL.
	 */
	private function get_duplicate_url( $post_id ) {
		return wp_nonce_url(
			admin_url( 'admin.php?action=sifency_duplicate_post&post=' . absint( $post_id ) ),
			'sifency_duplicate_post_' . absint( $post_id ),
			'sifency_duplicate_nonce'
		);
	}

	/**
	 * Handle the duplication process.
	 */
	public function handle_duplicate_action() {
		// Nonce and post check.
		if (
			! isset( $_GET['post'], $_GET['sifency_duplicate_nonce'] ) ||
			! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['sifency_duplicate_nonce'] ) ), 'sifency_duplicate_post_' . absint( $_GET['post'] ) )
		) {
			wp_die( esc_html__( 'Security check failed.', 'sifency-addons' ) );
		}

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

		if ( ! $post ) {
			wp_die( esc_html__( 'Post not found.', 'sifency-addons' ) );
		}

		// Get CPT name prefix for the new title.
		$cpt_object  = get_post_type_object( $post->post_type );
		$cpt_label   = isset( $cpt_object->labels->singular_name ) ? $cpt_object->labels->singular_name : ucfirst( $post->post_type );
		$copy_suffix = sprintf( ' (%s Copy)', $cpt_label );

		$current_user = wp_get_current_user();

		// Prepare post data.
		$new_post_data = [
			'post_author'   => $current_user->ID,
			'post_content'  => $post->post_content,
			'post_title'    => $post->post_title . $copy_suffix,
			'post_excerpt'  => $post->post_excerpt,
			'post_status'   => 'draft',
			'post_type'     => $post->post_type,
			'post_parent'   => $post->post_parent,
			'ping_status'   => $post->ping_status,
			'post_password' => $post->post_password,
			'post_name'     => '',
		];

		$new_post_id = wp_insert_post( $new_post_data );

		// Copy taxonomies.
		$taxonomies = get_object_taxonomies( $post->post_type );
		foreach ( $taxonomies as $taxonomy ) {
			$terms = wp_get_object_terms( $post_id, $taxonomy, [ 'fields' => 'slugs' ] );
			wp_set_object_terms( $new_post_id, $terms, $taxonomy, false );
		}

		// Copy post meta.
		$metas = get_post_meta( $post_id );
		foreach ( $metas as $meta_key => $meta_values ) {
			foreach ( $meta_values as $meta_value ) {
				add_post_meta( $new_post_id, $meta_key, maybe_unserialize( $meta_value ) );
			}
		}

		// Redirect to the edit screen.
		wp_safe_redirect( admin_url( 'post.php?action=edit&post=' . $new_post_id ) );
		exit;
	}
}

new Sifency_Post_Duplicator();