<?php
/**
 * Phase 19 — single sub-menu surface for managing single-listing templates.
 *
 * Renders cards for the seeded Gutenberg + Elementor defaults and a list of
 * customer-created templates. Action handlers (Edit / Duplicate / Reset /
 * Delete) live in the `Templates\TemplateActions` collaborator — the page
 * just builds the button URLs from the shared `ACTION_*` / `NONCE_*` consts
 * on this class.
 *
 * Lives in the free plugin so customers can edit/duplicate templates without
 * needing Pro. Per-listing override (Pro feature) hooks into the same data
 * model via shared meta keys.
 *
 * @package ThemeREX\AutoDealer
 */

declare(strict_types=1);

namespace ThemeREX\AutoDealer\Admin;

defined( 'ABSPATH' ) || exit;

use ThemeREX\AutoDealer\Admin\Templates\TemplateActions;
use ThemeREX\AutoDealer\Core\Activator;

final class TemplatesAdminPage {

	public const PAGE_SLUG        = 'trx-auto-dealer-templates';
	public const ACTION_DUPLICATE = 'trx_ad_template_duplicate';
	public const ACTION_RESET     = 'trx_ad_template_reset';
	public const ACTION_DELETE    = 'trx_ad_template_delete';
	public const NONCE_DUPLICATE  = 'trx_ad_template_duplicate_nonce';
	public const NONCE_RESET      = 'trx_ad_template_reset_nonce';
	public const NONCE_DELETE     = 'trx_ad_template_delete_nonce';

	public function register(): void {
		add_action( 'admin_menu', array( $this, 'addPage' ), 30 );
		( new TemplateActions() )->register();
	}

	public function addPage(): void {
		add_submenu_page(
			'edit.php?post_type=trx_ad_listing',
			__( 'Layouts & Templates', 'trx-auto-dealer' ),
			__( 'Layouts & Templates', 'trx-auto-dealer' ),
			'manage_options',
			self::PAGE_SLUG,
			array( $this, 'renderPage' ),
			95
		);
	}

	public function renderPage(): void {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( esc_html__( 'You do not have permission to access this page.', 'trx-auto-dealer' ), '', array( 'response' => 403 ) );
		}

		$gut_id  = (int) get_option( Activator::DEFAULT_GUTENBERG_TEMPLATE_OPTION, 0 );
		$ele_id  = (int) get_option( Activator::DEFAULT_ELEMENTOR_TEMPLATE_OPTION, 0 );
		$gut     = $gut_id > 0 ? get_post( $gut_id ) : null;
		$ele     = $ele_id > 0 ? get_post( $ele_id ) : null;
		$customs = self::listCustomTemplates();
		$notice  = self::consumeNotice();

		echo '<div class="wrap trx-ad-templates-page">';
		printf( '<h1>%s</h1>', esc_html__( 'Layouts & Templates', 'trx-auto-dealer' ) );

		if ( '' !== $notice ) {
			printf( '<div class="notice notice-success is-dismissible"><p>%s</p></div>', esc_html( $notice ) );
		}

		printf(
			'<p class="description">%s</p>',
			esc_html__( 'Edit the default single-listing templates, duplicate them as a starting point, or manage your custom layouts. The site-wide default is selected from Settings → Layouts.', 'trx-auto-dealer' )
		);

		echo '<div class="trx-ad-templates-grid" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));gap:24px;margin-top:20px;">';
		self::renderCard( 'gutenberg', $gut );
		if ( defined( 'ELEMENTOR_VERSION' ) ) {
			self::renderCard( 'elementor', $ele );
		}
		echo '</div>';

