<?php
/**
 * Admin-post handlers for Layouts & Templates: duplicate / reset / delete.
 *
 * The companion view (`Admin\TemplatesAdminPage`) renders the buttons that
 * link to these handlers — each button URL embeds the action slug + a
 * per-source nonce, both defined as `public const` on `TemplatesAdminPage`
 * so this class doesn't own the surface that page-rendering code references.
 *
 * After a successful action the handler stashes a one-shot notice on the
 * current user and `wp_safe_redirect`s back to the page; the next render
 * picks the notice up via `TemplatesAdminPage::consumeNotice()`.
 *
 * @package ThemeREX\AutoDealer\Admin\Templates
 */

declare(strict_types=1);

namespace ThemeREX\AutoDealer\Admin\Templates;

defined( 'ABSPATH' ) || exit;

use ThemeREX\AutoDealer\Admin\TemplatesAdminPage;
use ThemeREX\AutoDealer\Core\Activator;

final class TemplateActions {

	public function register(): void {
		add_action( 'admin_post_' . TemplatesAdminPage::ACTION_DUPLICATE, array( $this, 'handleDuplicate' ) );
		add_action( 'admin_post_' . TemplatesAdminPage::ACTION_RESET, array( $this, 'handleReset' ) );
		add_action( 'admin_post_' . TemplatesAdminPage::ACTION_DELETE, array( $this, 'handleDelete' ) );
	}

	public function handleDuplicate(): void {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( esc_html__( 'You do not have permission.', 'trx-auto-dealer' ), '', array( 'response' => 403 ) );
		}
		$source_id = isset( $_GET['source_id'] ) ? absint( wp_unslash( $_GET['source_id'] ) ) : 0;
		check_admin_referer( TemplatesAdminPage::NONCE_DUPLICATE . '_' . $source_id );

		$source = $source_id > 0 ? get_post( $source_id ) : null;
		if ( ! ( $source instanceof \WP_Post ) || ! in_array( $source->post_type, array( 'wp_block', 'elementor_library' ), true ) ) {
			self::redirect( __( 'Source template not found.', 'trx-auto-dealer' ), 'error' );
		}

		$new_title = self::nextCopyTitle( (string) $source->post_title, (string) $source->post_type );

		$inserted = wp_insert_post(
			array(
				'post_title'   => $new_title,
				'post_status'  => 'publish',
				'post_type'    => $source->post_type,
				'post_content' => $source->post_content,
			),
			true
		);

		if ( is_wp_error( $inserted ) || $inserted <= 0 ) {
			self::redirect( __( 'Could not create duplicate.', 'trx-auto-dealer' ), 'error' );
		}

		$new_id = (int) $inserted;

		// Carry over Elementor data + identity meta so the duplicate is
		// editable in Elementor immediately.
		if ( 'elementor_library' === $source->post_type ) {
			$ele_meta_keys = array(
				'_elementor_data',
				'_elementor_template_type',
				'_elementor_edit_mode',
				'_elementor_version',
				'_elementor_page_settings',
			);
			foreach ( $ele_meta_keys as $key ) {
				$value = get_post_meta( $source->ID, $key, true );
				if ( '' !== $value && null !== $value ) {
					update_post_meta( $new_id, $key, $value );
				}
			}
		}

		update_post_meta( $new_id, Activator::TEMPLATE_KIND_META, Activator::TEMPLATE_KIND_VALUE );
		update_post_meta( $new_id, Activator::TEMPLATE_ORIGIN_META, 'duplicate' );

