<?php
/**
 * Sifency Custom Post Type and Taxonomy Registration
 *
 * @package Sifency_Addons
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;  }

/**
 * Handles registration and management of the Theme Builder CPT and taxonomy.
 */
class Sifency_CPT {

	/**
	 * Constructor.
	 */
	public function __construct() {
		add_action( 'init', array( $this, 'register_cpt_and_taxonomy' ), 5 );
		add_action( 'init', array( $this, 'register_meta_field' ), 6 );

		// Save and meta handling.
		add_action( 'save_post_themebuilder', array( $this, 'set_term_from_meta_on_save' ), 10, 2 );
		add_action( 'save_post', array( $this, 'auto_enable_elementor' ), 10, 2 );

		// UI and editor support.
		add_filter( 'post_row_actions', array( $this, 'add_elementor_edit_link' ), 10, 2 );
		add_action( 'edit_form_after_title', array( $this, 'add_type_to_editor_form' ) );
		add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_editor_assets' ) );
		add_action( 'wp_insert_post', array( $this, 'assign_term_on_insert' ), 20, 3 );
	}

	/**
	 * Registers the custom post type and taxonomy.
	 *
	 * @return void
	 */
	public function register_cpt_and_taxonomy() {
		$cpt_labels = array(
			'name'          => esc_html__( 'Sifency ThemeBuilders', 'sifency-addons' ),
			'singular_name' => esc_html__( 'Sifency ThemeBuilder', 'sifency-addons' ),
		);

		$cpt_args = array(
			'labels'             => $cpt_labels,
			'public'             => true,
			'publicly_queryable' => true,
			'show_ui'            => true,
			'show_in_menu'       => false,
			'query_var'          => true,
			'rewrite'            => array( 'slug' => 'themebuilder' ),
			'capability_type'    => 'post',
			'has_archive'        => false,
			'hierarchical'       => false,
			'supports'           => array( 'title', 'editor', 'author', 'elementor' ),
			'show_in_rest'       => true,
		);

		register_post_type( 'themebuilder', $cpt_args );

		register_taxonomy(
			'sifency_builder_type',
			'themebuilder',
			array(
				'label'        => esc_html__( 'Template Type', 'sifency-addons' ),
				'rewrite'      => array( 'slug' => 'sifency_builder_type' ),
				'hierarchical' => true,
				'public'       => false,
				'show_ui'      => false,
				'show_in_rest' => true,
				'rest_base'    => 'sifency_builder_type',
			)
		);

		$default_terms = array(
			'topbar'            => 'Topbar',
			'header'            => 'Header',
			'subheader'         => 'Subheader',
			'after-subheader'   => 'After Subheader',
			'footer'            => 'Footer',
			'pre-before-footer' => 'Pre Before Footer',
			'before-footer'     => 'Before Footer',
			'error_404'         => '404',
			'offcanvas'         => 'Offcanvas',
			'post-archive'      => 'Post Archive',
			'post'              => 'Single Post',
			'popup'             => 'Popup',
			'scrollup'          => 'Scroll To Top',
			'shop'              => 'Shop',
			'product'           => 'Single Product',
			'service-archive'   => 'Service Archive',
			'service'           => 'Service Single',
			'team-archive'      => 'Team Archive',
			'team'              => 'Member Single',
			'portfolio-archive' => 'Portfolio Archive',
			'portfolio'         => 'Portfolio Single',
			'event-archive'     => 'Event Archive',
			'event'             => 'Event Single',
			'career-archive'    => 'Career Archive',
			'career'            => 'Career Single',
			'doc-archive'       => 'Doc Archive',
			'documentation'     => 'Doc Single',
			'digital-archive'   => 'Digital Goods',
			'digital'           => 'Digital Goods Item',
			'edd-archive'       => 'Easy Digital Download Archive',
			'edd'               => 'Easy Digital Download Item',
		);

		foreach ( $default_terms as $slug => $name ) {
			if ( ! term_exists( $slug, 'sifency_builder_type' ) ) {
				wp_insert_term( $name, 'sifency_builder_type', array( 'slug' => $slug ) );
			}
		}
	}