		echo '<h2 style="margin-top:36px;">' . esc_html__( 'Custom templates', 'trx-auto-dealer' ) . '</h2>';
		if ( empty( $customs ) ) {
			echo '<p>' . esc_html__( 'No custom templates yet. Click "Duplicate" on a default to create one.', 'trx-auto-dealer' ) . '</p>';
		} else {
			echo '<table class="wp-list-table widefat fixed striped"><thead><tr>';
			echo '<th>' . esc_html__( 'Title', 'trx-auto-dealer' ) . '</th>';
			echo '<th style="width:120px;">' . esc_html__( 'Type', 'trx-auto-dealer' ) . '</th>';
			echo '<th style="width:80px;">' . esc_html__( 'ID', 'trx-auto-dealer' ) . '</th>';
			echo '<th style="width:160px;">' . esc_html__( 'Last modified', 'trx-auto-dealer' ) . '</th>';
			echo '<th style="width:280px;">' . esc_html__( 'Actions', 'trx-auto-dealer' ) . '</th>';
			echo '</tr></thead><tbody>';
			foreach ( $customs as $row ) {
				echo '<tr>';
				printf( '<td><strong>%s</strong></td>', esc_html( $row['title'] ) );
				printf( '<td>%s</td>', esc_html( 'wp_block' === $row['type'] ? 'Gutenberg' : 'Elementor' ) );
				printf( '<td>#%d</td>', (int) $row['id'] );
				printf( '<td>%s</td>', esc_html( $row['modified'] ) );
				echo '<td>';
				printf(
					'<a href="%s" class="button button-small">%s</a> ',
					esc_url( self::editUrl( (int) $row['id'], (string) $row['type'] ) ),
					esc_html__( 'Edit', 'trx-auto-dealer' )
				);
				printf(
					'<a href="%s" class="button button-small">%s</a> ',
					esc_url( self::actionUrl( self::ACTION_DUPLICATE, self::NONCE_DUPLICATE, (int) $row['id'] ) ),
					esc_html__( 'Duplicate', 'trx-auto-dealer' )
				);
				printf(
					'<a href="%s" class="button button-small button-link-delete" onclick="return confirm(%s);">%s</a>',
					esc_url( self::actionUrl( self::ACTION_DELETE, self::NONCE_DELETE, (int) $row['id'] ) ),
					esc_attr( wp_json_encode( __( 'Delete this template? This cannot be undone.', 'trx-auto-dealer' ) ) ?: '"Delete?"' ),
					esc_html__( 'Delete', 'trx-auto-dealer' )
				);
				echo '</td></tr>';
			}
			echo '</tbody></table>';
		}