		self::redirect(
			sprintf(
			/* translators: %s = new template title */
				__( 'Template duplicated as "%s".', 'trx-auto-dealer' ),
				$new_title
			)
		);
	}

	public function handleReset(): void {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( esc_html__( 'You do not have permission.', 'trx-auto-dealer' ), '', array( 'response' => 403 ) );
		}
		$id = isset( $_GET['source_id'] ) ? absint( wp_unslash( $_GET['source_id'] ) ) : 0;
		check_admin_referer( TemplatesAdminPage::NONCE_RESET . '_' . $id );

		$post = $id > 0 ? get_post( $id ) : null;
		if ( ! ( $post instanceof \WP_Post ) ) {
			self::redirect( __( 'Template not found.', 'trx-auto-dealer' ), 'error' );
		}
		$origin = (string) get_post_meta( $id, Activator::TEMPLATE_ORIGIN_META, true );
		if ( 'seed' !== $origin ) {
			self::redirect( __( 'Only the plugin-shipped defaults can be reset. Edit or delete custom templates instead.', 'trx-auto-dealer' ), 'error' );
		}

		if ( 'wp_block' === $post->post_type ) {
			wp_update_post(
				array(
					'ID'           => $id,
					'post_content' => '<!-- wp:trx-auto-dealer/single-listing /-->',
				)
			);
		} elseif ( 'elementor_library' === $post->post_type && defined( 'ELEMENTOR_VERSION' ) ) {
			$encoded = wp_json_encode( self::elementorSeedData() );
			if ( false === $encoded ) {
				$encoded = '[]';
			}
			update_post_meta( $id, '_elementor_data', wp_slash( $encoded ) );
			update_post_meta( $id, '_elementor_edit_mode', 'builder' );
			update_post_meta( $id, '_elementor_template_type', 'page' );
			update_post_meta( $id, '_elementor_version', ELEMENTOR_VERSION );

			// Bump Elementor's CSS cache so the next frontend render rebuilds.
			delete_post_meta( $id, '_elementor_css' );
		}

		self::redirect( __( 'Template reset to plugin default.', 'trx-auto-dealer' ) );
	}

	public function handleDelete(): void {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( esc_html__( 'You do not have permission.', 'trx-auto-dealer' ), '', array( 'response' => 403 ) );
		}
		$id = isset( $_GET['source_id'] ) ? absint( wp_unslash( $_GET['source_id'] ) ) : 0;
		check_admin_referer( TemplatesAdminPage::NONCE_DELETE . '_' . $id );

		$post = $id > 0 ? get_post( $id ) : null;
		if ( ! ( $post instanceof \WP_Post ) ) {
			self::redirect( __( 'Template not found.', 'trx-auto-dealer' ), 'error' );
		}
		$origin = (string) get_post_meta( $id, Activator::TEMPLATE_ORIGIN_META, true );
		if ( 'seed' === $origin ) {
			self::redirect( __( 'The plugin default cannot be deleted. Use Reset to restore its original markup.', 'trx-auto-dealer' ), 'error' );
		}

		wp_delete_post( $id, true );
		self::redirect( __( 'Template deleted.', 'trx-auto-dealer' ) );
	}

	/**
	 * Pick the next " (Copy N)" title that doesn't already exist for this
	 * post type. Strips a trailing " (Copy N)" off the source first so
	 * duplicating "Foo (Copy 1)" yields "Foo (Copy 2)" rather than
	 * "Foo (Copy 1) (Copy 1)".
	 */
	private static function nextCopyTitle( string $source_title, string $post_type ): string {
		global $wpdb;

		$base = preg_replace( '/\s*\(Copy \d+\)\s*$/u', '', $source_title );
		$base = '' === $base ? $source_title : $base;

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery
		$existing = (array) $wpdb->get_col(
			$wpdb->prepare(
				"SELECT post_title FROM {$wpdb->posts} WHERE post_type = %s AND post_status <> 'trash'",
				$post_type
			)
		);
		$existing = array_map( static fn( $t ): string => (string) $t, $existing );

		for ( $n = 1; $n <= 9999; $n++ ) {
			$candidate = $base . ' (Copy ' . $n . ')';
			if ( ! in_array( $candidate, $existing, true ) ) {
				return $candidate;
			}
		}
		return $base . ' (Copy ' . time() . ')';
	}

	/**
	 * Stash a one-shot notice in user_meta and redirect back to the page.
	 * Notice is read once by `TemplatesAdminPage::consumeNotice()` then cleared.
	 *
	 * @return never
	 */
	private static function redirect( string $message, string $type = 'success' ): void {
		$user_id = get_current_user_id();
		if ( $user_id > 0 ) {
			update_user_meta(
				$user_id,
				'trx_ad_template_notice',
				array(
					'message' => $message,
					'type'    => $type,
				)
			);
		}
		$url = add_query_arg(
			array(
				'post_type' => 'trx_ad_listing',
				'page'      => TemplatesAdminPage::PAGE_SLUG,
			),
			admin_url( 'edit.php' )
		);
		wp_safe_redirect( $url );
		exit;
	}

	/**
	 * Mirror of `Activator::elementorStarterData()` for Reset. Kept private
	 * here so the Reset button doesn't need to call into the activation
	 * routine (which has heavier side effects).
	 *
	 * @return array<int, array<string, mixed>>
	 */
	private static function elementorSeedData(): array {
		$id     = static fn(): string => substr( md5( uniqid( '', true ) ), 0, 7 );
		$widget = static function ( string $type ) use ( $id ): array {
			return array(
				'id'         => $id(),
				'elType'     => 'widget',
				'widgetType' => $type,
				'settings'   => array(),
				'elements'   => array(),
			);
		};
		return array(
			array(
				'id'       => $id(),
				'elType'   => 'section',
				'settings' => array(
					'structure'     => '100',
					'content_width' => array(
						'unit' => 'px',
						'size' => 1280,
					),
					'gap'           => 'no',
				),
				'elements' => array(
					array(
						'id'       => $id(),
						'elType'   => 'column',
						'settings' => array( '_column_size' => 100 ),
						'elements' => array(
							$widget( 'trx_ad_single_listing' ),
						),
					),
				),
			),
		);
	}
}