	/**
	 * Registers meta field for temporary storage.
	 *
	 * @return void
	 */
	public function register_meta_field() {
		register_post_meta(
			'themebuilder',
			'_sifency_initial_type',
			array(
				'show_in_rest'  => true,
				'single'        => true,
				'type'          => 'string',
				'auth_callback' => static function () {
					return current_user_can( 'edit_posts' );
				},
			)
		);
	}

	/**
	 * Sets taxonomy term based on saved meta value.
	 *
	 * @param int     $post_id The post ID.
	 * @param WP_Post $post    The post object.
	 * @return void
	 */
	public function set_term_from_meta_on_save( $post_id, $post ) {
		if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
			return;
		}

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

		$type_slug = get_post_meta( $post_id, '_sifency_initial_type', true );

		if ( empty( $type_slug ) ) {
			return;
		}

		$term = term_exists( $type_slug, 'sifency_builder_type' );
		if ( $term && ! is_wp_error( $term ) ) {
			wp_set_post_terms( $post_id, array( (int) $term['term_id'] ), 'sifency_builder_type', false );
		}
		delete_post_meta( $post_id, '_sifency_initial_type' );
	}


	/**
	 * Automatically enables Elementor editing for Theme Builder templates.
	 *
	 * @param int     $post_id The post ID.
	 * @param WP_Post $post    The post object.
	 * @return void
	 */
	public function auto_enable_elementor( $post_id, $post ) {
		if ( wp_is_post_revision( $post_id ) ) {
			return;
		}

		if ( 'themebuilder' === $post->post_type && class_exists( '\Elementor\Plugin' ) ) {
			update_post_meta( $post_id, '_elementor_edit_mode', 'builder' );
			update_post_meta( $post_id, '_elementor_template_type', 'wp-post' );

			if ( defined( 'ELEMENTOR_VERSION' ) ) {
				update_post_meta( $post_id, '_elementor_version', ELEMENTOR_VERSION );
			}
		}
	}

	/**
	 * Adds "Edit with Elementor" action link in post list.
	 *
	 * @param array   $actions The current row actions.
	 * @param WP_Post $post    The post object.
	 * @return array
	 */
	public function add_elementor_edit_link( $actions, $post ) {
		if ( 'themebuilder' === $post->post_type && class_exists( '\Elementor\Plugin' ) ) {
			$url                  = admin_url( 'post.php?post=' . $post->ID . '&action=elementor' );
			$actions['elementor'] = sprintf(
				'<a href="%1$s">%2$s</a>',
				esc_url( $url ),
				esc_html__( 'Edit with Elementor', 'sifency-addons' )
			);
		}
		return $actions;
	}

	/**
	 * Adds hidden field for template type during new post creation.
	 *
	 * @param WP_Post $post The post object.
	 * @return void
	 */
	public function add_type_to_editor_form( $post ) {
		if ( 'themebuilder' !== $post->post_type ) {
			return;
		}

		if ( isset( $_GET['sifency_builder_type'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
			$type_slug = sanitize_key( wp_unslash( $_GET['sifency_builder_type'] ) );
			if ( ! empty( $type_slug ) ) {
				printf(
					'<input type="hidden" id="sifency-initial-template-type" value="%s" />',
					esc_attr( $type_slug )
				);
			}
		}
	}

	/**
	 * Enqueues editor script to assign taxonomy terms on new posts.
	 *
	 * @return void
	 */
	public function enqueue_editor_assets() {
		// Only run in admin/editor.
		if ( ! is_admin() ) {
			return;
		}

		$screen = get_current_screen();
		if ( ! $screen || 'post' !== $screen->base ) {
			return;
		}

		if ( isset( $screen->post_type ) && 'themebuilder' !== $screen->post_type ) {
			return;
		}

		$terms = get_terms(
			array(
				'taxonomy'   => 'sifency_builder_type',
				'hide_empty' => false,
			)
		);

		$terms_map = array();

		if ( ! is_wp_error( $terms ) && ! empty( $terms ) ) {
			foreach ( $terms as $term ) {
				$terms_map[ $term->slug ] = $term->term_id;
			}
		}

		wp_enqueue_script(
			'sifency-editor-taxonomy-fix',
			plugins_url( '/js/dummy.js', __FILE__ ),
			array( 'wp-data', 'wp-dom-ready', 'wp-api' ),
			'1.0',
			true
		);

		// Inline: assign taxonomy term when creating a clean new post (existing logic).
		wp_add_inline_script(
			'sifency-editor-taxonomy-fix',
			sprintf(
				'
				( function( wp ) {
					wp.data.subscribe( function () {
						if ( ! wp.data.select( "core/editor" ).isCleanNewPost() ) {
							return;
						}

						const input = document.getElementById( "sifency-initial-template-type" );
						if ( ! input ) return;

						const slug = input.value;
						const map  = %s;

						if ( slug && map.hasOwnProperty( slug ) ) {
							const termId = map[slug];
							if ( termId > 0 ) {
								wp.data.dispatch( "core/editor" ).editPost( {
									sifency_builder_type: [ termId ]
								} );
								input.remove();
							}
						}
					});
				} )( window.wp );
				',
				wp_json_encode( $terms_map )
			),
			'after'
		);

		wp_add_inline_script(
			'sifency-editor-taxonomy-fix',
			'
			( function( wp ) {
				// Find the hidden input we printed in edit_form_after_title()
				const input = document.getElementById("sifency-initial-template-type");
				if ( ! input || ! wp || ! wp.apiFetch || ! wp.apiFetch.use ) {
					return;
				}
				const tab = input.value || "all";

				// Add middleware to inject header into every apiFetch request.
				wp.apiFetch.use( ( options, next ) => {
					options = options || {};
					options.headers = options.headers || {};
					// Only inject for requests that look like restful calls (namespace included)
					if ( typeof options.path === "string" ) {
						options.headers["X-Sifency-Return-Tab"] = tab;
					}
					return next( options );
				} );
			} )( window.wp );
			',
			'after'
		);
	}


	public function assign_term_on_insert( $post_id, $post, $update ) {
		if ( $update || 'themebuilder' !== $post->post_type ) {
			return;
		}

		$type_slug = '';

		if ( isset( $_POST['sifency_builder_type'] ) ) {
			$val = wp_unslash( $_POST['sifency_builder_type'] );
			if ( is_array( $val ) && ! empty( $val ) ) {
				$first     = reset( $val );
				$type_slug = is_numeric( $first ) ? (int) $first : sanitize_key( $first );
			} else {
				$type_slug = is_numeric( $val ) ? (int) $val : sanitize_key( $val );
			}
		} elseif ( isset( $_POST['type'] ) ) { // AJAX uses 'type'
			$type_slug = sanitize_key( wp_unslash( $_POST['type'] ) );
		} elseif ( isset( $_GET['sifency_builder_type'] ) ) {
			$type_slug = sanitize_key( wp_unslash( $_GET['sifency_builder_type'] ) );
		} else {
			$type_slug = get_post_meta( $post_id, '_sifency_initial_type', true );
		}

		if ( empty( $type_slug ) ) {
			return;
		}

		$term_id = 0;
		if ( is_numeric( $type_slug ) ) {
			$term_id = (int) $type_slug;
		} else {
			$term = term_exists( $type_slug, 'sifency_builder_type' );
			if ( $term && ! is_wp_error( $term ) ) {
				if ( is_array( $term ) && isset( $term['term_id'] ) ) {
					$term_id = (int) $term['term_id'];
				} else {
					$term_id = (int) $term;
				}
			}
		}

		if ( $term_id ) {
			wp_set_post_terms( $post_id, array( $term_id ), 'sifency_builder_type', false );
		} else {
			wp_set_post_terms( $post_id, array( (string) $type_slug ), 'sifency_builder_type', false );
		}

		delete_post_meta( $post_id, '_sifency_initial_type' );
	}
}