		echo '</div>';
	}

	/**
	 * Render a default-template card for Gutenberg or Elementor. `$post` is
	 * null when the seed never ran or the post was hard-deleted. Echoes
	 * directly (every fragment is escaped at its own printf) instead of
	 * returning captured HTML, so the caller never echoes a variable
	 * (escape-late, wp.org 2026-07 review round 2).
	 */
	private static function renderCard( string $kind, ?\WP_Post $post ): void {
		$label = 'gutenberg' === $kind
			? __( 'Default Gutenberg Single Listing', 'trx-auto-dealer' )
			: __( 'Default Elementor Single Listing', 'trx-auto-dealer' );

		echo '<div class="card" style="padding:18px;border:1px solid #c3c4c7;background:#fff;border-radius:4px;">';
		printf( '<h2 style="margin-top:0;">%s</h2>', esc_html( $label ) );

		if ( ! ( $post instanceof \WP_Post ) ) {
			printf( '<p>%s</p>', esc_html__( 'Template not found. Reactivate the plugin to re-seed it.', 'trx-auto-dealer' ) );
			echo '</div>';
			return;
		}

		printf( '<p><strong>%s</strong></p>', esc_html( $post->post_title ) );
		printf(
			'<p class="description">%s</p>',
			esc_html(
				sprintf(
				/* translators: 1: post ID, 2: last modified date */
					__( 'ID #%1$d · last modified %2$s', 'trx-auto-dealer' ),
					$post->ID,
					get_the_modified_date( '', $post )
				)
			)
		);

		echo '<p>';
		printf(
			'<a href="%s" class="button button-primary">%s</a> ',
			esc_url( self::editUrl( $post->ID, $post->post_type ) ),
			esc_html__( 'Edit', 'trx-auto-dealer' )
		);
		printf(
			'<a href="%s" class="button">%s</a> ',
			esc_url( self::actionUrl( self::ACTION_DUPLICATE, self::NONCE_DUPLICATE, $post->ID ) ),
			esc_html__( 'Duplicate', 'trx-auto-dealer' )
		);
		printf(
			'<a href="%s" class="button" onclick="return confirm(%s);">%s</a>',
			esc_url( self::actionUrl( self::ACTION_RESET, self::NONCE_RESET, $post->ID ) ),
			esc_attr( wp_json_encode( __( 'Reset this template to its original plugin defaults? Your customizations will be lost.', 'trx-auto-dealer' ) ) ?: '"Reset?"' ),
			esc_html__( 'Reset to plugin default', 'trx-auto-dealer' )
		);
		echo '</p></div>';
	}

	/**
	 * List every plugin-managed template that's NOT a seed (i.e. customer
	 * duplicates and any manually-tagged custom templates). Sorted newest
	 * first by modified date.
	 *
	 * @return array<int, array{id:int, title:string, type:string, modified:string}>
	 */
	private static function listCustomTemplates(): array {
		$post_types = array( 'wp_block' );
		if ( defined( 'ELEMENTOR_VERSION' ) ) {
			$post_types[] = 'elementor_library';
		}

		$query = new \WP_Query(
			array(
				'post_type'      => $post_types,
				'post_status'    => array( 'publish', 'draft', 'private' ),
				'posts_per_page' => 200,
				'orderby'        => 'modified',
				'order'          => 'DESC',
				'meta_query'     => array(  // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
				'relation' => 'AND',
				array(
					'key'   => Activator::TEMPLATE_KIND_META,
					'value' => Activator::TEMPLATE_KIND_VALUE,
				),
				array(
					'relation' => 'OR',
					array(
						'key'     => Activator::TEMPLATE_ORIGIN_META,
						'value'   => 'seed',
						'compare' => '!=',
					),
					array(
						'key'     => Activator::TEMPLATE_ORIGIN_META,
						'compare' => 'NOT EXISTS',
					),
				),
				),
				'no_found_rows'  => true,
			)
		);

		$out = array();
		foreach ( $query->posts as $post ) {
			if ( ! ( $post instanceof \WP_Post ) ) {
				continue;
			}
			$out[] = array(
				'id'       => (int) $post->ID,
				'title'    => (string) $post->post_title,
				'type'     => (string) $post->post_type,
				'modified' => (string) get_the_modified_date( '', $post ),
			);
		}
		return $out;
	}

	/**
	 * Build the post.php edit URL for a Gutenberg or Elementor template.
	 * Elementor library posts open in Elementor's editor when the user
	 * clicks "Edit with Elementor" inside; we just deep-link to wp-admin
	 * so both flavors land somewhere working.
	 */
	private static function editUrl( int $post_id, string $post_type ): string {
		return add_query_arg(
			array(
				'post'   => $post_id,
				'action' => 'edit',
			),
			admin_url( 'post.php' )
		);
	}

	private static function actionUrl( string $action, string $nonce, int $source_id ): string {
		$url = add_query_arg(
			array(
				'action'    => $action,
				'source_id' => $source_id,
			),
			admin_url( 'admin-post.php' )
		);
		return wp_nonce_url( $url, $nonce . '_' . $source_id );
	}

	/**
	 * Read + clear the one-shot notice stashed by `TemplateActions::redirect()`.
	 * Returns the message string, or '' if no notice is pending.
	 */
	private static function consumeNotice(): string {
		$user_id = get_current_user_id();
		if ( $user_id <= 0 ) {
			return '';
		}
		$stash = get_user_meta( $user_id, 'trx_ad_template_notice', true );
		if ( ! is_array( $stash ) || empty( $stash['message'] ) ) {
			return '';
		}
		delete_user_meta( $user_id, 'trx_ad_template_notice' );
		return (string) $stash['message'];
	}
}
